Thread overview
std.stream.EndianStream ...
Feb 08, 2007
nescire
Feb 08, 2007
torhu
Feb 08, 2007
Ben Hinkle
Feb 08, 2007
torhu
Feb 08, 2007
nescire
Feb 09, 2007
torhu
February 08, 2007
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


February 08, 2007
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.
February 08, 2007
"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.


February 08, 2007
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?
February 08, 2007
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!
February 09, 2007
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.