www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Streams vs ranges

reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Is there a plan to replace streams with byte ranges? Or should I just 
use streams?

I need to do some binary parsing and I found using ranges is not very 
comfortable. For example to read an uint I need to:

version (LittleEndian)
     auto r = retro(takeExactly(range, 4));
else
     auto r = takeExactly(range, 4);

uint u;
auto ar = (cast(ubyte*)&u)[0 .. 4];
replaceInPlace(ar, 0, 4, r);

while with streams its easier:

uint u;
stream.read(u);
version (LittleEndian)
     u = swapEndian(u);
Jan 13 2012
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, January 13, 2012 12:17:06 Piotr Szturmaj wrote:
 Is there a plan to replace streams with byte ranges? Or should I just
 use streams?

At some point, std.stream will be replace with a range-based API. There has been some discussion on the design, but it hasn't been fully fleshed out, let alone implemented yet.
 I need to do some binary parsing and I found using ranges is not very
 comfortable. For example to read an uint I need to:
 
 version (LittleEndian)
      auto r = retro(takeExactly(range, 4));
 else
      auto r = takeExactly(range, 4);
 
 uint u;
 auto ar = (cast(ubyte*)&u)[0 .. 4];
 replaceInPlace(ar, 0, 4, r);
 
 while with streams its easier:
 
 uint u;
 stream.read(u);
 version (LittleEndian)
      u = swapEndian(u);

Just because it's a range doesn't mean that there won't be a function allowing you to do something something more like auto val = read!int(range); That sort of thing will have to be discussed and sorted out when the stream API is overhauled. Unfortunately, it's one of those things that seems to be forever on the TODO list. - Jonathan M Davis
Jan 13 2012
parent Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Jonathan M Davis wrote:
 On Friday, January 13, 2012 12:17:06 Piotr Szturmaj wrote:
 Is there a plan to replace streams with byte ranges? Or should I just
 use streams?

At some point, std.stream will be replace with a range-based API. There has been some discussion on the design, but it hasn't been fully fleshed out, let alone implemented yet.

 I need to do some binary parsing and I found using ranges is not very
 comfortable. For example to read an uint I need to:

 version (LittleEndian)
       auto r = retro(takeExactly(range, 4));
 else
       auto r = takeExactly(range, 4);

 uint u;
 auto ar = (cast(ubyte*)&u)[0 .. 4];
 replaceInPlace(ar, 0, 4, r);

 while with streams its easier:

 uint u;
 stream.read(u);
 version (LittleEndian)
       u = swapEndian(u);

Just because it's a range doesn't mean that there won't be a function allowing you to do something something more like auto val = read!int(range); That sort of thing will have to be discussed and sorted out when the stream API is overhauled. Unfortunately, it's one of those things that seems to be forever on the TODO list.

Thanks for clarifying this. Btw. I find those endian conversions little uncomfortable. I'm talking about: version(LittleEndian) swapEndian() instead of directly calling bigEndianToNative() on uint. I know ubyte[4] param is to avoid mistakes, but I think most of the time programmers know what they do, so IMHO these preventions are unnecessary if we convert integers only. I would leave ubyte[4] params as they are and create overloads for integers using regular int params.
Jan 13 2012