struct map_entry_t
{
- long rcode;
+ int rcode;
Kumu::Result_t* result;
};
-const ui32_t MapMax = 512;
+const ui32_t MapMax = 1024;
const ui32_t MapSize = MapMax * (sizeof(struct map_entry_t));
static bool s_MapInit = false;
static struct map_entry_t s_ResultMap[MapSize];
//
const Kumu::Result_t&
-Kumu::Result_t::Find(long v)
+Kumu::Result_t::Find(int v)
{
if ( v == 0 )
return RESULT_OK;
}
//
-Kumu::Result_t::Result_t(long v, const char* l) : value(v), label(l)
+Kumu::Result_t
+Kumu::Result_t::Delete(int v)
+{
+ if ( v >= RESULT_NOTAFILE.Value() )
+ {
+ DefaultLogSink().Error("Cannot delete core result code: %ld\n", v);
+ return RESULT_FAIL;
+ }
+
+ for ( ui32_t i = 0; s_ResultMap[i].result != 0 && i < MapMax; i++ )
+ {
+ if ( s_ResultMap[i].rcode == v )
+ {
+ s_ResultMap[i].rcode = 0;
+ s_ResultMap[i++].result = 0;
+
+ for ( ; s_ResultMap[i].result != 0 && i < MapMax; i++ )
+ s_ResultMap[i-1] = s_ResultMap[i];
+
+ return RESULT_OK;
+ }
+ }
+
+ return RESULT_FALSE;
+}
+
+
+//
+Kumu::Result_t::Result_t(int v, const char* l) : value(v), label(l)
{
assert(l);
+ assert(value < (int)MapMax);
if ( v == 0 )
return;
Kumu::Result_t::~Result_t() {}
+//------------------------------------------------------------------------------------------
+// DTrace internals
+
+static int s_DTraceSequence = 0;
+
+Kumu::DTrace_t::DTrace_t(const char* Label, Kumu::Result_t* Watch, int Line, const char* File)
+ : m_Label(Label), m_Watch(Watch), m_Line(Line), m_File(File)
+{
+ m_Sequence = s_DTraceSequence++;
+ DefaultLogSink().Debug("@enter %s[%d] (%s at %d)\n", m_Label, m_Sequence, m_File, m_Line);
+}
+
+Kumu::DTrace_t::~DTrace_t()
+{
+ if ( m_Watch != 0 )
+ DefaultLogSink().Debug("@exit %s[%d]: %s\n", m_Label, m_Sequence, m_Watch->Label());
+ else
+ DefaultLogSink().Debug("@exit %s[%d]\n", m_Label, m_Sequence);
+}
+
//------------------------------------------------------------------------------------------
i32_t
Kumu::hex2bin(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* conv_size)
{
- KM_TEST_NULL(str);
- KM_TEST_NULL(buf);
- KM_TEST_NULL(conv_size);
+ KM_TEST_NULL_L(str);
+ KM_TEST_NULL_L(buf);
+ KM_TEST_NULL_L(conv_size);
*conv_size = 0;
//
void
-Kumu::GenRandomValue(SymmetricKey& ID)
+Kumu::GenRandomValue(SymmetricKey& Key)
{
byte_t tmp_buf[SymmetricKey_Length];
FortunaRNG RNG;
RNG.FillRandom(tmp_buf, SymmetricKey_Length);
- ID.Set(tmp_buf);
+ Key.Set(tmp_buf);
}
return ( CompareFileTime(&lft, &rft) == -1 );
}
+//
+bool
+Kumu::Timestamp::operator>(const Timestamp& rhs) const
+{
+ SYSTEMTIME lhst, rhst;
+ FILETIME lft, rft;
+
+ TIMESTAMP_TO_SYSTIME(*this, &lhst);
+ TIMESTAMP_TO_SYSTIME(rhs, &rhst);
+ SystemTimeToFileTime(&lhst, &lft);
+ SystemTimeToFileTime(&rhst, &rft);
+ return ( CompareFileTime(&lft, &rft) == 1 );
+}
+
inline ui64_t
seconds_to_ns100(ui32_t seconds)
{
return ( timegm(&lhtm) < timegm(&rhtm) );
}
+//
+bool
+Kumu::Timestamp::operator>(const Timestamp& rhs) const
+{
+ struct tm lhtm, rhtm;
+ TIMESTAMP_TO_TM(*this, &lhtm);
+ TIMESTAMP_TO_TM(rhs, &rhtm);
+ return ( timegm(&lhtm) > timegm(&rhtm) );
+}
+
//
void
Kumu::Timestamp::AddDays(i32_t days)
bool
Kumu::Timestamp::DecodeString(const char* datestr)
{
+ Timestamp TmpStamp;
+
if ( ! ( isdigit(datestr[0]) && isdigit(datestr[1]) && isdigit(datestr[2]) && isdigit(datestr[3]) )
|| datestr[4] != '-'
|| ! ( isdigit(datestr[5]) && isdigit(datestr[6]) )
|| datestr[7] != '-'
- || ! ( isdigit(datestr[8]) && isdigit(datestr[9]) )
- || datestr[10] != 'T'
- || ! ( isdigit(datestr[11]) && isdigit(datestr[12]) )
- || datestr[13] != ':'
- || ! ( isdigit(datestr[14]) && isdigit(datestr[15]) )
- || datestr[16] != ':'
- || ! ( isdigit(datestr[17]) && isdigit(datestr[18]) )
- || ! ( datestr[19] == '-' || datestr[19] == '+' )
- || ! ( isdigit(datestr[20]) && isdigit(datestr[21]) )
- || datestr[22] != ':'
- || ! ( isdigit(datestr[23]) && isdigit(datestr[24]) ) )
+ || ! ( isdigit(datestr[8]) && isdigit(datestr[9]) ) )
return false;
- // TODO -- test this!
- Year = atoi(datestr);
- Month = atoi(datestr + 5);
- Day = atoi(datestr + 8);
- Hour = atoi(datestr + 11);
- Minute = atoi(datestr + 14);
- Second = atoi(datestr + 17);
+ ui32_t char_count = 10;
+ TmpStamp.Year = atoi(datestr);
+ TmpStamp.Month = atoi(datestr + 5);
+ TmpStamp.Day = atoi(datestr + 8);
+ TmpStamp.Hour = TmpStamp.Minute = TmpStamp.Second = 0;
+
+ if ( datestr[10] == 'T' )
+ {
+ if ( ! ( isdigit(datestr[11]) && isdigit(datestr[12]) )
+ || datestr[13] != ':'
+ || ! ( isdigit(datestr[14]) && isdigit(datestr[15]) ) )
+ return false;
+
+ char_count += 6;
+ TmpStamp.Hour = atoi(datestr + 11);
+ TmpStamp.Minute = atoi(datestr + 14);
- ui32_t TZ_hh = atoi(datestr + 20);
- ui32_t TZ_mm = atoi(datestr + 23);
+ if ( datestr[16] == ':' )
+ {
+ if ( ! ( isdigit(datestr[17]) && isdigit(datestr[18]) ) )
+ return false;
- if ( TZ_mm != 0 )
- DefaultLogSink().Error("Ignoring sub-hours timezone offset: %u\n", TZ_mm);
-
- if ( TZ_hh > 12 )
- DefaultLogSink().Error("Ignoring large timezone offset: %s\n", (datestr+19));
- else
- AddHours(TZ_hh);
+ char_count += 3;
+ TmpStamp.Second = atoi(datestr + 17);
+ }
+
+ if ( datestr[19] == '.' )
+ {
+ if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) && isdigit(datestr[22]) ) )
+ return false;
+
+ // we don't carry the ms value
+ datestr += 4;
+ }
+
+ if ( datestr[19] == '-' || datestr[19] == '+' )
+ {
+ if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) )
+ || datestr[22] != ':'
+ || ! ( isdigit(datestr[23]) && isdigit(datestr[24]) ) )
+ return false;
+
+ char_count += 6;
+ ui32_t TZ_hh = atoi(datestr + 20);
+ ui32_t TZ_mm = atoi(datestr + 23);
+
+ if ( TZ_mm != 0 )
+ DefaultLogSink().Warn("Ignoring minutes in timezone offset: %u\n", TZ_mm);
+
+ if ( TZ_hh > 12 )
+ return false;
+
+ else
+ AddHours( (datestr[19] == '-' ? (0 - TZ_hh) : TZ_hh));
+ }
+ }
+
+ if ( datestr[char_count] != 0 )
+ {
+ DefaultLogSink().Error("Unexpected extra characters in string: %s (%ld)\n",
+ datestr, char_count);
+ return false;
+ }
+
+#ifdef KM_WIN32
+ SYSTEMTIME st;
+ FILETIME ft;
+ TIMESTAMP_TO_SYSTIME(TmpStamp, &st);
+ if ( SystemTimeToFileTime(&st, &ft) == 0 )
+ return false;
+ SYSTIME_TO_TIMESTAMP(&st, *this);
+#else
+ struct tm stm;
+ TIMESTAMP_TO_TM(TmpStamp, &stm);
+ if ( timegm(&stm) == 0 )
+ return false;
+ TM_TO_TIMESTAMP(&stm, *this);
+#endif
return true;
}
return true;
}
-#if 0
-//
-bool
-Kumu::UnarchiveString(MemIOReader* Reader, std::string&)
-{
- assert(Reader);
- ui32_t str_length;
- if ( ! Reader->ReadUi32BE(&str_length) ) return false;
- assign((const char*)Reader->CurrentData(), str_length);
- if ( ! Reader->SkipOffset(str_length) ) return false;
- return true;
-}
-
-//
-bool
-Kumu::String::Archive(MemIOWriter* Writer) const
-{
- assert(Writer);
- if ( ! Writer->WriteUi32BE(length()) ) return false;
- if ( ! Writer->WriteRaw((const byte_t*)c_str(), length()) ) return false;
-
- return true;
-}
-#endif
-
//------------------------------------------------------------------------------------------
Kumu::MemIOWriter::MemIOWriter(ByteString* Buf)
: m_p(0), m_capacity(0), m_size(0)
{
m_p = Buf->RoData();
- m_capacity = Buf->Capacity();
+ m_capacity = Buf->Length();
assert(m_p); assert(m_capacity);
}
}
+// copy the given data into the ByteString, set Length value.
+// Returns error if the ByteString is too small.
+Kumu::Result_t
+Kumu::ByteString::Set(const ByteString& Buf)
+{
+ if ( m_Capacity < Buf.m_Capacity )
+ return RESULT_ALLOC;
+
+ memcpy(m_Data, Buf.m_Data, Buf.m_Length);
+ m_Length = Buf.m_Length;
+ return RESULT_OK;
+}
+
+
// Sets the size of the internally allocate buffer.
-// Resets content length to zero.
Kumu::Result_t
Kumu::ByteString::Capacity(ui32_t cap_size)
{
- if ( m_Capacity < cap_size )
+ if ( m_Capacity >= cap_size )
+ return RESULT_OK;
+
+ byte_t* tmp_data = 0;
+ if ( m_Data != 0 )
{
- if ( m_Data != 0 )
+ if ( m_Length > 0 )
+ tmp_data = m_Data;
+ else
free(m_Data);
+ }
- m_Data = (byte_t*)malloc(cap_size);
-
- if ( m_Data == 0 )
- return RESULT_ALLOC;
-
- m_Capacity = cap_size;
- m_Length = 0;
+ if ( ( m_Data = (byte_t*)malloc(cap_size) ) == 0 )
+ return RESULT_ALLOC;
+
+ if ( tmp_data != 0 )
+ {
+ assert(m_Length > 0);
+ memcpy(m_Data, tmp_data, m_Length);
+ free(tmp_data);
}
-
+
+ m_Capacity = cap_size;
return RESULT_OK;
}