ReByteBuffer& append(const Byte* source, size_t length = -1);
ReByteBuffer& append(const ReByteBuffer& source);
ReByteBuffer& append(double, const char* format = "%f");
+ /** Appends a 8 bit value in an architecture independent way.
+ * @param value character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendBits8(int value){
+ setLength(m_length + 1);
+ m_buffer[m_length - 1] = (char) value;
+ return *this;
+ }
+ /** Appends a 16 bit value in an architecture independent way.
+ * @param value character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendBits16(int value){
+ setLength(m_length + 2);
+ m_buffer[m_length - 2] = char(value >> 8);
+ m_buffer[m_length - 1] = char(value);
+ return *this;
+ }
+ /** Appends a 24 bit value in an architecture independent way.
+ * @param value character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendBits24(int value){
+ setLength(m_length + 3);
+ m_buffer[m_length - 3] = char(value >> 16);
+ m_buffer[m_length - 2] = char(value >> 8);
+ m_buffer[m_length - 1] = char(value);
+ return *this;
+ }
+ /** Appends a 24 bit value in an architecture independent way.
+ * @param value character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendBits32(int value){
+ setLength(m_length + 4);
+ m_buffer[m_length - 4] = char(value >> 24);
+ m_buffer[m_length - 3] = char(value >> 16);
+ m_buffer[m_length - 2] = char(value >> 8);
+ m_buffer[m_length - 1] = char(value);
+ return *this;
+ }
+ /** Appends a 24 bit value in an architecture independent way.
+ * @param value character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendBits64(int64_t value){
+ setLength(m_length + 8);
+ m_buffer[m_length - 8] = char(value >> 56);
+ m_buffer[m_length - 7] = char(value >> 48);
+ m_buffer[m_length - 6] = char(value >> 40);
+ m_buffer[m_length - 5] = char(value >> 32);
+ m_buffer[m_length - 4] = char(value >> 24);
+ m_buffer[m_length - 3] = char(value >> 16);
+ m_buffer[m_length - 2] = char(value >> 8);
+ m_buffer[m_length - 1] = char(value);
+ return *this;
+ }
/** Appends a character.
* @param aChar character to append
* @return <code>*this</code> (for chaining)
m_buffer[m_length - 1] = aChar;
return *this;
}
+ /** Appends 2 characters.
+ * @param char1 first character to append
+ * @param char2 2nd character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendChar2(char char1, char char2) {
+ setLength(m_length + 2);
+ m_buffer[m_length - 2] = char1;
+ m_buffer[m_length - 1] = char2;
+ return *this;
+ }
+ /** Appends 4 characters.
+ * @param char1 first character to append
+ * @param char2 2nd character to append
+ * @param char3 3rd character to append
+ * @param char4 4th character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendChar(char char1, char char2, char char3, char char4) {
+ setLength(m_length + 4);
+ m_buffer[m_length - 4] = char1;
+ m_buffer[m_length - 3] = char2;
+ m_buffer[m_length - 2] = char3;
+ m_buffer[m_length - 1] = char4;
+ return *this;
+ }
+ /** Appends 4 characters.
+ * @param char1 first character to append
+ * @param char2 2nd character to append
+ * @param char3 3rd character to append
+ * @param char4 4th character to append
+ * @return <code>*this</code> (for chaining)
+ */
+ inline ReByteBuffer& appendChar(char char1, char char2, char char3,
+ char char4, char char5, char char6, char char7, char char8) {
+ setLength(m_length + 8);
+ m_buffer[m_length - 8] = char1;
+ m_buffer[m_length - 7] = char2;
+ m_buffer[m_length - 6] = char3;
+ m_buffer[m_length - 5] = char4;
+ m_buffer[m_length - 4] = char5;
+ m_buffer[m_length - 3] = char6;
+ m_buffer[m_length - 2] = char7;
+ m_buffer[m_length - 1] = char8;
+ return *this;
+ }
/** Appends a character at least one time.
* @param aChar character to append
* @param count number of times to append
--- /dev/null
+/*
+ * ReSerializable.hpp
+ *
+ * License: Public domain
+ * Do what you want.
+ * No warranties and disclaimer of any damages.
+ * The latest sources: https://github.com/republib
+ */
+
+#ifndef BASE_RESERIALIZABLE_HPP_
+#define BASE_RESERIALIZABLE_HPP_
+
+/**
+ * Base class for all serialization/deserialization errors.
+ */
+class ReSerializationException: public ReException {
+};
+/**
+ * The length is not enough for the deserialization.
+ */
+class ReSerializationLengthException : public ReSerializationException {
+public:
+ ReSerializationLengthException(int currentLength, int expectedLength);
+public:
+ int m_currentLength;
+ int m_expectedLength;
+};
+/**
+ * Unexpected data found while unpacking.
+ */
+class ReSerializeFormatException : public ReSerializationException {
+};
+/**
+ * Abstract base class for serializing.
+ *
+ * Serializing packs a class into a sequence of bytes.
+ * Deserializing converts a sequence of bytes into the members of the instance.
+ */
+class ReSerializable {
+public:
+ virtual ~ReSerializable() {
+ }
+public:
+ /** Appends a boolean value.
+ * @param buffer IN/OUT: the buffer with the serialized values
+ * @param value the value to serialize
+ */
+ inline void packBool(ReByteBuffer& buffer, bool value) {
+ buffer.appendChar(value ? 't' : 'f');
+ }
+ /** Appends a string with a maximal length of 255 to the buffer.
+ * @param buffer IN/OUT: the buffer with the serialized values
+ * @param value the value to serialize
+ */
+ inline void packString8(ReByteBuffer& buffer, ReByteBuffer& value) {
+ buffer.appendBits8(value.length()).append(value);
+ }
+ /** Appends a string with a maximal length of 64KiByte to the buffer.
+ * @param buffer IN/OUT: the buffer with the serialized values
+ * @param value the value to serialize
+ */
+ inline void appendString16(ReByteBuffer& buffer, ReByteBuffer& value) {
+ buffer.appendBits16(value.length()).append(value);
+ }
+ /** Appends a string with a maximal length of 4GiByte to the buffer.
+ * @param buffer IN/OUT: the buffer with the serialized values
+ * @param value the value to serialize
+ */
+ inline void appendString32(ReByteBuffer& buffer, ReByteBuffer& value) {
+ buffer.appendBits32(value.length()).append(value);
+ }
+ /** Sets the members of the instance from the byte sequence.
+ *
+ * @param sequence IN: a byte sequence starting with the serialized members
+ * of the instance<br>
+ * OUT: the byte sequence behind the serialized members
+ * @param length IN: the length of <code>sequence</code><br>
+ * OUT: the length of <code>sequence</code> without the
+ * serialized members
+ */
+ virtual void deserialize(uint8_t*& sequence, size_t& length) = 0;
+ /** Appends the class members to the end of the buffer.
+ *
+ * @param buffer IN/OUT: the buffer containing the serialized bytes
+ * @return the <code>buffer</code> (for chaining)
+ */
+ virtual ReByteBuffer& serialize(ReByteBuffer& buffer) = 0;
+ /** Reads a 8 bit integer from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackBool(uint8_t*& sequence, size_t& length, bool& value) {
+ if (length < 1)
+ throw ReSerializationLengthException(length, 1);
+ char cc = *sequence++;
+ if (cc != 't' && cc != 'f')
+ throw ReSerializeFormatException(i18n("not a boolean value"));
+ value = cc == 't';
+ length--;
+ }
+ /** Reads a 8 bit integer from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackInt8(uint8_t*& sequence, size_t& length, int& value) {
+ if (length < 1)
+ throw ReSerializationLengthException(length, 1);
+ value = *sequence++;
+ length--;
+ }
+ /** Reads a 16 bit integer from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackInt16(uint8_t*& sequence, size_t& length, int& value) {
+ if (length < 2)
+ throw ReSerializationLengthException(length, 2);
+ value = (*sequence++ << 8) + *sequence++;
+ length -= 2;
+ }
+ /** Reads a 24 bit integer from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackInt24(uint8_t*& sequence, size_t& length, int& value) {
+ if (length < 3)
+ throw ReSerializationLengthException(length, 3);
+ value = (*sequence++ << 16) + (*sequence++ << 8) + *sequence++;
+ length -= 3;
+ }
+ /** Reads a 32 bit integer from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackInt32(uint8_t*& sequence, size_t& length, int& value) {
+ if (length < 4)
+ throw ReSerializationLengthException(length, 4);
+ value = (*sequence++ << 24) + (*sequence++ << 16) + (*sequence++ << 8)
+ + *sequence++;
+ length -= 4;
+ }
+ /** Reads a 64 bit integer from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackInt64(uint8_t*& sequence, size_t& length, int64_t& value) {
+ if (length < 8)
+ throw ReSerializationLengthException(length, 8);
+ value = (int64_t(*sequence++) << 56) + (int64_t(*sequence++) << 48)
+ + (int64_t(*sequence++) << 40) + (int64_t(*sequence++) << 32)
+ + (int64_t(*sequence++) << 24) + (int64_t(*sequence++) << 16)
+ + (int64_t(*sequence++) << 8) + int64_t(*sequence++);
+ length -= 8;
+ }
+ /** Reads a string with a max. length of 255 from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackString255(uint8_t*& sequence, size_t& length, ReByteBuffer& value) {
+ size_t strLen = 0;
+ if (length == 0 || (strLen = *sequence) > length)
+ throw ReSerializationLengthException(length, 1 + strLen);
+ value.set(reinterpret_cast<char*>(sequence), strLen);
+ length -= strLen - 1;
+ }
+ /** Reads a string with a max. length of 64KiByte from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackString64k(uint8_t*& sequence, size_t& length, ReByteBuffer& value) {
+ size_t strLen = 0;
+ if (length == 0 || (strLen = (sequence[0] << 8) + sequence[1]) > length)
+ throw ReSerializationLengthException(length, 1 + strLen);
+ value.set(reinterpret_cast<char*>(sequence), strLen);
+ length -= strLen - 1;
+ }
+ /** Reads a string with a max. length of 64KiByte from the serialized byte sequence.
+ * @param sequence IN/OUT: the byte sequence with the serialized data
+ * @param length IN/OUT: the length of <code>sequence</code>
+ * @param value OUT: the value read from the sequence
+ */
+ inline void unpackString4t(uint8_t*& sequence, size_t& length, ReByteBuffer& value) {
+ size_t strLen = 0;
+ if (length == 0 || (strLen = (sequence[0] << 24) + (sequence[1] << 16)
+ + (sequence[2] << 8) + sequence[3]) > length)
+ throw ReSerializationLengthException(length, 1 + strLen);
+ value.set(reinterpret_cast<char*>(sequence), strLen);
+ length -= strLen - 1;
+ }
+};
+
+#endif /* BASE_RESERIALIZABLE_HPP_ */