created new type ArchivableUi16
[asdcplib.git] / src / KM_util.h
index f4de54eb95bd8878144ae260a007afabbcce44dc..b209d27841a890814e1841885a5e1abae6ed4f4d 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2005-2012, John Hurst
+Copyright (c) 2005-2015, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,6 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <KM_error.h>
 #include <KM_tai.h>
 #include <string.h>
-#include <string>
 #include <list>
 
 namespace Kumu
@@ -244,7 +243,7 @@ namespace Kumu
       virtual ~ArchivableString() {}
 
       bool   HasValue() const { return ! this->empty(); }
-      ui32_t ArchiveLength() const { sizeof(ui32_t) + static_cast<ui32_t>(this->size()); }
+      ui32_t ArchiveLength() const { return sizeof(ui32_t) + static_cast<ui32_t>(this->size()); }
 
       bool   Archive(MemIOWriter* Writer) const {
        if ( Writer == 0 ) return false;
@@ -257,6 +256,35 @@ namespace Kumu
       }
     };
 
+  //
+  class ArchivableUi16 : public Kumu::IArchive
+    {
+      ui16_t m_Value;
+
+    public:
+      ArchivableUi16() : m_Value(0) {}
+      ArchivableUi16(const ui16_t& value) : m_Value(value) {}
+      virtual ~ArchivableUi16() {}
+
+      bool   HasValue() const { return true; }
+      ui32_t ArchiveLength() const { return sizeof(ui16_t); }
+
+      bool   Archive(MemIOWriter* Writer) const {
+       if ( Writer == 0 ) return false;
+       return Writer->WriteUi16BE(m_Value);
+      }
+
+      bool   Unarchive(MemIOReader* Reader) {
+       if ( Reader == 0 ) return false;
+       return Reader->ReadUi16BE(&m_Value);
+      }
+
+      const char* EncodeString(char* str_buf, ui32_t buf_len) const {
+       snprintf(str_buf, buf_len, "%hu", m_Value);
+       return str_buf;
+      }
+    };
+
   //
   typedef Kumu::ArchivableList<ArchivableString> StringList;
 
@@ -510,7 +538,7 @@ namespace Kumu
 
       inline virtual bool HasValue() const { return m_Length > 0; }
 
-      inline virtual ui32_t ArchiveLength() const { return m_Length; }
+      inline virtual ui32_t ArchiveLength() const { return sizeof(ui32_t) + m_Length; }
 
       inline virtual bool Archive(MemIOWriter* Writer) const {
        assert(Writer);
@@ -531,9 +559,39 @@ namespace Kumu
     };
 
   inline void hexdump(const ByteString& buf, FILE* stream = 0) {
-    hexdump(buf.RoData(), buf.Length());
+    hexdump(buf.RoData(), buf.Length(), stream);
   }
 
+  // Locates the first occurrence of the null-terminated string s2 in the string s1, where not more
+  // than n characters are searched.  Characters that appear after a `\0' character are not searched.
+  // Reproduced here from BSD for portability.
+  const char *km_strnstr(const char *s1, const char *s2, size_t n);
+
+  // Split the input string into tokens using the given separator. If the separator is not found the
+  // entire string will be returned as a single-item list.  Empty items will be recorded for
+  // adjacent instances of the separator. E.g., "/foo//bar/" will return ["", "foo", "", "bar", ""].
+  std::list<std::string> km_token_split(const std::string& str, const std::string& separator);
+
+  // Join the tokens in the given list using delimiter. If prefix is defined then each token
+  // will be concatenated with the prefix before being added to the composite string.
+  template <class T>
+    std::string
+    km_join(const T& list, const std::string& delimiter, const std::string& prefix = "")
+    {
+      std::string result;
+
+      for ( typename T::const_iterator i = list.begin(); i != list.end(); ++i )
+       {
+         if ( i != list.begin() )
+           {
+             result += delimiter;
+           }
+      
+         result += prefix + *i;
+       }
+
+      return result;
+    }
 
 } // namespace Kumu