Proper way to initialize Bytes with a literal?

Using 4.0.0-preview.4, I want to instantiate an Int with raw byte values (more convenient way for me to write it out) like this:

var bof = Bytes.ofData([
    0x00, 0x06, 0x05, 0x00, 0xF2, 0x15, 0xCC, 0x07,
    0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00
]);

But this doesn’t compile. I get Array<Int> should be haxe.io.BytesData. So I have to add a cast thusly:

var bof = Bytes.ofData(cast [
    0x00, 0x06, 0x05, 0x00
]);

Why is that necessary and is there a reason I can’t just say these values are all actually 8-bit and instantiate accordingly?

On most platforms BytesData is not an Array<Int>.

One way of getting binary data into the compiler is with -resource path/to/file.ext@alias and get it back with haxe.Resource.getBytes('alias') at runtime.

Or you could use a macro that allows you to write something like:

var bof = Literal.bytes(0x00, 0x06, 0x05, 0x00, ...);

That way you can hide all the noise of filling the bytes :wink:

1 Like

Yeah I was thinking about using resource but seemed too convoluted for such short sequences of bytes. And it helps in the code for me to see the byte layout. I like the macro idea (actually I was searching through tink earlier to see if you might’ve made one for this already). It seems to me haxe should have this built-in. I end up doing a lot of bitwise stuff and find its harder to do in haxe than in a lot of other languages.

Upon further though, I think you might actually want this syntax:

var bof = Literal.bytes('00060500');

It’s best to skip any whitespace in the string, so that the bytes can be visually grouped.

It can also be grouped the way you originally said with just the right whitespace in the code.

Of course. The point of using a string is to have less noise, i.e. neither the , nor the 0x carry any information. But using the first notation inherently allows for formatting, hence I suggested allowing the same with strings.

I have pull request for Bytes.ofHex(…) https://github.com/HaxeFoundation/haxe/pull/7346
After merge it will be very simple:

  var bof = Bytes.ofHex( "00060500F215CC070000000006000000");
1 Like

Pull request was merged. For more readability you can set hex string as :

   var data = "
        0x00, 0x06, 0x05, 0x00, 0xF2, 0x15, 0xCC, 0x07,
        0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00
   ";
   var r = ~/0x|\s|:|,/gi;
   data = r.replace(data,"");
   var bof = Bytes.ofHex(data);

A bit lenghty, but you can also use UInt8Array:

import haxe.io.UInt8Array;

...

   var bytes:Bytes = UInt8Array.fromArray([0xcc,0x01,0xFF]).view.buffer;
   trace(bytes.toHex()); // cc01ff
2 Likes