View mode: basic / threaded / horizontal-split · Log in · Help
February 08, 2007
std.stream.EndianStream ...
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
Re: std.stream.EndianStream ...
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
Re: std.stream.EndianStream ...
"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
Re: std.stream.EndianStream ...
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
Re: std.stream.EndianStream ...
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
Re: std.stream.EndianStream ...
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.
Top | Discussion index | About this forum | D home