X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FKM_util.h;h=6714c368c6b48f8440a0c30b84bfa6537f85629a;hb=44bc524e3cf74f0903b7fbb51ca2f366f48d3495;hp=344cfd161d704fc2c4490a88e3d0b2fcea41ebf9;hpb=04591a0dae1919f7ec3d740173b55dfad742fba6;p=asdcplib.git diff --git a/src/KM_util.h b/src/KM_util.h index 344cfd1..6714c36 100755 --- a/src/KM_util.h +++ b/src/KM_util.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2006, John Hurst +Copyright (c) 2005-2008, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -36,22 +36,34 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include namespace Kumu { + // a class that represents the string form of a value template class IntPrinter : public std::string { - protected: + KM_NO_COPY_CONSTRUCT(IntPrinter); IntPrinter(); + + protected: + const char* m_format; char m_strbuf[SIZE]; public: - inline const char* c_str() { return m_strbuf; } - IntPrinter(const char* format, T value) { - snprintf(m_strbuf, SIZE, format, value); + assert(format); + m_format = format; + snprintf(m_strbuf, SIZE, m_format, value); + } + + inline operator const char*() { return m_strbuf; } + inline const char* c_str() { return m_strbuf; } + inline const char* set_value(T value) { + snprintf(m_strbuf, SIZE, m_format, value); + return m_strbuf; } }; @@ -106,7 +118,7 @@ namespace Kumu i32_t hex2bin(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* char_count); // Convert a binary string to NULL-terminated UTF-8 hexadecimal, returns the buffer - // if the binary buffer was large enough to hold the result. If the output buffer + // if the output buffer was large enough to hold the result. If the output buffer // is too small or any of the pointer arguments are NULL, the subroutine will // return 0. // @@ -152,23 +164,73 @@ namespace Kumu //---------------------------------------------------------------- // + // an abstract base class that objects implement to serialize state + // to and from a binary stream. class IArchive { public: virtual ~IArchive(){} - virtual bool HasValue() const = 0; - virtual bool Archive(MemIOWriter* Writer) const = 0; - virtual bool Unarchive(MemIOReader* Reader) = 0; + virtual bool HasValue() const = 0; + virtual ui32_t ArchiveLength() const = 0; + virtual bool Archive(MemIOWriter* Writer) const = 0; + virtual bool Unarchive(MemIOReader* Reader) = 0; }; + // + template + class ArchivableList : public std::list, public IArchive + { + public: + ArchivableList() {} + virtual ~ArchivableList() {} + + bool HasValue() const { return ! this->empty(); } + + ui32_t ArchiveLength() const + { + ui32_t arch_size = sizeof(ui32_t); + + typename ArchivableList::const_iterator i = this->begin(); + for ( ; i != this->end(); i++ ) + arch_size += i->ArchiveLength(); + + return arch_size; + } + + bool Unarchive(Kumu::MemIOReader* Reader) + { + if ( Reader == 0 ) return false; + ui32_t read_size = 0; + if ( ! Reader->ReadUi32BE(&read_size) ) return false; + for ( ui32_t i = 0; i < read_size; i++ ) + { + T TmpTP; + if ( ! TmpTP.Unarchive(Reader) ) return false; + this->push_back(TmpTP); + } + + return true; + } + + bool Archive(Kumu::MemIOWriter* Writer) const + { + if ( Writer == 0 ) return false; + if ( ! Writer->WriteUi32BE(this->size()) ) return false; + typename ArchivableList::const_iterator i = this->begin(); + for ( ; i != this->end(); i++ ) + if ( ! i->Archive(Writer) ) return false; + + return true; + } + }; // - // the base of all identifier classes + // the base of all identifier classes, Identifier is not usually used directly + // see UUID and SymmetricKey below for more detail. + // template class Identifier : public IArchive { - const Identifier& operator=(const Identifier& rhs); - protected: bool m_HasValue; byte_t m_Value[SIZE]; @@ -183,64 +245,67 @@ namespace Kumu virtual ~Identifier() {} + const Identifier& operator=(const Identifier& rhs) { + m_HasValue = rhs.m_HasValue; + memcpy(m_Value, rhs.m_Value, SIZE); + return *this; + } + inline void Set(const byte_t* value) { m_HasValue = true; memcpy(m_Value, value, SIZE); } + inline void Reset() { m_HasValue = false; memset(m_Value, 0, SIZE); } inline const byte_t* Value() const { return m_Value; } inline ui32_t Size() const { return SIZE; } - inline bool operator<(const Identifier& rhs) const - { - ui32_t test_size = xmin(rhs.Size(), SIZE); - for ( ui32_t i = 0; i < test_size; i++ ) - { - if ( m_Value[i] != rhs.m_Value[i] ) - return m_Value[i] < rhs.m_Value[i]; - } + inline bool operator<(const Identifier& rhs) const { + ui32_t test_size = xmin(rhs.Size(), SIZE); - return false; - } + for ( ui32_t i = 0; i < test_size; i++ ) + { + if ( m_Value[i] != rhs.m_Value[i] ) + return m_Value[i] < rhs.m_Value[i]; + } + + return false; + } - inline bool operator==(const Identifier& rhs) const - { - if ( rhs.Size() != SIZE ) return false; - return ( memcmp(m_Value, rhs.m_Value, SIZE) == 0 ); - } + inline bool operator==(const Identifier& rhs) const { + if ( rhs.Size() != SIZE ) return false; + return ( memcmp(m_Value, rhs.m_Value, SIZE) == 0 ); + } - inline bool operator!=(const Identifier& rhs) const - { - if ( rhs.Size() != SIZE ) return true; - return ( memcmp(m_Value, rhs.m_Value, SIZE) != 0 ); - } + inline bool operator!=(const Identifier& rhs) const { + if ( rhs.Size() != SIZE ) return true; + return ( memcmp(m_Value, rhs.m_Value, SIZE) != 0 ); + } - inline bool DecodeHex(const char* str) - { - ui32_t char_count; - m_HasValue = ( hex2bin(str, m_Value, SIZE, &char_count) == 0 ); - return m_HasValue; - } + inline bool DecodeHex(const char* str) { + ui32_t char_count; + m_HasValue = ( hex2bin(str, m_Value, SIZE, &char_count) == 0 ); + return m_HasValue; + } - inline const char* EncodeHex(char* buf, ui32_t buf_len) const - { - return bin2hex(m_Value, SIZE, buf, buf_len); - } + inline const char* EncodeHex(char* buf, ui32_t buf_len) const { + return bin2hex(m_Value, SIZE, buf, buf_len); + } inline const char* EncodeString(char* str_buf, ui32_t buf_len) const { return EncodeHex(str_buf, buf_len); } - inline bool DecodeBase64(const char* str) - { - ui32_t char_count; - m_HasValue = ( base64decode(str, m_Value, SIZE, &char_count) == 0 ); - return m_HasValue; - } + inline bool DecodeBase64(const char* str) { + ui32_t char_count; + m_HasValue = ( base64decode(str, m_Value, SIZE, &char_count) == 0 ); + return m_HasValue; + } - inline const char* EncodeBase64(char* buf, ui32_t buf_len) const - { - return base64encode(m_Value, SIZE, buf, buf_len); - } + inline const char* EncodeBase64(char* buf, ui32_t buf_len) const { + return base64encode(m_Value, SIZE, buf, buf_len); + } inline bool HasValue() const { return m_HasValue; } + inline ui32_t ArchiveLength() const { return SIZE; } + inline bool Unarchive(Kumu::MemIOReader* Reader) { m_HasValue = Reader->ReadRaw(m_Value, SIZE); return m_HasValue; @@ -251,7 +316,7 @@ namespace Kumu } }; - + // UUID // const ui32_t UUID_Length = 16; @@ -262,11 +327,9 @@ namespace Kumu UUID(const byte_t* value) : Identifier(value) {} UUID(const UUID& rhs) : Identifier(rhs) {} virtual ~UUID() {} - - const UUID& operator=(const UUID& rhs) { - if ( m_HasValue = rhs.m_HasValue ) - memcpy(m_Value, rhs.m_Value, UUID_Length); - return *this; + + inline const char* EncodeString(char* buf, ui32_t buf_len) const { + return bin2UUIDhex(m_Value, Size(), buf, buf_len); } inline const char* EncodeHex(char* buf, ui32_t buf_len) const { @@ -274,7 +337,7 @@ namespace Kumu } }; - void GenRandomUUID(byte_t* buf); + void GenRandomUUID(byte_t* buf); // buf must be UUID_Length or longer void GenRandomValue(UUID&); // a self-wiping key container @@ -292,12 +355,6 @@ namespace Kumu SymmetricKey(const byte_t* value) : Identifier(value) {} SymmetricKey(const UUID& rhs) : Identifier(rhs) {} virtual ~SymmetricKey() { memcpy(m_Value, NilKey, 16); m_HasValue = false; } - - const SymmetricKey& operator=(const SymmetricKey& rhs) { - if ( m_HasValue = rhs.m_HasValue ) - memcpy(m_Value, rhs.m_Value, SymmetricKey_Length); - return *this; - } }; void GenRandomValue(SymmetricKey&); @@ -324,6 +381,7 @@ namespace Kumu const Timestamp& operator=(const Timestamp& rhs); bool operator<(const Timestamp& rhs) const; + bool operator>(const Timestamp& rhs) const; bool operator==(const Timestamp& rhs) const; bool operator!=(const Timestamp& rhs) const; @@ -334,19 +392,24 @@ namespace Kumu // decode and set value from string formatted by EncodeString bool DecodeString(const char* datestr); - // add the given number of days or hours to the timestamp value. Values less than zero - // will cause the value to decrease + // Add the given number of days or hours to the timestamp value. + // Values less than zero will cause the timestamp to decrease void AddDays(i32_t); void AddHours(i32_t); - // Read and write the timestamp value as a byte string - virtual bool HasValue() const; - virtual bool Archive(MemIOWriter* Writer) const; - virtual bool Unarchive(MemIOReader* Reader); + // Read and write the timestamp value as a byte string having + // the following format: + // | 16 bits int, big-endian | 8 bits | 8 bits | 8 bits | 8 bits | 8 bits | + // | Year A.D | Month(1-12) | Day(1-31) | Hour(0-23) | Minute(0-59) | Second(0-59) | + // + virtual bool HasValue() const; + virtual ui32_t ArchiveLength() const { return 8L; } + virtual bool Archive(MemIOWriter* Writer) const; + virtual bool Unarchive(MemIOReader* Reader); }; // - class ByteString + class ByteString : public IArchive { KM_NO_COPY_CONSTRUCT(ByteString); @@ -360,8 +423,7 @@ namespace Kumu ByteString(ui32_t cap); virtual ~ByteString(); - // Sets the size of the internally allocated buffer. - // Resets content Size to zero. + // Sets or resets the size of the internally allocated buffer. Result_t Capacity(ui32_t cap); Result_t Append(const ByteString&); @@ -371,10 +433,10 @@ namespace Kumu inline ui32_t Capacity() const { return m_Capacity; } // returns a const pointer to the essence data - inline const byte_t* RoData() const { return m_Data; } + inline const byte_t* RoData() const { assert(m_Data); return m_Data; } // returns a non-const pointer to the essence data - inline byte_t* Data() { return m_Data; } + inline byte_t* Data() { assert(m_Data); return m_Data; } // set the length of the buffer's contents inline ui32_t Length(ui32_t l) { return m_Length = l; } @@ -385,6 +447,28 @@ namespace Kumu // copy the given data into the ByteString, set Length value. // Returns error if the ByteString is too small. Result_t Set(const byte_t* buf, ui32_t buf_len); + Result_t Set(const ByteString& Buf); + + inline virtual bool HasValue() const { return m_Length > 0; } + + inline virtual ui32_t ArchiveLength() const { return m_Length; } + + inline virtual bool Archive(MemIOWriter* Writer) const { + assert(Writer); + if ( ! Writer->WriteUi32BE(m_Length) ) return false; + if ( ! Writer->WriteRaw(m_Data, m_Length) ) return false; + return true; + } + + inline virtual bool Unarchive(MemIOReader* Reader) { + assert(Reader); + ui32_t tmp_len; + if ( ! Reader->ReadUi32BE(&tmp_len) ) return false; + if ( KM_FAILURE(Capacity(tmp_len)) ) return false; + if ( ! Reader->ReadRaw(m_Data, tmp_len) ) return false; + m_Length = tmp_len; + return true; + } }; } // namespace Kumu