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