xy

用C#實現Blob數據類型

 

PowerBuilder提供了Blob數據類型, 用來處理二進制數據(如:圖像,文件,二進制流,文本等等). 本質上, Blob是可變長的字節數組, 它提供了一系列全局函數來讀/寫Blob對象:

 

Blob   : 將字符串轉換為Blob對象 

BlobEdit : 將任意PowerBuilder基礎類型數據寫入Blob對象

BlobMid  : 從Blob對象中讀取指定長度的數據,並返回Blob對象

Len   : 求Blob對象的長度

 

請按說明文檔, 用C#實現命名,功能,行為,數據結果兼容PowerBuilder的Blob類型. 注: 為兼容PowerBuilder, 代碼不應拋出異常.

 

附:說明文檔

1.PowerBuilder基礎數據類型--------------------------------------------------------------------

Standard datatypes

The datatypes

The standard datatypes in PocketBuilder are the familiar datatypes that are used in many programming languages, including char, integer, decimal, long, and string. In PowerScript, you use these datatypes to declare variables or arrays.

These are the standard PowerScript datatypes, followed by a description of each: 

Blob 

LongLong

 

Boolean 

Long

 

Char or character

Real 

 

Date 

String

 

DateTime

Time

 

Decimal or Dec

UnsignedInteger, UnsignedInt, or UInt

 

Double

UnsignedLong or ULong

 

Integer or Int

   

Blob 

Binary large object. Used to store an unbounded amount of data (for example, generic binary, image, or large text such as a word-processing document). 

Boolean 

Contains TRUE or FALSE. 

Char or character 

A single ASCII character. 

If you have character-based data that you will want to parse in an application, you might want to define it as an array of type char. Parsing a char array is easier and faster than parsing strings. If you will be passing character-based data to external functions, you might want to use char arrays instead of strings. 

For more information about passing character-based data to external functions, see the Resource Guide. For information about datatype conversion when assigning strings to chars and vice versa, see “String and char datatypes in PocketBuilder”.

Using literals To assign a literal value, enclose the character in either single or double quotation marks. For example:

char c

c = 'T'

c = "T"

Date 

The date, including the full year (1000 to 3000), the number of the month (01 to 12), and the day (01 to 31). 

Using literals To assign a literal value, separate the year, month, and day with hyphens. For example:

1992-12-25  // December 25, 1992 

1995-02-06  // February 6, 1995

DateTime

The date and time in a single datatype, used only for reading and writing DateTime values from and to a database. To convert DateTime values to datatypes that you can use in PocketBuilder, use:

· The Date(datetime) function to convert a DateTime value to a PocketBuilder date value after reading from a database

· The Time(datetime) function to convert a DateTime value to a PocketBuilder time value after reading from a database

· The DateTime (date, time) function to convert a date and (optional) time to a DateTime before writing to a DateTime column in a database. 

Decimal or Dec 

Signed decimal numbers with up to 18 digits. You can place the decimal point anywhere within the 18 digits—for example, 123.456, 0.000000000000000001 or 12345678901234.5678.

Using literals To assign a literal value, use any number with a decimal point and no exponent. The plus sign is optional (95 and +95 are the same). For numbers between zero and one, the zero to the left of the decimal point is optional (for example, 0.1 and .1 are the same). For whole numbers, zeros to the right of the decimal point are optional (32.00, 32.0, and 32. are all the same). For example:

12.34    0.005     14.0    -6500     +3.5555 

Double 

A signed floating-point number with 15 digits of precision and a range from 2.2250738585073E-308 to 1.79769313486231E+308.

Integer or Int 

16-bit signed integers, from -32768 to +32767.

Using literals To assign a literal value, use any whole number (positive, negative, or zero). The leading plus sign is optional (18 and +18 are the same). For example: 

1        123       1200       +55       -32

Long 

32-bit signed integers, from -2147483648 to +2147483647.

Using literals Use literals as for integers, but longer numbers are permitted.

LongLong 

64-bit signed integers, from -9223372036854775808 to 9223372036854775807.

