// Copyright (c) 2013 by István Váradi // This file is part of VSCPL, a simple cross-platform utility library // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // 1. Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // The views and conclusions contained in the software and documentation are those // of the authors and should not be interpreted as representing official policies, // either expressed or implied, of the FreeBSD Project. #ifndef HU_VARADIISTVAN_SCPL_IO_DATASTREAM_H #define HU_VARADIISTVAN_SCPL_IO_DATASTREAM_H //------------------------------------------------------------------------------ #include "BlockingStream.h" #include #include #include //------------------------------------------------------------------------------ namespace hu { namespace varadiistvan { namespace scpl { namespace io { //------------------------------------------------------------------------------ /** * A blocking stream with extra functions to read and write values of * basic data types. The values are read and written in host * byte-order, so this stream does not work properly between machines * of different endianness. * * The reading functions return the value read and you can check of * error or interruption only by calling the appropriate * functions. The purpose of this behaviour is that the data could be * read item-by-item without having to check for the stream's * health all the time. Such checks are needed only, if some decision * is made, based on the data. In case of an error, the read functions * return some well-define default value, typically 0. * * The writing functions return a boolean value indicating success or * failure, but writing can be handled the same way as reading from * the point of view of error checking. */ class DataStream : public BlockingStream { public: /** * Construct the stream. */ DataStream(BufferedStream& stream); /** * Template for simple, type-specific reading. */ template T readT(T defaultValue = 0); /** * Read a signed, 8-bit value */ int8_t readS8(); /** * Read an unsigned, 8-bit value */ uint8_t readU8(); /** * Read a signed, 16-bit value */ int16_t readS16(); /** * Read an unsigned, 16-bit value */ uint16_t readU16(); /** * Read a signed, 32-bit value */ int32_t readS32(); /** * Read an unsigned, 32-bit value */ uint32_t readU32(); /** * Read a signed, 64-bit value */ int64_t readS64(); /** * Read an unsigned, 64-bit value */ uint64_t readU64(); /** * Read a float value. */ float readFloat(); /** * Read a double value. */ double readDouble(); /** * Read a long double value. */ long double readLongDouble(); /** * Read a length value. This is a of at most 32 bits, represented * by a variable number of bytes for space efficiency. * * @see writeLength() */ size_t readLength(); /** * Read a string. */ std::string readString(); /** * Read a string into the given buffer. If the string is too large * for the buffer, its end will be discarded. A trailing 0 is * added in cases! * * @return the actual length of the string. */ size_t readString(char* dest, size_t capacity); /** * Write a signed, 8-bit value */ bool writeS8(int8_t x); /** * Write an unsigned, 8-bit value */ bool writeU8(uint8_t x); /** * Write a signed, 16-bit value */ bool writeS16(int16_t x); /** * Write an unsigned, 16-bit value */ bool writeU16(uint16_t x); /** * Write a signed, 32-bit value */ bool writeS32(int32_t x); /** * Write an unsigned, 32-bit value */ bool writeU32(uint32_t x); /** * Write a signed, 64-bit value */ bool writeS64(int64_t x); /** * Write an unsigned, 64-bit value */ bool writeU64(uint64_t x); /** * Write a float value. */ bool writeFloat(float x); /** * Write a double value. */ bool writeDouble(double x); /** * Write a long double value. */ bool writeLongDouble(long double x); /** * Write a length value. This a 32-bit value written as a sequence * of bytes of variable length. A bytes's lower 7 bits contain * parts of the value. The MSB indicates if another byte is left. */ bool writeLength(size_t length); /** * Write a string. First the string's length is written as a * length (see writeLength()), then the characters of the string * without the trailing 0. */ bool writeString(const char* s, size_t length); /** * Write a string. First the string's length is written as a * length (see writeLength()), then the characters of the string * without the trailing 0. */ bool writeString(const std::string& s); /** * Write a string. First the string's length is written as a * length (see writeLength()), then the characters of the string * without the trailing 0. */ bool writeString(const char* s); }; //------------------------------------------------------------------------------ // Inline definitions //------------------------------------------------------------------------------ inline DataStream::DataStream(BufferedStream& stream) : BlockingStream(stream) { } //------------------------------------------------------------------------------ template T DataStream::readT(T defaultValue) { T value = defaultValue; read(&value, sizeof(value)); return value; } //------------------------------------------------------------------------------ inline int8_t DataStream::readS8() { return readT(0); } //------------------------------------------------------------------------------ inline uint8_t DataStream::readU8() { return readT(0); } //------------------------------------------------------------------------------ inline int16_t DataStream::readS16() { return readT(0); } //------------------------------------------------------------------------------ inline uint16_t DataStream::readU16() { return readT(0); } //------------------------------------------------------------------------------ inline int32_t DataStream::readS32() { return readT(0); } //------------------------------------------------------------------------------ inline uint32_t DataStream::readU32() { return readT(0); } //------------------------------------------------------------------------------ inline int64_t DataStream::readS64() { return readT(0); } //------------------------------------------------------------------------------ inline uint64_t DataStream::readU64() { return readT(0); } //------------------------------------------------------------------------------ inline float DataStream::readFloat() { return readT(0.0); } //------------------------------------------------------------------------------ inline double DataStream::readDouble() { return readT(0.0); } //------------------------------------------------------------------------------ inline long double DataStream::readLongDouble() { return readT(0.0); } //------------------------------------------------------------------------------ inline bool DataStream::writeS8(int8_t x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeU8(uint8_t x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeS16(int16_t x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeU16(uint16_t x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeS32(int32_t x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeU32(uint32_t x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeS64(int64_t x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeU64(uint64_t x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeFloat(float x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeDouble(double x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeLongDouble(long double x) { return write(&x, sizeof(x)); } //------------------------------------------------------------------------------ inline bool DataStream::writeString(const char* s, size_t length) { if (!writeLength(length)) return false; else return write(s, length); } //------------------------------------------------------------------------------ inline bool DataStream::writeString(const std::string& s) { return writeString(s.c_str(), s.length()); } //------------------------------------------------------------------------------ inline bool DataStream::writeString(const char* s) { return writeString(s, strlen(s)); } //------------------------------------------------------------------------------ } /* namespace hu::varadiistvan::scpl::io */ } /* namespace hu::varadiistvan::scpl */ } /* namespace hu::varadiistvan */ } /* namespace hu */ //------------------------------------------------------------------------------ #endif // HU_VARADIISTVAN_SCPL_IO_DATASTREAM_H // Local Variables: // mode: C++ // c-basic-offset: 4 // indent-tabs-mode: nil // End: