cancel
Showing results for 
Search instead for 
Did you mean: 

Differences in blob handling between PowerBuilder 8.03 and 12.6

Former Member
0 Kudos

I'm migrating an application from PowerBuilder 8.03 to PowerBuilder 12.6. The only thing that doesn't work correctly is a module which works with blob variables that contain string data. I've found three functions that give different results in versions 8.03 and 12.6:

  • The len function returns 100 in 8.03 and 200 in 12.6. In both cases, the same 100-character string had been converted to a blob and stored in a blob variable, and the len function was performed on the blob variable.
  • BlobMid returns a blob that converts to a 2-character string in 8.03, but only half that in 12.6. Specifically, 8.03 returned "vv" but 12.6 only returned "v".
  • BlobEdit gives different results in the two versions.

I noticed that  in PB 12 the BlobEdit function takes an additional, optional parameter to specify the encoding format for string values.

I have two questions:

First, what changed between version 8.03 and 12.6 that causes these differences? Second, is there a value for the encoding parameter that would make the BlobEdit function give the same result in 12.6 that it did in 8.03?

Thanks in advance.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

The major change is that you now need to specify the encoding.

BlobMid ( lBlob , 1234 , EncodingAnsi! )

or 

BlobMid ( lBlob , 1234 , EncodingUTF8! )

Former Member
0 Kudos

Good excuse my English, I use the PowerBuilder 10.5 made a query to a database that contains PDF files with SelectBlob and want to transform it to a PDF file returns me corrupt file and double the size.

In PowerBuilder 9.0 if it works, please if you could help me and I'm 2 days with that problem.

The following is the function.

li_numarch = FileOpen (ls_pathname, streamMode !, write !, lockwrite !, Replace!)

li_numarch if <0 then return -1

ll_BlobLen = Len (a_blob)

If ll_BlobLen> 32765 Then

    If Mod (ll_BlobLen, 32765) = 0 Then

       li_Writes = ll_BlobLen / 32765

    else

       li_Writes = (ll_BlobLen / 32765) + 1

    End if

else

    li_Writes = 1

End if

ll_CurrentPos = 1

For li_Cnt = 1 To li_Writes

    ls_blob = BlobMid (a_blob, ll_CurrentPos, 32765)

    ll_CurrentPos + = 32765

    If FileWrite (li_numarch, ls_blob) = -1 Then

FileClose (li_numarch)

FileDelete (ls_pathname)

return -1

end if

Next

FileClose (li_numarch)

Answers (5)

Answers (5)

Former Member
0 Kudos

PowerBuilder 10 and higher are Unicode (2 bytes per string character) and PowerBuilder 9 and lower are Ansi (1 byte per string character). This is something to keep in mind when moving from PB 8.

PB 10.5 has a new function FileWriteEx which will allow you to write the entire blob at one time. Try using one call to FileWriteEx passing the entire blob variable instead.

Former Member
0 Kudos

Many thanks to all of you who posted replies. If the web site had allowed, I would have marked all your responses as correct, because they all were. You gave me the info I desperately needed, explaining it from different angles. Giving the EncodingUTF8! argument with the calls to the Blob, BlobEdit, and String functions gave me the results I needed.

Former Member
0 Kudos

The Char datatype is Unicode as well.

Former Member
0 Kudos

This message was moderated.

Former Member
0 Kudos

The answer is Unicode - welcome to 2015. Internal encoding for all strings in Powerbuilder is Unicode DBCS (i.e. 2 bytes per character) and has been for many years. I thought it changed from Powerbuilder 8.0, but could be wrong (that is a long time ago now!).

It sounds like your blobs are encoded as Ansi ASCII characters i.e. 1 byte per character. Powerbuilder has no way of knowing what your blobs contain - that is only knowledge only you have (or should have!). If they contain ASCII encoded strings you need to tell Powerbuilder what they contain when you work with them.

Re BlobEdit() - assuming your blobs are encoded at EncodingAnsi! (because that was the default in earlier versions of Powerbuilder when the blobs were created) try using that argument to the BlobEdit() function.

Or alternatively stop using blobs to store string-type data in your database, and migrate the column(s) to character/text type.

Former Member
0 Kudos

Thank you for this information. It is exactly what I needed to know.

The data in question is actually stored in the database in a character field. The data in question is a set of screen permissions, which are encoded. The security object takes a set of true/false values, converts them to integers using an algorithm that makes sure a particular permission is mapped to a certain digit, and then converts the resulting integer to a string. I didn't create this object, and the person who did left the company a long time ago. For some reason I don't understand, instead of doing a straight string concatenation, the string is converted to a blob, and the concatenation is done with BlobEdit.. If I could have figured out how to get the correct result with pure string functions, I would have.

Either the ANSI format or the UTF8 format gave the correct results when reading the permissions in and decoding them. However, ANSI gave the wrong result when encoding the permissions. I tried replacing ANSI with UTF8, and that did the trick.

I intended to mark your answer as "CORRECT", but the website seems to only allow one "correct answer", and the others can only be "helpful". ALL the answers I got to my question were correct. I am impressed with how helpful people in the SAP community are.

-Mary Anne Green

Former Member
0 Kudos

PB went full Unicode-compliant with the release of v10.  So all strings are now double-byte.  Any blob-to-string (or vice versa) conversion will be affected.

-Paul-

Former Member
0 Kudos

Good excuse my English, I use the PowerBuilder 10.5 made a query to a database that contains PDF files with SelectBlob and want to transform it to a PDF file returns me corrupt file and double the size.

In PowerBuilder 9.0 if it works, please if you could help me and I'm 2 days with that problem.

The following is the function.

li_numarch = FileOpen (ls_pathname, streamMode !, write !, lockwrite !, Replace!)

li_numarch if <0 then return -1

ll_BlobLen = Len (a_blob)

If ll_BlobLen> 32765 Then

    If Mod (ll_BlobLen, 32765) = 0 Then

       li_Writes = ll_BlobLen / 32765

    else

       li_Writes = (ll_BlobLen / 32765) + 1

    End if

else

    li_Writes = 1

End if

ll_CurrentPos = 1

For li_Cnt = 1 To li_Writes

    ls_blob = BlobMid (a_blob, ll_CurrentPos, 32765)

    ll_CurrentPos + = 32765

    If FileWrite (li_numarch, ls_blob) = -1 Then

FileClose (li_numarch)

FileDelete (ls_pathname)

return -1

end if

Next

FileClose (li_numarch)