Merge pull request #9 from dcbullock/master
[asdcplib.git] / src / KM_util.cpp
index d6b71418ecc2648d76a8fd3d3c95a8dbcc9a9dfa..d263d6e47bcfd416b30ddf71a164a594a78890cf 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
@@ -129,10 +129,10 @@ Kumu::Result_t::Get(unsigned int i)
 }
 
 //
-Kumu::Result_t::Result_t(int v, const char* s, const char* l) : value(v), symbol(s), label(l)
+Kumu::Result_t::Result_t(int v, const std::string& s, const std::string& l) : value(v), symbol(s), label(l)
 {
-  assert(l);
-  assert(s);
+  assert(!l.empty());
+  assert(!s.empty());
 
   if ( v == 0 )
     return;
@@ -162,8 +162,65 @@ Kumu::Result_t::Result_t(int v, const char* s, const char* l) : value(v), symbol
   return;
 }
 
+
+Kumu::Result_t::Result_t(const Result_t& rhs)
+{
+  value = rhs.value;
+  symbol = rhs.symbol;
+  label = rhs.label;
+  message = rhs.message;
+}
+
 Kumu::Result_t::~Result_t() {}
 
+//
+const Kumu::Result_t&
+Kumu::Result_t::operator=(const Result_t& rhs)
+{
+  value = rhs.value;
+  symbol = rhs.symbol;
+  label = rhs.label;
+  message = rhs.message;
+  return *this;
+}
+
+//
+const Kumu::Result_t
+Kumu::Result_t::operator()(const std::string& message) const
+{
+  Result_t result = *this;
+  result.message = message;
+  return result;
+}
+
+static int const MESSAGE_BUF_MAX = 2048;
+
+//
+const Kumu::Result_t
+Kumu::Result_t::operator()(const int& line, const char* filename) const
+{
+  assert(filename);
+  char buf[MESSAGE_BUF_MAX];
+  snprintf(buf, MESSAGE_BUF_MAX-1, "%s, line %d", filename, line);
+
+  Result_t result = *this;
+  result.message = buf;
+  return result;
+}
+
+//
+const Kumu::Result_t
+Kumu::Result_t::operator()(const std::string& message, const int& line, const char* filename) const
+{
+  assert(filename);
+  char buf[MESSAGE_BUF_MAX];
+  snprintf(buf, MESSAGE_BUF_MAX-1, "%s, line %d", filename, line);
+
+  Result_t result = *this;
+  result.message = message + buf;
+  return result;
+}
+
 
 //------------------------------------------------------------------------------------------
 // DTrace internals
@@ -796,8 +853,8 @@ Kumu::Timestamp::EncodeString(char* str_buf, ui32_t buf_len) const
       tmp_t.AddMinutes(m_TZOffsetMinutes);
       tmp_t.GetComponents(year, month, day, hour, minute, second);
 
-      ofst_hours = abs(m_TZOffsetMinutes) / 60;
-      ofst_minutes = abs(m_TZOffsetMinutes) % 60;
+      ofst_hours = Kumu::xabs(m_TZOffsetMinutes) / 60;
+      ofst_minutes = Kumu::xabs(m_TZOffsetMinutes) % 60;
 
       if ( m_TZOffsetMinutes < 0 )
        direction = '-';
@@ -805,14 +862,14 @@ Kumu::Timestamp::EncodeString(char* str_buf, ui32_t buf_len) const
   
   // 2004-05-01T13:20:00+00:00
   snprintf(str_buf, buf_len,
-          "%04hu-%02hu-%02huT%02hu:%02hu:%02hu%c%02hu:%02hu",
+          "%04hu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhu%c%02u:%02u",
           year, month, day, hour, minute, second,
           direction, ofst_hours, ofst_minutes);
 
   return str_buf;
 }
 
-//
+// ^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?(?:([+-]\d{2}):(\d{2}))?)?$
 bool
 Kumu::Timestamp::DecodeString(const char* datestr)
 {
@@ -825,10 +882,13 @@ Kumu::Timestamp::DecodeString(const char* datestr)
 
   ui32_t char_count = 10;
   TAI::caltime YMDhms;
+  YMDhms.hour = 0;
+  YMDhms.minute = 0;
+  YMDhms.second = 0;
   YMDhms.offset = 0;
-  YMDhms.date.year = atoi(datestr);
-  YMDhms.date.month = atoi(datestr + 5);
-  YMDhms.date.day = atoi(datestr + 8);
+  YMDhms.date.year = strtol(datestr, 0, 10);
+  YMDhms.date.month = strtol(datestr + 5, 0, 10);
+  YMDhms.date.day = strtol(datestr + 8, 0, 10);
  
   if ( datestr[10] == 'T' )
     {
@@ -838,8 +898,8 @@ Kumu::Timestamp::DecodeString(const char* datestr)
        return false;
 
       char_count += 6;
-      YMDhms.hour = atoi(datestr + 11);
-      YMDhms.minute = atoi(datestr + 14);
+      YMDhms.hour = strtol(datestr + 11, 0, 10);
+      YMDhms.minute = strtol(datestr + 14, 0, 10);
 
       if ( datestr[16] == ':' )
        {
@@ -847,16 +907,23 @@ Kumu::Timestamp::DecodeString(const char* datestr)
            return false;
 
          char_count += 3;
-         YMDhms.second = atoi(datestr + 17);
+         YMDhms.second = strtol(datestr + 17, 0, 10);
        }
 
       if ( datestr[19] == '.' )
        {
-         if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) && isdigit(datestr[22]) ) )
-           return false;
-         
+         if ( ! isdigit(datestr[20]) )
+           {
+             return false;
+           }
+
          // we don't carry the ms value
