Community

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

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.

"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.

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?

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!

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.