/* ZBinaryReader.hpp Author: Patrick Baggett #include class ZBinaryReader { public: ZBinaryReader(SST_ByteOrder streamOrder) : streamByteOrder(streamOrder) { } //SINGLE ELEMENT READ /* virtual public ZBinaryReader::ReadU8 Reads a single unsigned 8-bit value from the stream. No validation is performed. @return (uint8_t) - value read from the stream */ virtual uint8_t ReadU8() = 0; /* virtual public ZBinaryReader::ReadU16 Reads a single unsigned 16-bit value from the stream. No validation is performed. @return (uint16_t) - value read from the stream */ virtual uint16_t ReadU16() = 0; /* virtual public ZBinaryReader::ReadU32 Reads a single unsigned 32-bit value from the stream. No validation is performed. @return (uint32_t) - value read from the stream */ virtual uint32_t ReadU32() = 0; /* virtual public ZBinaryReader::ReadU64 Reads a single unsigned 64-bit value from the stream. No validation is performed. @return (uint64_t) - value read from the stream */ virtual uint64_t ReadU64() = 0; /* public ZBinaryReader::ReadF32 Reads a single 32-bit floating point value from the stream. No validation is performed. @return (float) - value read from the stream */ float ReadF32() { return cast_i2f(ReadU32()); } /* public ZBinaryReader::ReadF64 Reads a single 64-bit floating point value from the stream. No validation is performed. @return (double) - value read from the stream */ double ReadF64() { return cast_i2d(ReadU64()); } //===================================================================== //ARRAY READ //===================================================================== /* virtual public ZBinaryReader::ReadU8Array Reads an array of 8-bit unsigned values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ virtual void ReadU8Array(uint8_t* ptr, size_t count) = 0; /* virtual public ZBinaryReader::ReadU16Array Reads an array of 16-bit unsigned values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ virtual void ReadU16Array(uint16_t* ptr, size_t count) = 0; /* virtual public ZBinaryReader::ReadU32Array Reads an array of 32-bit unsigned values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ virtual void ReadU32Array(uint32_t* ptr, size_t count) = 0; /* virtual public ZBinaryReader::ReadU64Array Reads an array of 64-bit unsigned values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ virtual void ReadU64Array(uint64_t* ptr, size_t count) = 0; /* public ZBinaryReader::ReadF32Array Reads an array of 32-bit floating point values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ void ReadF32Array(float* ptr, size_t count) { ReadU32Array((uint32_t*)ptr, count); } /* public ZBinaryReader::ReadF64Array Reads an array of 64-bit floating point values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ void ReadF64Array(double* ptr, size_t count) { ReadU64Array((uint64_t*)ptr, count); } //===================================================================== //STREAM SEEKING / POSITIONING //===================================================================== /* virtual public ZBinaryReader::GetLength Gets the total length of the stream in bytes. @return (size_t) - The total length of the stream */ virtual size_t GetLength() const = 0; /* virtual public ZBinaryReader::GetOffset Gets the current (zero-based) offset into the stream from which the next read will be performed. @return (size_t) - The offset. */ virtual size_t GetOffset() const = 0; /* public ZBinaryReader::SeekForward Advances the offset into the stream by the given number of bytes. No validation is performed. @param amount - The amount of seek forward by. @return (void) */ void SeekForward(size_t amount) { SeekTo(GetOffset() + amount); } /* public ZBinaryReader::SeekBackward Rewinds the offset into the stream by the given number of bytes. No validation is performed. @param amount - The amount of seek backward by. @return (void) */ void SeekBackward(size_t amount) { SeekTo(GetOffset() - amount); } /* virtual public ZBinaryReader::SeekTo Directly sets the offset into the stream from which reads will occur. No validation is performed. @param offset - The new offset @return (void) */ virtual void SeekTo(size_t offset) = 0; /* public ZBinaryReader::Rewind Sets the offset to the start of the stream @param offset - The new offset @return (void) */ void Rewind() { SeekTo(0); } /* public ZBinaryReader::CanRead Checks if the given number of bytes can be read @param bytes - The number of bytes that wish to be read @return (void) */ bool CanRead(size_t bytes) const { return (GetLength() - GetOffset() >= bytes); } //===================================================================== //SAFE SEEK FUNCTIONS //===================================================================== /* public ZBinaryReader::SafeSeekForward Attempts to advance the offset into the stream by the given number of bytes. If this would produce an out-of-bounds result, then false is returned and the offset is not adjusted, otherwise, the offset is adjusted and true is returned. @param amount - The amount to seek forward by @return (bool) - True if the seek operation succeeded, false if the value was invalid */ bool SafeSeekForward(size_t amount) { bool ok = (GetLength() - GetOffset() > amount); //i.e. length > offset + amount if(ok) SeekTo(GetOffset() + amount); return ok; } /* public ZBinaryReader::SafeSeekBackward Attempts to rewind the offset into the stream by the given number of bytes. If this would produce an out-of-bounds result, then false is returned and the offset is not adjusted, otherwise, the offset is adjusted and true is returned. @param amount - The amount to seek backward by @return (bool) - True if the seek operation succeeded, false if the value was invalid */ bool SafeSeekBackward(size_t amount) { bool ok = (GetOffset() >= amount); //i.e. offset - amount >= 0 if(ok) SeekTo(GetOffset() - amount); return ok; } /* public ZBinaryReader::SafeSeekTo Attempts to set the offset into the stream directly. If the new offset is out-of-bounds, then false is returned and the offset is not adjusted, otherwise, the offset is adjusted and true is returned. @return (bool) - True if the seek operation succeeded, false if the value was invalid */ bool SafeSeekTo(size_t offset) { bool ok = (offset < GetLength()); if(ok) SeekTo(offset); return ok; } //===================================================================== //SAFE READ FUNCTIONS //===================================================================== /* public ZBinaryReader::SafeReadU8 Attempt to reads a single unsigned 8-bit value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadU8(uint8_t* ptr) { bool ok = CanRead(sizeof(uint8_t)); if(ok) *ptr = ReadU8(); return ok; } /* public ZBinaryReader::SafeReadU16 Attempt to reads a single unsigned 16-bit value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadU16(uint16_t* ptr) { bool ok = CanRead(sizeof(uint16_t)); if(ok) *ptr = ReadU16(); return ok; } /* public ZBinaryReader::SafeReadU32 Attempt to reads a single unsigned 32-bit value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadU32(uint32_t* ptr) { bool ok = CanRead(sizeof(uint32_t)); if(ok) *ptr = ReadU32(); return ok; } /* public ZBinaryReader::SafeReadU64 Attempt to reads a single unsigned 64-bit value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadU64(uint64_t* ptr) { bool ok = CanRead(sizeof(uint64_t)); if(ok) *ptr = ReadU64(); return ok; } /* public ZBinaryReader::SafeReadF32 Attempt to reads a single 32-bit floating point value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadF32(float* ptr) { bool ok = CanRead(sizeof(float)); if(ok) *ptr = ReadF32(); return ok; } /* public ZBinaryReader::SafeReadF64 Attempt to reads a single 64-bit floating point value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadF64(double* ptr) { bool ok = CanRead(sizeof(double)); if(ok) *ptr = ReadF64(); return ok; } /* public ZBinaryReader::SafeReadU8Array Attempt to reads an array of unsigned 8-bit values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadU8Array(uint8_t* ptr, size_t count) { bool ok = CanRead(count); if(ok) ReadU8Array(ptr, count); return ok; } /* public ZBinaryReader::SafeReadU16Array Attempt to reads an array of unsigned 16-bit values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadU16Array(uint16_t* ptr, size_t count) { bool ok = (SIZE_MAX / count > sizeof(uint16_t)); //i.e. SIZE_MAX > count * size ok = ok && CanRead(count * sizeof(uint16_t)); if(ok) ReadU16Array(ptr, count); return ok; } /* public ZBinaryReader::SafeReadU32Array Attempt to reads an array of unsigned 32-bit values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadU32Array(uint32_t* ptr, size_t count) { bool ok = (SIZE_MAX / count > sizeof(uint32_t)); //i.e. SIZE_MAX > count * size ok = ok && CanRead(count * sizeof(uint32_t)); if(ok) ReadU32Array(ptr, count); return ok; } /* public ZBinaryReader::SafeReadU64Array Attempt to reads an array of unsigned 64-bit values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadU64Array(uint64_t* ptr, size_t count) { bool ok = (SIZE_MAX / count > sizeof(uint64_t)); //i.e. SIZE_MAX > count * size ok = ok && CanRead(count * sizeof(uint64_t)); if(ok) ReadU64Array(ptr, count); return ok; } /* public ZBinaryReader::SafeReadF32Array Attempt to reads an array of 32-bit floating point values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadF32Array(float* ptr, size_t count) { return SafeReadU32Array((uint32_t*)ptr, count); } /* public ZBinaryReader::SafeReadF64Array Attempt to reads an array of 64-bit floating point values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadF64Array(double* ptr, size_t count) { return SafeReadU64Array((uint64_t*)ptr, count); } //===================================================================== //TYPED ALIASES //===================================================================== /* public ZBinaryReader::ReadI8 Reads a single signed 8-bit value from the stream. No validation is performed. @return (int8_t) - value read from the stream */ int8_t ReadI8() { return (int8_t)ReadU8(); } /* public ZBinaryReader::ReadI16 Reads a single signed 16-bit value from the stream. No validation is performed. @return (int16_t) - value read from the stream */ int16_t ReadI16() { return (int16_t)ReadU16(); } /* public ZBinaryReader::ReadI32 Reads a single signed 32-bit value from the stream. No validation is performed. @return (int32_t) - value read from the stream */ int32_t ReadI32() { return (int32_t)ReadU32(); } /* public ZBinaryReader::ReadI64 Reads a single signed 64-bit value from the stream. No validation is performed. @return (int64_t) - value read from the stream */ int64_t ReadI64() { return (int64_t)ReadU64(); } /* public ZBinaryReader::ReadI8Array Reads an array of 8-bit signed values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ void ReadI8Array(int8_t* ptr, size_t count) { return ReadU8Array((uint8_t*)ptr, count); } /* public ZBinaryReader::ReadI16Array Reads an array of 16-bit signed values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ void ReadI16Array(int16_t* ptr, size_t count) { return ReadU16Array((uint16_t*)ptr, count); } /* public ZBinaryReader::ReadI32Array Reads an array of 32-bit signed values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ void ReadI32Array(int32_t* ptr, size_t count) { return ReadU32Array((uint32_t*)ptr, count); } /* public ZBinaryReader::ReadI64Array Reads an array of 64-bit signed values from the stream. No validation is performed. @param ptr - The base of the array @param count - Number of elements to read @return (void) */ void ReadI64Array(int64_t* ptr, size_t count) { return ReadU64Array((uint64_t*)ptr, count); } /* public ZBinaryReader::SafeReadI8 Attempt to reads a single signed 8-bit value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadI8(int8_t* ptr) { return SafeReadU8((uint8_t*)ptr); } /* public ZBinaryReader::SafeReadI16 Attempt to reads a single signed 16-bit value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadI16(int16_t* ptr) { return SafeReadU16((uint16_t*)ptr); } /* public ZBinaryReader::SafeReadI32 Attempt to reads a single signed 32-bit value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadI32(int32_t* ptr) { return SafeReadU32((uint32_t*)ptr); } /* public ZBinaryReader::SafeReadI64 Attempt to reads a single signed 64-bit value from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the value is read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the read value at @return (bool) - If the value was successfully read */ bool SafeReadI64(int64_t* ptr) { return SafeReadU64((uint64_t*)ptr); } /* public ZBinaryReader::SafeReadI8Array Attempt to reads an array of signed 8-bit values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadI8Array(int8_t* ptr, size_t count) { return SafeReadU8Array((uint8_t*)ptr, count); } /* public ZBinaryReader::SafeReadI16Array Attempt to reads an array of signed 16-bit values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadI16Array(int16_t* ptr, size_t count) { return SafeReadU16Array((uint16_t*)ptr, count); } /* public ZBinaryReader::SafeReadI32Array Attempt to reads an array of signed 32-bit values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadI32Array(int32_t* ptr, size_t count) { return SafeReadU32Array((uint32_t*)ptr, count); } /* public ZBinaryReader::SafeReadI64Array Attempt to reads an array of signed 64-bit values from the stream. If this would result in reading out of bounds, false is returned and *ptr is unmodified, otherwise the values are read and stored at *ptr and true is returned. No validation is performed. @param ptr - The address to store the values @param count - The number of values to read @return (bool) - If the array was successfully read */ bool SafeReadI64Array(int64_t* ptr, size_t count) { return SafeReadU64Array((uint64_t*)ptr, count); } //===================================================================== //GETTERS / SETTERS //===================================================================== /* public ZBinaryReader::GetStreamByteOrder Gets the byte order in which the stream (source data) is read as. @return (SST_ByteOrder) - The byte order */ SST_ByteOrder GetStreamByteOrder() const { return streamByteOrder; } /* public ZBinaryReader::SetStreamByteOrder Sets the byte order in which the stream (source data) is read as. @param newOrder - The new byte order @return (void) */ void SetStreamByteOrder(SST_ByteOrder newOrder) { streamByteOrder = newOrder; } private: SST_ByteOrder streamByteOrder; //The current byte order the stream is being read in. }; #endif