www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - std.stream.EndianStream ...

reply nescire <chrysme gmail.com> writes:
I have trouble understanding this compiler error I ran into while using the
std.stream.EndianStream class.

When trying to compile:

EndianStream es = new EndianStream( new MemoryStream() );
ubyte b;
es.read( b );

dmd gives the error:

function std.stream.EndianStream.read called with argument types:
	(ubyte)
matches both:
	std.stream.EndianStream.read(short)
and:
	std.stream.EndianStream.read(dchar)

Which seems to suggest the EndianStream class does not have a void read( out
ubyte ) method, even though it should inherit it from FilterStream.

And the following code compiles:

EndianStream es = new EndianStream( new MemoryStream() );
ubyte b;
(cast(InputStream) es).read( b );


Could someone explain? Am I missing something obvious, or is it a compiler bug?

nescire
Feb 07 2007
parent reply torhu <fake address.dude> writes:
nescire wrote:
 EndianStream es = new EndianStream( new MemoryStream() );
 ubyte b;
 es.read( b );
 
 dmd gives the error:
 
 function std.stream.EndianStream.read called with argument types:
 	(ubyte)
 matches both:
 	std.stream.EndianStream.read(short)
 and:
 	std.stream.EndianStream.read(dchar)
 
 Which seems to suggest the EndianStream class does not have a void read( out
ubyte ) method, even though it should inherit it from FilterStream.

It's hard to find anything about this in the docs. But it seems overloads are not inherited by default, which is the same behavior as in C++. EndianStream redefine most of the read() overloads, but not the byte and ubyte versions. The read() methods does the actual byteswapping, which wouldn't work on single-byte reads. So this is done on purpose. You would do 'alias SuperClass.method method;' to pull in 'method()' overloads from SuperClass.
 And the following code compiles:
 
 EndianStream es = new EndianStream( new MemoryStream() );
 ubyte b;
 (cast(InputStream) es).read( b );
 
 
 Could someone explain? Am I missing something obvious, or is it a compiler bug?

I'm guessing this makes it call Stream's version of read(ubyte), which will give the wrong result.
Feb 07 2007
parent reply "Ben Hinkle" <bhinkle mathworks.com> writes:
"torhu" <fake address.dude> wrote in message 
news:eqeff9$22i3$1 digitaldaemon.com...
 nescire wrote:
 EndianStream es = new EndianStream( new MemoryStream() );
 ubyte b;
 es.read( b );

 dmd gives the error:

 function std.stream.EndianStream.read called with argument types:
 (ubyte)
 matches both:
 std.stream.EndianStream.read(short)
 and:
 std.stream.EndianStream.read(dchar)

 Which seems to suggest the EndianStream class does not have a void 
 read( out ubyte ) method, even though it should inherit it from 
 FilterStream.

It's hard to find anything about this in the docs. But it seems overloads are not inherited by default, which is the same behavior as in C++. EndianStream redefine most of the read() overloads, but not the byte and ubyte versions. The read() methods does the actual byteswapping, which wouldn't work on single-byte reads. So this is done on purpose. You would do 'alias SuperClass.method method;' to pull in 'method()' overloads from SuperClass.

yeah, looks like that should be added to EndianStream.
 And the following code compiles:

 EndianStream es = new EndianStream( new MemoryStream() );
 ubyte b;
 (cast(InputStream) es).read( b );


 Could someone explain? Am I missing something obvious, or is it a 
 compiler bug?

I'm guessing this makes it call Stream's version of read(ubyte), which will give the wrong result.

Why is that the wrong result? EndianStream only swaps when reading multi-byte data since there's nothing to swap with a single byte.
Feb 08 2007
parent reply torhu <fake address.dude> writes:
Ben Hinkle wrote:
 "torhu" <fake address.dude> wrote in message 
 news:eqeff9$22i3$1 digitaldaemon.com...
 nescire wrote:
 EndianStream es = new EndianStream( new MemoryStream() );
 ubyte b;
 es.read( b );

 dmd gives the error:

 function std.stream.EndianStream.read called with argument types:
 (ubyte)
 matches both:
 std.stream.EndianStream.read(short)
 and:
 std.stream.EndianStream.read(dchar)

 Which seems to suggest the EndianStream class does not have a void 
 read( out ubyte ) method, even though it should inherit it from 
 FilterStream.

It's hard to find anything about this in the docs. But it seems overloads are not inherited by default, which is the same behavior as in C++. EndianStream redefine most of the read() overloads, but not the byte and ubyte versions. The read() methods does the actual byteswapping, which wouldn't work on single-byte reads. So this is done on purpose. You would do 'alias SuperClass.method method;' to pull in 'method()' overloads from SuperClass.

yeah, looks like that should be added to EndianStream.

Why? Stream's methods don't do byteswapping, which seems to be the whole point of EndianStream.
 
 And the following code compiles:

 EndianStream es = new EndianStream( new MemoryStream() );
 ubyte b;
 (cast(InputStream) es).read( b );


 Could someone explain? Am I missing something obvious, or is it a 
 compiler bug?

I'm guessing this makes it call Stream's version of read(ubyte), which will give the wrong result.

Why is that the wrong result? EndianStream only swaps when reading multi-byte data since there's nothing to swap with a single byte.

Is EndianStream supposed to be used for single-byte reads too?
Feb 08 2007
parent reply nescire <chrysme gmail.com> writes:
torhu Wrote:
 And the following code compiles:

 EndianStream es = new EndianStream( new MemoryStream() );
 ubyte b;
 (cast(InputStream) es).read( b );


 Could someone explain? Am I missing something obvious, or is it a 
 compiler bug?

I'm guessing this makes it call Stream's version of read(ubyte), which will give the wrong result.

Why is that the wrong result? EndianStream only swaps when reading multi-byte data since there's nothing to swap with a single byte.

Is EndianStream supposed to be used for single-byte reads too?

It seemed to me that EndianStream was supposed to wrap a source stream to provide byte swapping on multi-byte read/write. I don't think the rest of FilterStream's functionality should be affected. The stream itself doesn't necesserily contain multi-byte data only, e.g. it can contain flag bytes, followed by multi-byte data (which is what I wanted to use EndianStream for). And by the way, thanks for the help!
Feb 08 2007
parent torhu <fake address.dude> writes:
nescire wrote:
 It seemed to me that EndianStream was supposed to wrap a source stream to
provide byte swapping on multi-byte read/write. I don't think the rest of
FilterStream's functionality should be affected.
 The stream itself doesn't necesserily contain multi-byte data only, e.g. it
can contain flag bytes, followed by multi-byte data (which is what I wanted to
use EndianStream for).

According to the docs for EndianStream, it should be safe to do this: auto stream = new EndianStream(source); ubyte flags; stream.source.read(flags); // call source stream's read() directly
 
 And by the way, thanks for the help!

You're welcome.
Feb 08 2007