Using literals Use literals as for integers, but longer numbers are permitted.

Real 

A signed floating-point number with six digits of precision and a range from 1.175495E-38 to 3.402822E+38.

Using literals To assign a literal value, use a decimal value, followed by E, followed by an integer; no spaces are allowed. The decimal number before the E follows all the conventions specified above for decimal literals. The leading plus sign in the exponent (the integer following the E) is optional (3E5 and 3E+5 are the same). For example:

2E4        2.5E78   +6.02E3    -4.1E-2

-7.45E16   7.7E+8   3.2E-45

String 

Any ASCII character with variable length (0 to 2147483647). 

Most of the character-based data in your application, such as names, addresses, and so on, will be defined as strings. PowerScript provides many functions that you can use to manipulate strings, such as a function to convert characters in a string to uppercase and functions to remove leading and trailing blanks.

For more information about passing character-based data to external functions, see the Resource Guide. For information about datatype conversion when assigning strings to chars and vice versa, see “String and char datatypes in PocketBuilder”.

Using literals To assign a literal value, enclose as many as 1024 characters in either single or double quotes, including a string of zero length or an empty string. For example: 

string s1

s1 = 'This is a string'

s1 = "This is a string"

You can embed a quotation mark in a string literal if you enclose the literal with the other quotation mark. For example, the following statements result in the string Here's a string:

string s1

s1 = "Here's a string."

You can also use a tilde (~) to embed a quotation mark in a string literal. For example:

string s1 = 'He said, "It~'s good!"'

Complex nesting When you nest a string within a string that is nested in another string, you can use tildes to tell the parser how to interpret the quotation marks. Each pass through the parser strips away the outermost quotes and interprets the character after each tilde as a literal. Two tildes become one tilde, and tilde-quote becomes the quote alone.

Example 1 This string has two levels of nesting:

"He said ~"she said ~~~"Hi ~~~" ~" "

The first pass results in:

He said "she said ~"Hi ~" "

The second pass results in:

she said "Hi"

The third pass results in:

Hi

Example 2 A more probable example is a string for the Modify function that sets a DataWindow property. The argument string often requires complex quotation marks (because you must specify one or more levels of nested strings). To understand the quotation marks, consider how PocketBuilder will parse the string. The following string is a possible argument for the Modify function; it mixes single and double quotes to reduce the number of tildes:

"bitmap_1.Invert='0~tIf(empstatus=~~'A~~',0,1)'"

The double quotes tell PocketBuilder to interpret the argument as a string. It contains the expression being assigned to the Invert property, which is also a string, so it must be quoted. The expression itself includes a nested string, the quoted A. First, PocketBuilder evaluates the argument for Modify and assigns the single-quoted string to the Invert property. In this pass through the string, it converts two tildes to one. The string assigned to Invert becomes:

'0[tab]If(empstatus=~'A~',0,1)'

Finally, PocketBuilder evaluates the property’s expression, converting tilde-quote to quote, and sets the bitmap’s colors accordingly.

Example 3 There are many ways to specify quotation marks for a particular set of nested strings. The following expressions for the Modify function all have the same end result:

"emp.Color = ~"0~tIf(stat=~~~"a~~~",255,16711680)~""

"emp.Color = ~"0~tIf(stat=~~'a~~',255,16711680)~""

"emp.Color = '0~tIf(stat=~~'a~~',255,16711680)'"

"emp.Color = ~"0~tIf(stat='a',255,16711680)~""

Rules for quotation marks and tildes When nesting quoted strings, the following rules of thumb might help:

· A tilde tells the parser that the next character should be taken as a literal, not a string terminator

