Endianness and Tango
Steven Schveighoffer
schveiguy at yahoo.com
Wed May 28 09:07:05 PDT 2008
"Mael" wrote
> Hello,
>
> this is a noob question, but I'm learning Tango/D, and I'm a bit lost with
> all the possibilities I'm offered to read/write a file. The format of the
> file is a bit fuzzy, since it has, say, a BigEndian part followed by a
> LittleEndian part, so I must switch protocols in the middle of the reading
> and writing. What should be the
> best approach ?
>
> For now, I do :
>
> read( char[] filename )
> {
> auto file = new FileConduit( filename ) ;
> version( LittleEndian ) auto inp = new EndianInput!( short )( file );
> version( BigEndian ) auto inp = file ;
> read some stuf... ;
>
> version( LittleEndian ) auto inp2 = file ;
> version( BigEndian ) auto inp2 = new EndianInput!( float )( file );
> read some stuff... ;
> }
>
> and same for writing (with FileConduit.WriteCreate, and EndianOutput!(
> short ))
>
> the reading seems to work fine, but the writing does not work (looks like
> when I do the second outpf = file ; it starts writing again from the
> beginning of the file rather than where I left it before. Plus the code
> looks ugly, to me, and I don't like having to specify the
> EndianInput!(short) thing, I'd prefer to tell at the point where I read
> something, what is the value I will be reading. Someone has a clue ?
You should probably use the Protocol classes as they allow reading/writing
different types from/to a stream without re-opening.
i.e.:
// the second argument says don't expect a length argument for arrays.
version( LittleEndian ) auto proto = new EndianProtocol( file, false ) ;
version( BigEndian ) auto proto = new NativeProtocol( file, false);
auto inp = new Reader(proto);
short[4] res;
auto _res = res[];
inp.get( _res );
if( res[0] != 0x4952 )
throw new Exception( "Invalid RIM file" );
int length_comment = res[1] ;
this.width = res[2] ;
this.height = res[3] ;
assert( width >= 0 && height >= 0 );
int length_header = base_length_header + length_comment ;
file.seek( length_header );
inp.buffer.clear(); // flush all content out of the buffer
this.data = new float[width*height] ;
inp.read( data );
Note: didn't compile this or test it :)
-Steve
More information about the Digitalmars-d-learn
mailing list