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?