Subject Re: [IBO] How can I write binary bytes on CHAR(20) field?
Author Paul Vinkenoog
Hi Hugo,

> I have problems writing sequences of arbitrary bytes (including
> binary zero) in CHAR()/VARCHAR() CHARACTER SET OCTETS field.
> Which TIB_Colum method must I use?
> I'm trying with AsString, AsRawString, ColData, even SetBlobData(),
> and I can't get my string char (with #0 byte in the middle) be
> assigned. The value always is truncated at the #0 byte position.
> I'm working with WinXP, Firebird 1.0, IBO 4.2Hi, C++Builder5.
> My code is something like this:
>
> char my_string[10];
> memset(my_string,0,10);
> *(my_string+0)=65; // 'A'
> *(my_string+1)=66; // 'B'
> *(my_string+2)=0; // this breaks all :(
> *(my_string+3)=67; // 'C'
> *(my_string+4)=68; // 'D'
>
> IB_Query1->FieldByName("MY_COMMAND")->AsString=my_string;
> or
> IB_Query1->FieldByName("MY_COMMAND")->AsRawString=my_string;
> or
> IB_Query1->FieldByName("MY_COMMAND")->SetBlobData(my_string,5);
>
> Always assign "AB", and the rest of the string is lost.
> There is not an AsBinary method?

This is a C problem, not an IBO problem. You declare my_string as a
char array, i.e. as a char*.

When you assign my_string to an AnsiString, BCB will convert the data
pointed to by my_string, but will of course expect a zero-terminated
string of characters and stop at the first 0. That's why AsString and
AsRawString fail.

About SetBlobData... does that also assign "AB", or does it fail
completely? If it fails completely that's understandable because the
column isn't a Blob. If it assigns "AB" I don't understand why.

Anyway: an AnsiString can contain any characters including zeroes.
Just use a temp AnsiString and call the right constructor:

AnsiString MyAnsiString( my_string, 5 );
IB_Query1->FieldByName("MY_COMMAND")->AsString = MyAnsiString;

You could also condense this to:

IB_Query1->FieldByName("MY_COMMAND")->AsString =
AnsiString( my_string, 5 );

In Delphi, you can store strings containing 0's directly, like this:

MyAnsiString := 'This string'#0' has an embedded 0';

In C++, you could build my_string a lot quicker like this (at least
if the value is known at design time):

char my_string[] = "AB\0CD";

But then, you could skip my_string altogether:

IB_Query1->FieldByName("MY_COMMAND")->AsString =
AnsiString( "AB\0CD", 5 );


Greetings,
Paul Vinkenoog