· Pairs of single quotes ( ' ) can be used in place of pairs of tilde double quotes (~")

· Pairs of tilde tilde single quotes (~~') can be used in place of pairs of triple tilde double quotes (~~~")

Time 

The time in 24-hour format, including the hour (00 to 23), minute (00 to 59), second (00 to 59), and fraction of second (up to six digits), with a range from 00:00:00 to 23:59:59:999999.

Using literals The time in 24-hour format, including the hour (00 to 23), minute (00 to 59), second (00 to 59), and fraction of second (up to six digits), with a range from 00:00:00 to 23:59:59.999999. You separate parts of the time with colons—except for fractional sections, which should be separated by a decimal point. For example:

21:09:15    // 15 seconds after 9:09 pm

06:00:00    // Exactly 6 am

10:29:59    // 1 second before 10:30 am

10:29:59.9  // 1/10 sec before 10:30 am

UnsignedInteger, UnsignedInt, or UInt 

16-bit unsigned integers, from 0 to 65535.

UnsignedLong or ULong 

32-bit unsigned integers, from 0 to 4294967295.

 

 

 

2.Blob函數說明

Blob

--------------------------------------------------

Description

Converts a string to a blob datatype.

Syntax

Blob ( text )

Argument

Description

text

The string you want to convert to a blob datatype

Returns

Blob. Returns the converted string. If text is null, Blob returns null.

Examples

Example 1

This example saves a text string as a blob datatype:

Blob B

B = Blob("Any Text")

 

BlobEdit

--------------------------------------------------

 

Description

Inserts data of any PocketBuilder datatype into a blob variable.

Syntax

BlobEdit ( blobvariable, n, data )

Argument

Description

blobvariable

An initialized variable of the blob datatype into which you want to copy a standard PocketBuilder datatype

n

The number (1 to 4,294,967,295) of the position in blobvariable at which you want to begin copying the data

data

Data of a valid PocketBuilder datatype that you want to copy into blobvariable

Returns

Unsigned long. Returns the position at which the next data can be copied if it succeeds, and returns null if there is not enough space in blobvariable to copy the data. If any argument’s value is null, BlobEdit returns null.

If the data argument is a string, the position in the blobvariable in which you want to copy data will be the length of the string + 2. If the data argument is a string converted to a blob, the position will be the length of the string + 1. This is because a string contains a null terminating character that it loses when it is converted to a blob. Thus, BlobEdit (blob_var, 1, "ZZZ'') returns 5, while BlobEdit (blob_var, 1, blob (''ZZZ'') ) returns 4.

Examples

Example 1

This example copies a bitmap in the blob emp_photo starting at position 1, stores the position at which the next copy can begin in nbr, and then copies a date into the blob emp_photo after the bitmap data:

blob{1000} emp_photo

blob temp

date pic_date

ulong nbr

 

... // Read BMP file containing employee picture

... // into temp using FileOpen and FileRead.

pic_date = Today()

 

nbr = BlobEdit(emp_photo, 1, temp)

BlobEdit(emp_photo, nbr, pic_date)

UPDATEBLOB Employee SET pic = :emp_photo

    WHERE ...

 

BlobMid

--------------------------------------------------

 

Description

Extracts data from a blob variable.

 

Syntax

BlobMid ( data, n {, length } )

Argument

Description

data

Data of the blob datatype

n

The number (1 to 4,294,967,295) of the first byte you want returned

length (optional)

The number of bytes (1 to 4,294,967,295) you want returned

Returns

Blob. Returns length bytes from data starting at byte n. If n is greater than the number of bytes in data, BlobMid returns an empty blob. If together length and n add up to more bytes than the blob contains, BlobMid returns the remaining bytes, and the returned blob will be shorter than the specified length. If any argument’s value is null, BlobMid returns null.

Include terminator characterString variables contain a zero terminator, which accounts for one byte. Include the terminator character when calculating how much data to extract.

Examples

Example 1

In this example, the first call to BlobMid stores 10 bytes of the blob datablob starting at position 5 in the blob data_1; the second call stores the bytes of datablob from position 5 to the end in data_2:

blob data_1, data_2, datablob

 

... // Read a blob datatype into datablob.

 

data_1 = BlobMid(datablob, 5, 10)

data_2 = BlobMid(datablob, 5)

Example 2

This code copies a bitmap in the blob emp_photo starting at position 1, stores the position at which the next copy can begin in nbr, and then copies a date into the blob emp_photo after the bitmap data. Then, using the date’s start position, it extracts the date from the blob and displays it in the StaticText st_1:

blob{1000} emp_photo

blob temp

date pic_date

ulong nbr

 

... // Read BMP file containing employee picture

... // into temp using FileOpen and FileRead.

 

pic_date = Today()

nbr = BlobEdit(emp_photo, 1, temp)

BlobEdit(emp_photo, nbr, pic_date)

st_1.Text = String(Date(BlobMid(emp_photo, nbr)))

 

 

String

--------------------------------------------------

 

Description

Converts data in a blob to a string value. If the blob’s value is not text data, String attempts to interpret the data as characters.

 

Syntax

String ( blob )

Argument

Description

blob

The blob whose value you want returned as a string. Blob can also be an Any variable containing a blob.

Returns

String. Returns the value of blob as a string if it succeeds and the empty string ("") if it fails. It the blob does not contain string data, String interprets the data as characters, if possible, and returns a string. If blob is null, String returns null.

Usage

You can also use String to extract a string from the Message object after calling TriggerEvent or PostEvent. For more information, see the TriggerEvent or PostEvent functions.

Examples

Example 18

This example converts the blob instance variable ib_sblob, which contains string data, to a string and stores the result in sstr:

string sstr

sstr = String(ib_sblob)

Example 19

This example stores today’s date and test status information in the blob bb. Pos1 and pos2 store the beginning and end of the status text in the blob. Finally, BlobMid extracts a "sub-blob" that String converts to a string. Sle_status displays the returned status text:

blob{100} bb

long pos1, pos2

string test_status

date test_date

 

test_date = Today()

IF DayName(test_date) = "Wednesday" THEN &

   test_status = "Coolant Test"

IF DayName(test_date) = "Thursday" THEN &

   test_status = "Emissions Test"

 

// Store data in the blob

pos1 = BlobEdit( bb, 1, test_date)

pos2 = BlobEdit( bb, pos1, test_status )

 

... // Some processing

 

// Extract the status stored in bb and display it

sle_status.text = String( &

   BlobMid(bb, pos1, pos2 - pos1))

 

 

Len

Description

Reports the length of a string or a blob. 

Syntax

Len ( stringorblob )

Argument

Description

stringorblob

The string or blob for which you want the length in number of characters or in number of bytes

Returns

Long. Returns a long whose value is the length of stringorblob if it succeeds and -1 if an error occurs. If stringorblob is null, Len returns null.

Usage

Len counts the number of characters in a string. The null that terminates a string is not included in the count. 

If you specify a size when you declare a blob, that is the size reported by Len. If you do not specify a size for the blob, Len initially reports the blob’s length as 0. PowerBuilder assigns a size to the blob the first time you assign data to the blob. Len reports the length of the blob as the number characters it can contain.

Examples

Example 1

This statement returns 0:

Len("")

Example 2

These statements store in the variable s_address_len the length of the text in the SingleLineEdit sle_address:

long s_address_len

s_address_len = Len(sle_address.Text)

Example 3

The following scenarios illustrate how the declaration of blobs affects their length, as reported by Len.

In the first example, an instance variable called ib_blob is declared but not initialized with a size. If you call Len before data is assigned to ib_blob, Len returns 0. After data is assigned, Len returns the blob’s new length.

The declaration of the instance variable is:

blob ib_blob

Example 4

The sample code is:

long ll_len

ll_len = Len(ib_blob)  // ll_len set to 0

ib_blob = Blob( "Test String")

ll_len = Len(ib_blob)   // ll_len set to 22

Example 5

In the second example, ib_blob is initialized to the size 100 when it is declared. When you call Len for ib_blob, it always returns 100. This example uses BlobEdit, instead of Blob, to assign data to the blob because its size is already established. The declaration of the instance variable is:

blob{100} ib_blob

Example 6

The sample code is:

long ll_len

ll_len = Len(ib_blob) // ll_len set to 100

BlobEdit(ib_blob, 1, "Test String")

ll_len = Len(ib_blob) // ll_len set to 100

 

原文地址:https://www.cnblogs.com/anbylau2130/p/3233166.html