X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2FKM_util.cpp;h=46dbfa6c07a26abdc7557a7bcdd7b608f0089595;hb=ec832f280ffa16392808ee4976deb5b190a6e205;hp=7dd6719ba28d0083c19d6d48fadfe6a2fc7ebb56;hpb=c589ee9d47d9f00aa4be32c5832a44ce466f014d;p=asdcplib.git diff --git a/src/KM_util.cpp b/src/KM_util.cpp index 7dd6719..46dbfa6 100755 --- a/src/KM_util.cpp +++ b/src/KM_util.cpp @@ -34,29 +34,37 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include #include +#include #include #include #include #include +const char* +Kumu::Version() +{ + return PACKAGE_VERSION; +} + + //------------------------------------------------------------------------------------------ // Result_t Internals 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; @@ -72,9 +80,38 @@ Kumu::Result_t::Find(long v) } // -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; @@ -110,6 +147,26 @@ Kumu::Result_t::Result_t(long v, const char* l) : value(v), label(l) 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); +} + //------------------------------------------------------------------------------------------ @@ -267,9 +324,9 @@ Kumu::base64decode(const char* str, byte_t* buf, ui32_t buf_len, ui32_t* char_co 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; @@ -600,6 +657,20 @@ Kumu::Timestamp::operator<(const Timestamp& rhs) const 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) { @@ -650,54 +721,80 @@ Kumu::Timestamp::AddHours(i32_t hours) #include -#define TIMESTAMP_TO_TM(ts, t) \ - (t)->tm_year = (ts).Year - 1900; /* year - 1900 */ \ - (t)->tm_mon = (ts).Month - 1; /* month of year (0 - 11) */ \ - (t)->tm_mday = (ts).Day; /* day of month (1 - 31) */ \ - (t)->tm_hour = (ts).Hour; /* hours (0 - 23) */ \ - (t)->tm_min = (ts).Minute; /* minutes (0 - 59) */ \ - (t)->tm_sec = (ts).Second; /* seconds (0 - 60) */ - -#define TM_TO_TIMESTAMP(t, ts) \ - (ts).Year = (t)->tm_year + 1900; /* year - 1900 */ \ - (ts).Month = (t)->tm_mon + 1; /* month of year (0 - 11) */ \ - (ts).Day = (t)->tm_mday; /* day of month (1 - 31) */ \ - (ts).Hour = (t)->tm_hour; /* hours (0 - 23) */ \ - (ts).Minute = (t)->tm_min; /* minutes (0 - 59) */ \ - (ts).Second = (t)->tm_sec; /* seconds (0 - 60) */ +#define TIMESTAMP_TO_CALTIME(ts, ct) \ + (ct)->date.year = (ts).Year; /* year */ \ + (ct)->date.month = (ts).Month; /* month of year (1 - 12) */ \ + (ct)->date.day = (ts).Day; /* day of month (1 - 31) */ \ + (ct)->hour = (ts).Hour; /* hours (0 - 23) */ \ + (ct)->minute = (ts).Minute; /* minutes (0 - 59) */ \ + (ct)->second = (ts).Second; /* seconds (0 - 60) */ \ + (ct)->offset = 0; + +#define CALTIME_TO_TIMESTAMP(ct, ts) \ + assert((ct)->offset == 0); \ + (ts).Year = (ct)->date.year; /* year */ \ + (ts).Month = (ct)->date.month; /* month of year (1 - 12) */ \ + (ts).Day = (ct)->date.day; /* day of month (1 - 31) */ \ + (ts).Hour = (ct)->hour; /* hours (0 - 23) */ \ + (ts).Minute = (ct)->minute; /* minutes (0 - 59) */ \ + (ts).Second = (ct)->second; /* seconds (0 - 60) */ + // Kumu::Timestamp::Timestamp() : - Year(0), Month(0), Day(0), Hour(0), Minute(0), Second(0) + Year(0), Month(0), Day(0), Hour(0), Minute(0), Second(0) { - time_t t_now = time(0); - struct tm* now = gmtime(&t_now); - TM_TO_TIMESTAMP(now, *this); + Kumu::TAI::tai now; + Kumu::TAI::caltime ct; + now.now(); + ct = now; + CALTIME_TO_TIMESTAMP(&ct, *this) } // 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) ); + Kumu::TAI::caltime lh_ct, rh_ct; + TIMESTAMP_TO_CALTIME(*this, &lh_ct) + TIMESTAMP_TO_CALTIME(rhs, &rh_ct) + + Kumu::TAI::tai lh_tai, rh_tai; + lh_tai = lh_ct; + rh_tai = rh_ct; + + return ( lh_tai.x < rh_tai.x ); +} + +// +bool +Kumu::Timestamp::operator>(const Timestamp& rhs) const +{ + Kumu::TAI::caltime lh_ct, rh_ct; + TIMESTAMP_TO_CALTIME(*this, &lh_ct) + TIMESTAMP_TO_CALTIME(rhs, &rh_ct) + + Kumu::TAI::tai lh_tai, rh_tai; + lh_tai = lh_ct; + rh_tai = rh_ct; + + return ( lh_tai.x > rh_tai.x ); } // void Kumu::Timestamp::AddDays(i32_t days) { - struct tm current; + Kumu::TAI::caltime ct; + Kumu::TAI::tai t; if ( days != 0 ) { - TIMESTAMP_TO_TM(*this, ¤t); - time_t adj_time = timegm(¤t); - adj_time += 86400 * days; - struct tm* now = gmtime(&adj_time); - TM_TO_TIMESTAMP(now, *this); + TIMESTAMP_TO_CALTIME(*this, &ct) + t = ct; + t.add_days(days); + ct = t; + CALTIME_TO_TIMESTAMP(&ct, *this) } } @@ -705,22 +802,23 @@ Kumu::Timestamp::AddDays(i32_t days) void Kumu::Timestamp::AddHours(i32_t hours) { - struct tm current; + Kumu::TAI::caltime ct; + Kumu::TAI::tai t; if ( hours != 0 ) { - TIMESTAMP_TO_TM(*this, ¤t); - time_t adj_time = timegm(¤t); - adj_time += 3600 * hours; - struct tm* now = gmtime(&adj_time); - TM_TO_TIMESTAMP(now, *this); + TIMESTAMP_TO_CALTIME(*this, &ct) + t = ct; + t.add_hours(hours); + ct = t; + CALTIME_TO_TIMESTAMP(&ct, *this) } } #endif // KM_WIN32 -Kumu::Timestamp::Timestamp(const Timestamp& rhs) +Kumu::Timestamp::Timestamp(const Timestamp& rhs) : IArchive() { Year = rhs.Year; Month = rhs.Month; @@ -786,7 +884,7 @@ 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-00:00", + "%04hu-%02hu-%02huT%02hu:%02hu:%02hu+00:00", Year, Month, Day, Hour, Minute, Second); return str_buf; @@ -805,6 +903,7 @@ Kumu::Timestamp::DecodeString(const char* datestr) || ! ( isdigit(datestr[8]) && isdigit(datestr[9]) ) ) return false; + ui32_t char_count = 10; TmpStamp.Year = atoi(datestr); TmpStamp.Month = atoi(datestr + 5); TmpStamp.Day = atoi(datestr + 8); @@ -817,6 +916,7 @@ Kumu::Timestamp::DecodeString(const char* datestr) || ! ( isdigit(datestr[14]) && isdigit(datestr[15]) ) ) return false; + char_count += 6; TmpStamp.Hour = atoi(datestr + 11); TmpStamp.Minute = atoi(datestr + 14); @@ -825,28 +925,46 @@ Kumu::Timestamp::DecodeString(const char* datestr) if ( ! ( isdigit(datestr[17]) && isdigit(datestr[18]) ) ) return false; + char_count += 3; TmpStamp.Second = atoi(datestr + 17); } - } - if ( datestr[19] == '-' || datestr[19] == '+' ) - { - if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) ) - || datestr[22] != ':' - || ! ( isdigit(datestr[23]) && isdigit(datestr[24]) ) ) - return false; + if ( datestr[19] == '.' ) + { + if ( ! ( isdigit(datestr[20]) && isdigit(datestr[21]) && isdigit(datestr[22]) ) ) + return false; + + // we don't carry the ms value + datestr += 4; + } - ui32_t TZ_hh = atoi(datestr + 20); - ui32_t TZ_mm = atoi(datestr + 23); + 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().Error("Ignoring minutes in timezone offset: %u\n", TZ_mm); + if ( TZ_mm != 0 ) + Kumu::DefaultLogSink().Warn("Ignoring minutes in timezone offset: %u\n", TZ_mm); + + if ( TZ_hh > 12 ) + return false; - if ( TZ_hh > 12 ) - return false; + else + AddHours( (datestr[19] == '-' ? (0 - TZ_hh) : TZ_hh)); + } + } - else - AddHours( (datestr[19] == '-' ? (-TZ_hh) : TZ_hh)); + if ( datestr[char_count] != 0 ) + { + Kumu::DefaultLogSink().Error("Unexpected extra characters in string: %s (%ld)\n", + datestr, char_count); + return false; } #ifdef KM_WIN32 @@ -857,11 +975,12 @@ Kumu::Timestamp::DecodeString(const char* datestr) 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); + Kumu::TAI::tai t; + Kumu::TAI::caltime ct; + TIMESTAMP_TO_CALTIME(TmpStamp, &ct); + t = ct; // back and forth to tai to normalize offset + ct = t; + CALTIME_TO_TIMESTAMP(&ct, *this) #endif return true; @@ -897,31 +1016,6 @@ Kumu::Timestamp::Archive(MemIOWriter* Writer) const 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) @@ -950,7 +1044,7 @@ Kumu::MemIOReader::MemIOReader(const 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); } @@ -1002,25 +1096,47 @@ Kumu::ByteString::Set(const byte_t* buf, ui32_t buf_len) } +// 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; }