Thread overview
Binary data in the code?
Nov 04, 2006
Bill Baxter
Nov 04, 2006
Bill Baxter
Nov 04, 2006
BCS
Nov 05, 2006
Bill Baxter
Nov 05, 2006
Bill Baxter
November 04, 2006
How does one embed binary data in code with D?

In C/C++ one would do something like:

  static const unsigned char data[] = {99,12,2,21};

The compiler counts the elements for you, but you still get a compile-time length, so you can do sizeof(data) and you'll get back 4 in the above example.

With D it looks like to get a fixed-size array I have to count the elements myself (annoying if there are a page full of numbers):
  static const ubyte[4] data = {99,12,2,21};

Or live with a dynamic array:
  static const ubyte[] data = {99,12,2,21};

Neither of which seems to be quite what I want, which is to end up with exactly one non-modifiable copy of the data in the data segment.

Thanks,
--bb
November 04, 2006
"Bill Baxter" <wbaxter@gmail.com> wrote in message news:eihhpl$1ish$1@digitaldaemon.com...

> Or live with a dynamic array:
>   static const ubyte[] data = {99,12,2,21};

Actually, if you then write

data.length = 6;

The compiler will complain.

However, getting data.sizeof does still return 8, which is the size of a dynamic array reference.. so.. hmm, confusing.


November 04, 2006
Jarrett Billingsley wrote:
> "Bill Baxter" <wbaxter@gmail.com> wrote in message news:eihhpl$1ish$1@digitaldaemon.com...
> 
> 
>>Or live with a dynamic array:
>>  static const ubyte[] data = {99,12,2,21};
> 
> 
> Actually, if you then write
> 
> data.length = 6;
> 
> The compiler will complain.
> 
> However, getting data.sizeof does still return 8, which is the size of a dynamic array reference.. so.. hmm, confusing. 
> 
> 

Of course one can get the "actual" size by doing 'data.length * (typeof(data[0]).sizeof)' but... ack, if you need to use this a lot (which I assume he will).  Might be another example of where an expression alias would be useful.

-- Chris Nicholson-Sauls
November 04, 2006
Chris Nicholson-Sauls wrote:
> Jarrett Billingsley wrote:
> 
>> "Bill Baxter" <wbaxter@gmail.com> wrote in message news:eihhpl$1ish$1@digitaldaemon.com...
>>
>>
>>> Or live with a dynamic array:
>>>  static const ubyte[] data = {99,12,2,21};
>>
>>
>>
>> Actually, if you then write
>>
>> data.length = 6;
>>
>> The compiler will complain.

The compilers complaints can be useful for the fixed-length array --
  static const ubyte[1 /*intentionally wrong*/] data = [99,12,2,21];

The compiler will complain 'hey 1 is to small for 4 elements'.
Really annoying to have to try to compile once to get the fixed length for the array, but it works.

It seems like there should be a syntax for a fixed-length array with automatically-deduced length.

I suggest either

  static const ubyte[$] data = [99,12,2,21];

taking the '$'-means-length syntax from arrays.  That would suggest that ubyte[length] data should also work.

Or alternatively use the 'auto' keyword:

  static const ubyte[auto] data = [99,12,2,21];


---
Anyway, I do find it useful to embed binary data in the app quite often, so I hope someone can chime in with the right way to do it in D.  It's good for inlining little images and things like that.
In fact, I have a little command line utility program for C++ that I use just for that purpose.  It takes binary files and converts them to C++ source files. (It's a slightly modified version of this: http://fox-toolkit.net/cgi-bin/wiki.pl?Tutorial_14_Reswrap)

I guess if I wrote a D version of that tool then I could have it automatically spit out the length as well, assuming fixed-length arrays are the right way to do this.

--bb
November 04, 2006
== Quote from Bill Baxter (wbaxter@gmail.com)'s article
> How does one embed binary data in code with D?
> In C/C++ one would do something like:
>    static const unsigned char data[] = {99,12,2,21};
> The compiler counts the elements for you, but you still get a
> compile-time length, so you can do sizeof(data) and you'll get
> back 4 in the above example.
[...]
> Thanks,
> --bb


IIRC, this works:

auto data = [cast(char)99,12,2,21];
// type of data == char[4];
November 05, 2006
BCS wrote:
> == Quote from Bill Baxter (wbaxter@gmail.com)'s article
> 
>>How does one embed binary data in code with D?
>>In C/C++ one would do something like:
>>   static const unsigned char data[] = {99,12,2,21};
>>The compiler counts the elements for you, but you still get a
>>compile-time length, so you can do sizeof(data) and you'll get
>>back 4 in the above example.
> 
> [...]
> 
>>Thanks,
>>--bb
> 
> 
> 
> IIRC, this works:
> 
> auto data = [cast(char)99,12,2,21];
> // type of data == char[4];


Ick.  Combines the lack of readability of 'auto' with the lameness of D's first-value array typing rule.

It's beside the point though, since that doesn't actually work.
   staticdata.d(9): Error: cannot infer type from initializer

--bb
November 05, 2006
Bill Baxter wrote:
> BCS wrote:
> 
>> == Quote from Bill Baxter (wbaxter@gmail.com)'s article
>>
>>> How does one embed binary data in code with D?
>>> In C/C++ one would do something like:
>>>   static const unsigned char data[] = {99,12,2,21};
>>> The compiler counts the elements for you, but you still get a
>>> compile-time length, so you can do sizeof(data) and you'll get
>>> back 4 in the above example.
>>
>>
>> [...]
>>
>>> Thanks,
>>> --bb
>>
>>
>>
>>
>> IIRC, this works:
>>
>> auto data = [cast(char)99,12,2,21];
>> // type of data == char[4];
> 
> 
> 
> Ick.  Combines the lack of readability of 'auto' with the lameness of D's first-value array typing rule.
> 
> It's beside the point though, since that doesn't actually work.
>    staticdata.d(9): Error: cannot infer type from initializer
> 
> --bb

Well, if as in the example one wishes to use char[] as the holding data type, one can always just use D's HexStrings.  Then the example becomes:

const data = x"63 0C 02 15"c ;

-- Chris Nicholson-Sauls
November 05, 2006
Chris Nicholson-Sauls wrote:
> Bill Baxter wrote:
> 
>> BCS wrote:
>>
>>> == Quote from Bill Baxter (wbaxter@gmail.com)'s article
>>>
>>>> How does one embed binary data in code with D?
>>>> In C/C++ one would do something like:
>>>>   static const unsigned char data[] = {99,12,2,21};
>>>> The compiler counts the elements for you, but you still get a
>>>> compile-time length, so you can do sizeof(data) and you'll get
>>>> back 4 in the above example.
>>>
>>>
>>>
>>> [...]
>>>
>>>> Thanks,
>>>> --bb
>>>
>>>
>>>
>>>
>>>
>>> IIRC, this works:
>>>
>>> auto data = [cast(char)99,12,2,21];
>>> // type of data == char[4];
>>
>>
>>
>>
>> Ick.  Combines the lack of readability of 'auto' with the lameness of D's first-value array typing rule.
>>
>> It's beside the point though, since that doesn't actually work.
>>    staticdata.d(9): Error: cannot infer type from initializer
>>
>> --bb
> 
> 
> Well, if as in the example one wishes to use char[] as the holding data type, one can always just use D's HexStrings.  Then the example becomes:
> 
> const data = x"63 0C 02 15"c ;
> 
> -- Chris Nicholson-Sauls

No dice:
  static const auto data = x"00 10 A3"c;
  --> ?Error: 4invalid UTF-8 sequence

The ? is actually some non-ascii character.

--bb