3

I just started learning D today and I really need to read and write data like this:

byte[] bytes = ...;
ByteBuffer buf = new ByteBuffer(bytes);
int a = buf.getInt();
byte b = buf.getByte();
short s = buf.getShort();
buf.putInt(200000);

Is there anything built in to D that can achieve this or must I make it myself?

Max Alibaev
  • 681
  • 7
  • 17
user3441843
  • 137
  • 1
  • 7

2 Answers2

9

I'd suggest looking at std.bitmanip's read, peek, write and append functions. e.g.

ubyte[] buffer = [1, 5, 22, 9, 44, 255, 8];
auto range = buffer; // if you don't want to mutate the original

assert(range.read!ushort() == 261);
assert(range == [22, 9, 44, 255, 8]);

assert(range.read!uint() == 369_700_095);
assert(range == [8]);

assert(range.read!ubyte() == 8);
assert(range.empty);
assert(buffer == [1, 5, 22, 9, 44, 255, 8]);

There is no buffer type - rather they're free functions which operate on ranges of ubyte (which includes ubyte[]) - so they may not work exactly like what you're looking for, but they are designed for the case where you need to extract integral values from an array or some other kind of range of bytes. And if you really want some kind of separate buffer type, then you should be able to create one fairly easily which uses them internally.

Max Alibaev
  • 681
  • 7
  • 17
Jonathan M Davis
  • 37,181
  • 17
  • 72
  • 102
0

The old std.stream module should do the trick: http://dlang.org/phobos/std_stream.html#MemoryStream

MemoryStream buf = new MemoryStream(bytes);
// need to declare the variable ahead of time
int a;
// then read knows what to get due to the declared type
buf.read(a);
byte b;
buf.read(b);
but.write(200000); // that is an int literal so it knows it is int
buf.write(cast(ubyte) 255); // you can also explicitly cast

As the warning on the page says though, the Phobos maintainers don't like this module and want to kill it... but they've been saying that for years, I'd just go ahead and use it. Or make a private copy of the stream.d source if you like.

Max Alibaev
  • 681
  • 7
  • 17
Adam D. Ruppe
  • 25,382
  • 4
  • 41
  • 60
  • 2
    It's always a bad idea to use deprecated symbols - let alone modules - from Phobos. It's true that std.stream had a note on it for quite a while that it was going to be removed without it actually being deprecated, but at this point, it has actually been deprecated (meaning that using it will mean that you'll see deprecation messages - and potentially a lot of them), and it _will_ be removed, at which point any code still using it will break. So, if you want to use std.stream, feel free, but copy it into your own code base. – Jonathan M Davis Mar 09 '16 at 06:01
  • 1
    Downvoting this, because there exist non-deprecated solutions. – Bauss Mar 09 '16 at 07:39
  • 1
    If there are, then write your own answer! – DejanLekic Mar 09 '16 at 07:52