0

I have a Buffer which wraps a stream of binary data. The first byte indicates order, either big endian or little endian, which is needed to unpack the data.

 class FooBuffer implements Buffer is
 private field stream: resource
 private field order: int
 constructor FooBuffer(stream) is
 this.stream = stream
 this.order = unpack("C", fread(this.stream, 1)) // unpacking 1 byte unsigned char
 method readUnsignedLong():int is
 return unpack(this.order ? "V" : "N", fread(this.stream, 4))
 method readDouble():double is
 method writeUnsignedLong(data):int is
 return fwrite(this.stream, pack(this.order ? "V" : "N", data))
 method writeDouble(data):int is
 // and other methods rewind() eof() seek() close()

There is no problem with reading, but for writing we have to somehow indicate which order to use.

 empty_resource = "";
 stream = new FooBuffer(empty_resource, SYSTEM_BYTE_ORDER or LITTLE_ENDIAN or BIG_ENDIAN)

Additional parameter to our constructor can be added

 constructor FooBuffer(stream, order) is
 this.stream = stream
 if (this.stream != "")
 this.order = unpack("C", fread(this.stream, 1))
 else
 fwrite(this.stream, pack("C", order))
 this.order = order

But in this case we end up with information redundancy, also it's prone to error in case the order and the data do not match.

 hex_resource = 0x00ABCDEF010101010101010101010; // all data encoded with big endian 00 
 stream = new FooBuffer(to_binary(hex_resource), 01) // we pass little endian as order

Now we dont know what is important order value that we put in constructor or order from resource. Do I need a separate factory so I can pass order along with displaced resource pointer?

 class FooBufferFactory implements BufferFactory is
 private field stream: resource
 constructor FooBufferFactory(stream) is
 this.stream = stream
 method createBuffer():Buffer is
 order = unpack("C", fread(this.stream, 1))
 // will read correctly because pointer already moved
 return new FooBuffer(this.stream, order)

or I need to keep this logic inside constructor, or there is any other solution?

Summary, what is the correct OOP way to read/write binary data if meta information of how data is encoded are stored inside data itself?

Robert Harvey
201k55 gold badges470 silver badges682 bronze badges
asked Jun 15, 2020 at 0:03
3
  • 1
    Does a FooBuffer support reading and writing of the same resource? If so, can you read the resource as big-endian and the write it as little-endian? Commented Jun 15, 2020 at 9:16
  • Is this Java? .. Commented Jun 15, 2020 at 20:49
  • I suggest splitting into two classes, one for reading and one for writing. Greatly simplifies things. Commented Nov 24, 2021 at 17:52

1 Answer 1

2

Endianess is stored in two different places in your code.

  • If the stream is not empty, the endianess is a property of the stream.
  • If the stream is empty, the endianess is introduced when creating the buffer.

I propose to change the stream to include the endianess property. Its constructor will write the first byte in the stream. The buffer can then read that property from the stream.

answered Jun 15, 2020 at 19:21
1
  • 4
    I don't agree. A stream is just a stream; it knows nothing about endianness. It's the responsibility of the reader and writer to manage the proper byte order. Commented Jun 15, 2020 at 19:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.