Using Raw ByteString

What if you need to pass an AnsiString as a parameter to a routine? When the parameter is assigned to a specific string type with an encoding, it will be converted to the proper type, with the potential for data loss. That's why Delphi 2009 introduces yet another custom string type, called RawByteString and defined as: type

RawByteString = type AnsiString($ffff);

This is definition creates a string type with no encoding or, to be more precise, with the placeholder $ffff indicating "no encoding". A RawByteString can be considered as a string of bytes, which ignores the attached encoding in case of an automatic conversion when assigning to an AnsiString. In other words, when passing a 1-byte per character string as a RawByteString parameter, no conversion is performed, unlike any other AnsiString derived type. You can do a specific conversion by calling the SetCodePage routine, as demonstrated earlier in the section "Converting Strings".

As such, it can become a handy replacement of the string (or AnsiString) type in code that uses strings for generic and custom data processing which you want to keep with a 1-byte per character representation44.

Declaring variables of type RawByteString for storing an actual string should rarely be done45. Given the undefined code page, this can lead to

44 Don't be confused by this extended support for 1-byte per character Ansi-compatible strings: the preferred solution is by far to migrate your string processing code to the UnicodeString type. Don't be too tempted by these new extra string types.

45 For some interesting considerations on RawByteString see Jan Goyvaerts blog post at http://www.micro-isv.asia/2008/08/using-rawbytestring-effectively/

undefined behavior and potential data loss. On the other hand if your goal is saving binary data using a string-like memory allocation and representation, you can use the RawByteString in the same way you used AnsiString in past versions of Delphi. Replacing non-string code that used AnsiString with RawByteString is an interesting migration path (as you'll see in the section "Don't Move String Data" of Chapter 3).

For now, let's focus on a typical example in which you can use the Raw-ByteString type as parameter. If you want to display some information about an 8-bit string, you could write either of the following two declarations (these are methods of the main form of the RawTest demo):

procedure DisplayStringData (str: AnsiString); procedure DisplayRawData (str: RawByteString);

The code of the two methods is identical (here I've listed only one of the two):

procedure TFormRawTest.DisplayRawData(

str: RawByteString); begi n

Log ( 'DispJayRawData(str: RawByteString)') ; Log ('String: ' + UnicodeString(str)); Log ('CodePage: ' + IntToStr (StringCodePage (str))); Log ('Address: ' + IntToStr (Integer (Pointer (str)))); end;

Notice the cast to UnicodeString used to display the proper string, which is necessary to avoid the data being treated like a plain AnsiString because of the concatenation of a string literal with a string whose code page is not defined at compile time46.

The reason I show the string memory address (beside its content and code page) is that this will let us determine if the string has been converted (and copied) or if it is the exact same string that was passed as a parameter.

Now we can use an AnsiString variable (not simply assigning a string constant but doing some processing, or the result would be different) and pass it as parameter to the two methods, after logging some string data: procedure TFormRawTest.btnRawAnsiClick(Sender: TObject);

Project Management Made Easy

Project Management Made Easy

What you need to know about… Project Management Made Easy! Project management consists of more than just a large building project and can encompass small projects as well. No matter what the size of your project, you need to have some sort of project management. How you manage your project has everything to do with its outcome.

Get My Free Ebook


Post a comment