]> gitweb.hamatoma.de Git - crepublib/commitdiff
ReSerializable
authorhama <hama@siduction.net>
Fri, 27 Mar 2015 00:10:33 +0000 (01:10 +0100)
committerhama <hama@siduction.net>
Fri, 27 Mar 2015 00:10:33 +0000 (01:10 +0100)
base/ReByteBuffer.hpp
base/ReSerializable.cpp [new file with mode: 0644]
base/ReSerializable.hpp [new file with mode: 0644]
base/rebase.hpp

index 461ec694b4417b5f1dec639186f38e908cd3f353..8f98f157f295654f4e82858f2d1b859fc65e4ea8 100644 (file)
@@ -46,6 +46,64 @@ public:
        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)
@@ -55,6 +113,52 @@ public:
                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
diff --git a/base/ReSerializable.cpp b/base/ReSerializable.cpp
new file mode 100644 (file)
index 0000000..d08c6d8
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * ReSerializable.cpp
+ *
+ * License: Public domain
+ * Do what you want.
+ * No warranties and disclaimer of any damages.
+ * The latest sources: https://github.com/republib
+ */
+
+#include "base/rebase.hpp"
+
+/**
+ * Constructor.
+ *
+ * @param length       the
+ */
+ReSerializationLengthException::ReSerializationLengthException(int currentLength,
+               int expectedlength) :
+       ReSerializationException(),
+       m_currentLength(currentLength),
+       m_expectedLength(expectedlength){
+}
diff --git a/base/ReSerializable.hpp b/base/ReSerializable.hpp
new file mode 100644 (file)
index 0000000..dc013bd
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * 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_ */
index a358798ddc1caaa8347566e0fa544643f0e11260..f035848562312831891326c23876894831eb2015 100644 (file)
@@ -120,6 +120,7 @@ inline int max(int a, int b){
 }\r
 #include "base/ReMutex.hpp"\r
 #include "base/ReByteBuffer.hpp"\r
+#include "base/ReSerializable.hpp"\r
 #include "base/ReVarArgs.hpp"\r
 #include "base/ReLogger.hpp"\r
 #include "base/ReThread.hpp"\r