-         datestr += 4;
+         while ( isdigit(datestr[20]) )
+           {
+             ++datestr;
+           }
+
+         ++datestr;
        }
 
       if ( datestr[19] == '-' || datestr[19] == '+' )
@@ -868,8 +935,8 @@ Kumu::Timestamp::DecodeString(const char* datestr)
 
          char_count += 6;
 
-         ui32_t TZ_hh = atoi(datestr + 20);
-         ui32_t TZ_mm = atoi(datestr + 23);
+         ui32_t TZ_hh = strtol(datestr + 20, 0, 10);
+         ui32_t TZ_mm = strtol(datestr + 23, 0, 10);
          if ((TZ_hh > 14) || (TZ_mm > 59) || ((TZ_hh == 14) && (TZ_mm > 0)))
            return false;
 
@@ -913,7 +980,7 @@ bool
 Kumu::Timestamp::Unarchive(MemIOReader* Reader)
 {
   ui16_t year;
-  ui8_t month, day, hour, minute, second;
+  ui8_t month, day, hour, minute, second, tick;
 
   assert(Reader);
   if ( ! Reader->ReadUi16BE(&year) ) return false;
@@ -922,6 +989,7 @@ Kumu::Timestamp::Unarchive(MemIOReader* Reader)
   if ( ! Reader->ReadUi8(&hour) ) return false;
   if ( ! Reader->ReadUi8(&minute) ) return false;
   if ( ! Reader->ReadUi8(&second) ) return false;
+  if ( ! Reader->ReadUi8(&tick) ) return false;
   SetComponents(year, month, day, hour, minute, second);
   return true;
 }
@@ -933,7 +1001,7 @@ Kumu::Timestamp::Archive(MemIOWriter* Writer) const
   assert(Writer);
 
   ui16_t year;
-  ui8_t month, day, hour, minute, second;
+  ui8_t month, day, hour, minute, second, tick = 0;
   GetComponents(year, month, day, hour, minute, second);
 
   if ( ! Writer->WriteUi16BE(year) ) return false;     
@@ -942,6 +1010,7 @@ Kumu::Timestamp::Archive(MemIOWriter* Writer) const
   if ( ! Writer->WriteUi8(hour) ) return false;
   if ( ! Writer->WriteUi8(minute) ) return false;
   if ( ! Writer->WriteUi8(second) ) return false;
+  if ( ! Writer->WriteUi8(tick) ) return false;
   return true;
 }
 
@@ -952,6 +1021,15 @@ Kumu::Timestamp::GetCTime() const
   return m_Timestamp.x - ui64_C(4611686018427387914);
 }
 
+//
+void
+Kumu::Timestamp::SetCTime(const ui64_t& ctime)
+{
+  m_Timestamp.x = ctime + ui64_C(4611686018427387914);
+}
+
+
+
 
 //------------------------------------------------------------------------------------------
 
@@ -1115,6 +1193,58 @@ Kumu::ByteString::Append(const byte_t* buf, ui32_t buf_len)
   return result;
 }
 
+//------------------------------------------------------------------------------------------
+
+//
+const char*
+Kumu::km_strnstr(const char *s, const char *find, size_t slen)
+{
+  char c, sc;
+  size_t len;
+
+  if ( ( c = *find++ ) != '\0' )
+    {
+      len = strlen(find);
+      do
+       {
+         do
+           {
+             if ( slen-- < 1 || ( sc = *s++ ) == '\0' )
+               return 0;
+           }
+         while ( sc != c );
+
+         if ( len > slen )
+           return 0;
+       }
+      while ( strncmp(s, find, len) != 0 );
+      --s;
+    }
+
+  return s;
+}
+
+//
+std::list<std::string>
+Kumu::km_token_split(const std::string& str, const std::string& separator)
+{
+  std::list<std::string> components;
+  const char* pstr = str.c_str();
+  const char* r = strstr(pstr, separator.c_str());
+
+  while ( r != 0 )
+    {
+      assert(r >= pstr);
+      std::string tmp_str;
+      tmp_str.assign(pstr, r - pstr);
+      components.push_back(tmp_str);
+      pstr = r + separator.size();
+      r = strstr(pstr, separator.c_str());
+    }
+      
+  components.push_back(std::string(pstr));
+  return components;
+}
 
 //
 // end KM_util.cpp