123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602 |
- /**
- * Tencent is pleased to support the open source community by making Tars available.
- *
- * Copyright (C) 2016THL A29 Limited, a Tencent company. All rights reserved.
- *
- * Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * https://opensource.org/licenses/BSD-3-Clause
- *
- * Unless required by applicable law or agreed to in writing, software distributed
- * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- * CONDITIONS OF ANY KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations under the License.
- */
- #include "util/tc_common.h"
- #include "util/tc_port.h"
- #include <chrono>
- #include <thread>
- #if TARGET_PLATFORM_WINDOWS
- #include <sys/timeb.h>
- #pragma comment(lib, "ws2_32.lib")
- #include "util/tc_strptime.h"
- #endif
- #include <signal.h>
- #include <string.h>
- #include <cmath>
- namespace tars
- {
- #define MATCH_DOUBLE \
- if (vx.size() != vy.size()) { return false; } \
- auto it1 = vx.begin(); auto it2 = vy.end(); \
- while(it1 != vx.end() && it2 != vy.end() ) { \
- if (!equal(*it1, *it2, epsilon)) { return false; } \
- ++it1; \
- ++it2; \
- } \
- return true;
- const float TC_Common::_EPSILON_FLOAT = 0.000001f;
- const double TC_Common::_EPSILON_DOUBLE = 0.000001;
- #if !TARGET_PLATFORM_WINDOWS
- string TC_Common::TimezoneHelper::timezone_local;
- #endif
- int64_t TC_Common::TimezoneHelper::timezone_diff_secs = 0;
- TC_Common::TimezoneHelper TC_Common::_TimeZoneHelper;
- void TC_Common::sleep(uint32_t sec)
- {
- std::this_thread::sleep_for(std::chrono::seconds(sec));
- }
- void TC_Common::msleep(uint32_t ms)
- {
- std::this_thread::sleep_for(std::chrono::milliseconds(ms));
- }
- bool TC_Common::equal(double x, double y, double epsilon)
- {
- return fabs(x - y) < epsilon;
- }
- bool TC_Common::equal(double x, double y, float epsilon)
- {
- return equal(x ,y,(double)epsilon);
- }
- bool TC_Common::equal(float x, float y, float epsilon)
- {
- return fabsf(x - y) < epsilon;
- }
- bool TC_Common::equal(float x, float y, double epsilon)
- {
- return equal(x, y, float(epsilon));
- }
- bool TC_Common::equal(const vector<double>& vx, const vector<double>& vy, double epsilon)
- {
- MATCH_DOUBLE
- }
- bool TC_Common::equal(const vector<double> &vx, const vector<double> &vy, float epsilon)
- {
- return equal(vx, vy, double(epsilon));
- }
- bool TC_Common::equal(const vector<float> &vx, const vector<float> &vy, float epsilon)
- {
- MATCH_DOUBLE
- }
- bool TC_Common::equal(const vector<float> &vx, const vector<float> &vy, double epsilon)
- {
- return equal(vx, vy, float(epsilon));
- }
- bool TC_Common::equal(const set<double> & vx, const set<double>& vy, double epsilon)
- {
- MATCH_DOUBLE
- }
- bool TC_Common::equal(const set<double>& vx, const set<double>& vy, float epsilon )
- {
- return equal(vx, vy, double(epsilon));
- }
- bool TC_Common::equal(const set<float>& vx, const set<float> & vy, float epsilon)
- {
- return equal(vx, vy, double(epsilon));
- }
- bool TC_Common::equal(const set<float>& vx, const set<float>& vy, double epsilon )
- {
- MATCH_DOUBLE
- }
- bool TC_Common::equal(const unordered_set<double> & vx, const unordered_set<double>& vy, double epsilon)
- {
- MATCH_DOUBLE
- }
- bool TC_Common::equal(const unordered_set<double>& vx, const unordered_set<double>& vy, float epsilon )
- {
- return equal(vx, vy, double(epsilon));
- }
- bool TC_Common::equal(const unordered_set<float>& vx, const unordered_set<float> & vy, float epsilon)
- {
- return equal(vx, vy, double(epsilon));
- }
- bool TC_Common::equal(const unordered_set<float>& vx, const unordered_set<float>& vy, double epsilon )
- {
- MATCH_DOUBLE
- }
- template<>
- string TC_Common::tostr<bool>(const bool &t)
- {
- char buf[2];
- buf[0] = t ? '1' : '0';
- buf[1] = '\0';
- return string(buf);
- }
- template<>
- string TC_Common::tostr<char>(const char &t)
- {
- char buf[2];
- snprintf(buf, 2, "%c", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<unsigned char>(const unsigned char &t)
- {
- char buf[2];
- snprintf(buf, 2, "%c", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<short>(const short &t)
- {
- char buf[16];
- snprintf(buf, 16, "%d", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<unsigned short>(const unsigned short &t)
- {
- char buf[16];
- snprintf(buf, 16, "%u", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<int>(const int &t)
- {
- char buf[16];
- snprintf(buf, 16, "%d", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<unsigned int>(const unsigned int &t)
- {
- char buf[16];
- snprintf(buf, 16, "%u", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<long>(const long &t)
- {
- char buf[32];
- snprintf(buf, 32, "%ld", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<long long>(const long long &t)
- {
- char buf[32];
- snprintf(buf, 32, "%lld", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<unsigned long>(const unsigned long &t)
- {
- char buf[32];
- snprintf(buf, 32, "%lu", t);
- return string(buf);
- }
- template<>
- string TC_Common::tostr<float>(const float &t)
- {
- //C++11 to_string,默认保留后面6位小数
- string s = std::to_string(t);
- //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
- bool bFlag = false;
- int pos = int(s.size() - 1);
- for (; pos > 0; --pos)
- {
- if (s[pos] == '0')
- {
- bFlag = true;
- if (s[pos - 1] == '.')
- {
- //-2为了去掉"."号
- pos -= 2;
- break;
- }
- }
- else
- {
- break;
- }
- }
- if (bFlag)
- s = s.substr(0, pos + 1);
- return s;
- }
- template<>
- string TC_Common::tostr<double>(const double &t)
- {
- //C++11 to_string,默认保留后面6位小数
- string s = std::to_string(t);
- //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
- bool bFlag = false;
- int pos = int(s.size() - 1);
- for (; pos > 0; --pos)
- {
- if (s[pos] == '0')
- {
- bFlag = true;
- if (s[pos - 1] == '.')
- {
- //-2为了去掉"."号
- pos -= 2;
- break;
- }
- }
- else
- {
- break;
- }
- }
- if (bFlag)
- s = s.substr(0, pos + 1);
- return s;
- }
- template<>
- string TC_Common::tostr<long double>(const long double &t)
- {
- char buf[32];
- snprintf(buf, 32, "%Lf", t);
- string s(buf);
- //去掉无效0, eg. 1.0300 -> 1.03;1.00 -> 1
- bool bFlag = false;
- int pos = int(s.size() - 1);
- for (; pos > 0; --pos)
- {
- if (s[pos] == '0')
- {
- bFlag = true;
- if (s[pos - 1] == '.')
- {
- //-2为了去掉"."号
- pos -= 2;
- break;
- }
- }
- else
- {
- break;
- }
- }
- if (bFlag)
- s = s.substr(0, pos + 1);
- return s;
- }
- template<>
- string TC_Common::tostr<std::string>(const std::string &t)
- {
- return t;
- }
- string TC_Common::trim(const string &sStr, const string &s, bool bChar)
- {
- if (sStr.empty())
- {
- return sStr;
- }
- /**
- * 将完全与s相同的字符串去掉
- */
- if (!bChar)
- {
- return trimright(trimleft(sStr, s, false), s, false);
- }
- return trimright(trimleft(sStr, s, true), s, true);
- }
- string TC_Common::trimleft(const string &sStr, const string &s, bool bChar)
- {
- if (sStr.empty())
- {
- return sStr;
- }
- /**
- * 去掉sStr左边的字符串s
- */
- if (!bChar)
- {
- if (sStr.length() < s.length())
- {
- return sStr;
- }
- if (sStr.compare(0, s.length(), s) == 0)
- {
- return sStr.substr(s.length());
- }
- return sStr;
- }
- /**
- * 去掉sStr左边的 字符串s中的字符
- */
- string::size_type pos = 0;
- while (pos < sStr.length())
- {
- if (s.find_first_of(sStr[pos]) == string::npos)
- {
- break;
- }
- pos++;
- }
- if (pos == 0) return sStr;
- return sStr.substr(pos);
- }
- string TC_Common::trimright(const string &sStr, const string &s, bool bChar)
- {
- if (sStr.empty())
- {
- return sStr;
- }
- /**
- * 去掉sStr右边的字符串s
- */
- if (!bChar)
- {
- if (sStr.length() < s.length())
- {
- return sStr;
- }
- if (sStr.compare(sStr.length() - s.length(), s.length(), s) == 0)
- {
- return sStr.substr(0, sStr.length() - s.length());
- }
- return sStr;
- }
- /**
- * 去掉sStr右边的 字符串s中的字符
- */
- string::size_type pos = sStr.length();
- while (pos != 0)
- {
- if (s.find_first_of(sStr[pos - 1]) == string::npos)
- {
- break;
- }
- pos--;
- }
- if (pos == sStr.length()) return sStr;
- return sStr.substr(0, pos);
- }
- string TC_Common::lower(const string &s)
- {
- string sString = s;
- for (string::iterator iter = sString.begin(); iter != sString.end(); ++iter)
- {
- *iter = tolower(*iter);
- }
- return sString;
- }
- string TC_Common::upper(const string &s)
- {
- string sString = s;
- for (string::iterator iter = sString.begin(); iter != sString.end(); ++iter)
- {
- *iter = toupper(*iter);
- }
- return sString;
- }
- bool TC_Common::isdigit(const string &sInput)
- {
- string::const_iterator iter = sInput.begin();
- if (sInput.empty())
- {
- return false;
- }
- while (iter != sInput.end())
- {
- if (!::isdigit(*iter))
- {
- return false;
- }
- ++iter;
- }
- return true;
- }
- TC_Common::TimezoneHelper::TimezoneHelper()
- {
- struct tm timeinfo;
- time_t secs, local_secs, gmt_secs;
- // UTC时间戳
- time(&secs);
- //带时区时间
- TC_Port::localtime_r(&secs, &timeinfo);
- local_secs = ::mktime(&timeinfo);
- #if !TARGET_PLATFORM_WINDOWS
- timezone_local = string(timeinfo.tm_zone);
- #endif
- //不带时区时间
- TC_Port::gmtime_r(&secs, &timeinfo);
- gmt_secs = ::mktime(&timeinfo);
- timezone_diff_secs = local_secs - gmt_secs;
- }
- int TC_Common::str2tm(const string &sString, const string &sFormat, struct tm &stTm)
- {
- memset(&stTm, 0, sizeof(stTm));
- char *p = strptime(sString.c_str(), sFormat.c_str(), &stTm);
- return (p != NULL) ? 0 : -1;
- }
- time_t TC_Common::str2time(const string &sString, const string &sFormat)
- {
- struct tm stTm;
- if (0 == str2tm(sString, sFormat, stTm))
- {
- //注意这里没有直接用mktime, mktime会访问时区文件, 会巨慢!
- return TC_Port::timegm(&stTm) - TimezoneHelper::timezone_diff_secs;
- }
- return 0;
- }
- int TC_Common::strgmt2tm(const string &sString, struct tm &stTm)
- {
- return str2tm(sString, "%a, %d %b %Y %H:%M:%S GMT", stTm);
- }
- string TC_Common::tm2str(const struct tm &stTm, const string &sFormat)
- {
- char sTimeString[255] = "\0";
- strftime(sTimeString, sizeof(sTimeString), sFormat.c_str(), &stTm);
- return string(sTimeString);
- }
- int TC_Common::gettimeofday(struct timeval &tv)
- {
- return TC_Port::gettimeofday(tv);
- }
- void TC_Common::tm2time(const time_t &t, struct tm &tt)
- {
- //加快速度, 否则会比较慢, 不用localtime_r(会访问时区文件, 较慢)
- time_t localt = t + TimezoneHelper::timezone_diff_secs;
- TC_Port::gmtime_r(&localt, &tt);
- #if !TARGET_PLATFORM_WINDOWS
- static string local_timezone = TimezoneHelper::timezone_local;
- tt.tm_zone = const_cast<char *>(local_timezone.c_str());
- tt.tm_gmtoff = TimezoneHelper::timezone_diff_secs;
- #endif
- }
- time_t TC_Common::UTC2LocalTime(const string& utcTimeStr)
- {
- // 2022-06-07T18:04:37.703806784Z
- if (utcTimeStr.length() < 20 || utcTimeStr.at(10) != 'T' || utcTimeStr.back() != 'Z')
- {
- return 0;
- }
- return TC_Common::str2time(utcTimeStr, "%Y-%m-%dT%H:%M:%S") + TimezoneHelper::timezone_diff_secs;
- }
- string TC_Common::tm2str(const time_t &t, const string &sFormat)
- {
- struct tm tt;
- tm2time(t, tt);
- return tm2str(tt, sFormat);
- }
- void TC_Common::tm2tm(const time_t &t, struct tm &tt)
- {
- tm2time(t, tt);
- }
- string TC_Common::now2str(const string &sFormat)
- {
- time_t t = time(NULL);
- return tm2str(t, sFormat.c_str());
- }
- //string TC_Common::now2msstr()
- //{
- // return ms2str(now2ms());
- //}
- string TC_Common::ms2str(int64_t ms)
- {
- time_t t = ms / 1000;
- auto duration_in_ms = ms % 1000;
- tm tt;
- TC_Port::localtime_r(&t, &tt);
- string s;
- s.resize(128);
- const char *szFormat = "%04d-%02d-%02d %02d:%02d:%02d.%03ld";
- size_t n = snprintf(&s[0], s.size(), szFormat, tt.tm_year + 1900, tt.tm_mon + 1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec, duration_in_ms);
- s.resize(n);
- return s;
- }
- string TC_Common::now2msstr()
- {
- time_t t = time(NULL);
- auto duration_in_ms = now2ms();
- tm tt;
- TC_Port::localtime_r(&t, &tt);
- string s;
- s.resize(128);
- const char *szFormat = "%04d-%02d-%02d %02d:%02d:%02d.%03ld";
- size_t n = snprintf(&s[0], s.size(), szFormat, tt.tm_year + 1900, tt.tm_mon + 1, tt.tm_mday, tt.tm_hour, tt.tm_min, tt.tm_sec, duration_in_ms % 1000);
- s.resize(n);
- return s;
- }
- string TC_Common::now2GMTstr()
- {
- time_t t = time(NULL);
- return tm2GMTstr(t);
- }
- string TC_Common::tm2GMTstr(const time_t &t)
- {
- struct tm tt;
- TC_Port::gmtime_r(&t, &tt);
- return tm2str(tt, "%a, %d %b %Y %H:%M:%S GMT");
- }
- string TC_Common::tm2GMTstr(const struct tm &stTm)
- {
- return tm2str(stTm, "%a, %d %b %Y %H:%M:%S GMT");
- }
- string TC_Common::nowdate2str()
- {
- return now2str("%Y%m%d");
- }
- string TC_Common::nowtime2str()
- {
- return now2str("%H%M%S");
- }
- int64_t TC_Common::now2ms()
- {
- struct timeval tv;
- TC_Common::gettimeofday(tv);
- return tv.tv_sec * (int64_t) 1000 + tv.tv_usec / 1000;
- }
- int64_t TC_Common::now2us()
- {
- struct timeval tv;
- TC_Common::gettimeofday(tv);
- return tv.tv_sec * (int64_t) 1000000 + tv.tv_usec;
- }
- //参照phorix的优化
- static char c_b2s[256][4] = {"00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f", "20", "21", "22",
- "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f", "40", "41", "42", "43", "44", "45",
- "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f", "60", "61", "62", "63", "64", "65", "66", "67", "68",
- "69", "6a", "6b", "6c", "6d", "6e", "6f", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b",
- "8c", "8d", "8e", "8f", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae",
- "af", "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf", "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf", "d0", "d1",
- "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df", "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef", "f0", "f1", "f2", "f3", "f4",
- "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff"};
- string TC_Common::bin2str(const void *buf, size_t len, const string &sSep, size_t lines)
- {
- if (buf == NULL || len <= 0)
- {
- return "";
- }
- string sOut;
- const unsigned char *p = (const unsigned char *) buf;
- for (size_t i = 0; i < len; ++i, ++p)
- {
- sOut += c_b2s[*p][0];
- sOut += c_b2s[*p][1];
- sOut += sSep;
- //换行
- if ((lines != 0) && ((i + 1) % lines == 0))
- {
- sOut += "\n";
- }
- }
- return sOut;
- }
- string TC_Common::bin2str(const string &sBinData, const string &sSep, size_t lines)
- {
- return bin2str((const void *) sBinData.data(), sBinData.length(), sSep, lines);
- }
- int TC_Common::str2bin(const char *psAsciiData, unsigned char *sBinData, int iBinSize)
- {
- int iAsciiLength = (int) strlen(psAsciiData);
- int iRealLength = (iAsciiLength / 2 > iBinSize) ? iBinSize : (iAsciiLength / 2);
- for (int i = 0; i < iRealLength; i++)
- {
- sBinData[i] = x2c(psAsciiData + i * 2);
- }
- return iRealLength;
- }
- string TC_Common::str2bin(const string &sString, const string &sSep, size_t lines)
- {
- const char *psAsciiData = sString.c_str();
- size_t iAsciiLength = sString.length();
- string sBinData;
- for (size_t i = 0; i < iAsciiLength; i++)
- {
- sBinData += x2c(psAsciiData + i);
- i++;
- i += sSep.length(); //过滤掉分隔符
- if (lines != 0 && sBinData.length() % lines == 0)
- {
- i++; //过滤掉回车
- }
- }
- return sBinData;
- }
- char TC_Common::x2c(const string &sWhat)
- {
- register char digit;
- if (sWhat.length() < 2)
- {
- return '\0';
- }
- digit = (sWhat[0] >= 'A' ? ((sWhat[0] & 0xdf) - 'A') + 10 : (sWhat[0] - '0'));
- digit *= 16;
- digit += (sWhat[1] >= 'A' ? ((sWhat[1] & 0xdf) - 'A') + 10 : (sWhat[1] - '0'));
- return (digit);
- }
- string TC_Common::replace(const string &sString, const string &sSrc, const string &sDest)
- {
- if (sSrc.empty())
- {
- return sString;
- }
- string sBuf = sString;
- string::size_type pos = 0;
- while ((pos = sBuf.find(sSrc, pos)) != string::npos)
- {
- sBuf.replace(pos, sSrc.length(), sDest);
- pos += sDest.length();
- }
- return sBuf;
- }
- string TC_Common::replace(const string &sString, const map<string, string> &mSrcDest)
- {
- if (sString.empty())
- {
- return sString;
- }
- string tmp = sString;
- map<string, string>::const_iterator it = mSrcDest.begin();
- while (it != mSrcDest.end())
- {
- string::size_type pos = 0;
- while ((pos = tmp.find(it->first, pos)) != string::npos)
- {
- tmp.replace(pos, it->first.length(), it->second);
- pos += it->second.length();
- }
- ++it;
- }
- return tmp;
- }
- bool TC_Common::matchPeriod(const string &s, const string &pat)
- {
- if (s.empty())
- {
- return false;
- }
- if (pat.empty())
- {
- return true;
- }
- if (pat.find('*') == string::npos)
- {
- return s == pat;
- }
- string::size_type sIndex = 0;
- string::size_type patIndex = 0;
- do
- {
- if (pat[patIndex] == '*')
- {
- if (s[sIndex] == '.')
- {
- return false;
- }
- while (sIndex < s.size() && s[sIndex] != '.')
- {
- ++sIndex;
- }
- patIndex++;
- }
- else
- {
- if (pat[patIndex] != s[sIndex])
- {
- return false;
- }
- ++sIndex;
- ++patIndex;
- }
- } while (sIndex < s.size() && patIndex < pat.size());
- return sIndex == s.size() && patIndex == pat.size();
- }
- bool TC_Common::matchPeriod(const string &s, const vector<string> &pat)
- {
- for (size_t i = 0; i < pat.size(); i++)
- {
- if (TC_Common::matchPeriod(s, pat[i]))
- {
- return true;
- }
- }
- return false;
- }
- #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
- void TC_Common::daemon()
- {
- pid_t pid;
- if ((pid = fork()) != 0)
- {
- exit(0);
- }
- setsid();
- signal(SIGINT, SIG_IGN);
- signal(SIGHUP, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGPIPE, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
- signal(SIGTTIN, SIG_IGN);
- signal(SIGCHLD, SIG_IGN);
- signal(SIGTERM, SIG_IGN);
- ignorePipe();
- if ((pid = fork()) != 0)
- {
- //父进程结束,变成daemon
- exit(0);
- }
- umask(0);
- // chdir("/");
- }
- void TC_Common::ignorePipe()
- {
- struct sigaction sig;
- memset(&sig, 0, sizeof(struct sigaction));
- sig.sa_handler = SIG_IGN;
- sig.sa_flags = 0;
- sigemptyset(&sig.sa_mask);
- sigaction(SIGPIPE, &sig, NULL);
- }
- #endif
- bool TC_Common::isPrimeNumber(size_t n)
- {
- size_t nn = (size_t)sqrt((double)n);
- for(size_t i = 2; i <= nn;i++)
- {
- if (n % i == 0)
- {
- return false;
- }
- }
- return true;
- }
- size_t TC_Common::toSize(const string &s, size_t iDefaultSize)
- {
- if (s.empty())
- {
- return iDefaultSize;
- }
- char c = s[s.length() - 1];
- if (c != 'K' && c != 'M' && c != 'G' && TC_Common::trim(s) == TC_Common::tostr(TC_Common::strto<size_t>(s)))
- {
- //没有后缀, 且转换是正确的
- return (size_t) (TC_Common::strto<size_t>(s));
- }
- else if (c == 'K' || c == 'M' || c == 'G')
- {
- if (s.length() == 1)
- {
- return iDefaultSize;
- }
- float n = TC_Common::strto<float>(s.substr(0, s.length() - 1));
- if (TC_Common::trim(s.substr(0, s.length() - 1)) != TC_Common::tostr(n))
- {
- return iDefaultSize;
- }
- if (c == 'K')
- {
- return (size_t) (n * 1024);
- }
- if (c == 'M')
- {
- return (size_t) (n * 1024 * 1024);
- }
- if (c == 'G')
- {
- return (size_t) (n * 1024 * 1024 * 1024);
- }
- }
- return iDefaultSize;
- }
- string TC_Common::getHostName()
- {
- string hostName;
- char buff[256] = {0};
- int ret = ::gethostname(buff, sizeof(buff));
- if (0 == ret)
- {
- hostName = string(buff);
- }
- else
- {
- // 获取不到host, 则直接传空串。
- }
- return hostName;
- }
- #if TARGET_PLATFORM_LINUX || TARGET_PLATFORM_IOS
- // Generate the randome string, a SHA1-sized random number
- void TC_Common::getRandomHexChars(char *p, unsigned int len)
- {
- const char *const chars = "0123456789abcdef";
- FILE *fp = fopen("/dev/urandom", "r");
- if (!fp || fread(p, len, 1, fp) == 0)
- {
- for (unsigned int j = 0; j < len; j++)
- p[j] ^= rand();
- }
- if (fp) fclose(fp);
- for (unsigned int j = 0; j < len; j++)
- p[j] = chars[p[j] & 0x0F];
- }
- #endif
- string TC_Common::nextDate(const string &sDate)
- {
- time_t tomorrow = TC_Common::str2time(sDate + "000000", "%Y%m%d%H%M%S") + 60 * 60 * 24;
- return TC_Common::tm2str(tomorrow, "%Y%m%d");
- }
- string TC_Common::prevDate(const string &sDate)
- {
- time_t tomorrow = TC_Common::str2time(sDate + "000000", "%Y%m%d%H%M%S") - 60 * 60 * 24;
- return TC_Common::tm2str(tomorrow, "%Y%m%d");
- }
- int TC_Common::nextDate(int iDate)
- {
- return TC_Common::strto<int>(nextDate(TC_Common::tostr(iDate)));
- }
- int TC_Common::prevDate(int iDate)
- {
- return TC_Common::strto<int>(prevDate(TC_Common::tostr(iDate)));
- }
- string TC_Common::nextMonth(const string &sMonth)
- {
- if (sMonth.length() != 6)
- {
- return "197001";
- }
- int year = TC_Common::strto<int>(sMonth.substr(0, 4));
- int month = TC_Common::strto<int>(sMonth.substr(4, 2));
- int monthNew = month + 1;
- int yearNew = year;
- if (monthNew == 13)
- {
- monthNew = 1;
- yearNew = year + 1;
- }
- yearNew = (yearNew >= 1970 && yearNew <= 9999) ? yearNew : 1970;
- monthNew = (monthNew >= 1 && monthNew <= 12) ? monthNew : 0;
- char szMonth[4] = {0};
- snprintf(szMonth, sizeof(szMonth) - 1, "%02d", monthNew);
- return TC_Common::tostr(yearNew) + szMonth;
- }
- string TC_Common::prevMonth(const string &sMonth)
- {
- if (sMonth.length() != 6)
- {
- return "197001";
- }
- int year = TC_Common::strto<int>(sMonth.substr(0, 4));
- int month = TC_Common::strto<int>(sMonth.substr(4, 2));
- int monthNew = month - 1;
- int yearNew = year;
- if (monthNew == 0)
- {
- monthNew = 12;
- yearNew = year - 1;
- }
- yearNew = (yearNew >= 1970 && yearNew <= 9999) ? yearNew : 1970;
- monthNew = (monthNew >= 1 && monthNew <= 12) ? monthNew : 0;
- char szMonth[4] = {0};
- snprintf(szMonth, sizeof(szMonth) - 1, "%02d", monthNew);
- return TC_Common::tostr(yearNew) + szMonth;
- }
- string TC_Common::nextYear(const string &sYear)
- {
- if (sYear.length() != 4)
- {
- return "1970";
- }
- int year = TC_Common::strto<int>(sYear.substr(0, 4));
- int yearNew = year + 1;
- yearNew = (yearNew >= 1970 && yearNew <= 9999) ? yearNew : 1970;
- return TC_Common::tostr(yearNew);
- }
- string TC_Common::prevYear(const string &sYear)
- {
- if (sYear.length() != 4)
- {
- return "1970";
- }
- int year = TC_Common::strto<int>(sYear.substr(0, 4));
- int yearNew = year - 1;
- yearNew = (yearNew >= 1970 && yearNew <= 9999) ? yearNew : 1970;
- return TC_Common::tostr(yearNew);
- }
- int TC_Common::secondsToDateInt(time_t seconds)
- {
- struct tm tt;
- TC_Common::tm2tm(seconds, tt);
- return (1900 + tt.tm_year) * 10000 + (tt.tm_mon + 1) * 100 + tt.tm_mday;
- }
- string TC_Common::secondsToDateString(time_t seconds)
- {
- return TC_Common::tostr(secondsToDateInt(seconds));
- }
- string TC_Common::secondsToMondayString(time_t seconds)
- {
- //换到周一
- int week = TC_Common::strto<int>(TC_Common::tm2str(seconds, "%w"));
- seconds -= (week - 1) * 86400;
- return TC_Common::tm2str(seconds, "%Y%m%d");
- }
- string TC_Common::secondsToMonthString(time_t seconds)
- {
- return TC_Common::tm2str(seconds, "%Y-%m");
- }
- string TC_Common::msToTimeString(int64_t ms)
- {
- int64_t sec = ms / 1000;
- int64_t msec = ms % 1000;
- char szMS[5] = {0};
- snprintf(szMS, sizeof(szMS) - 1, "%03d", (int) msec);
- return TC_Common::tm2str(sec, "%Y%m%d-%H%M%S-") + string(szMS);
- }
- int64_t TC_Common::timeStringToMs(const string &timeStr)
- {
- vector<string> vt = TC_Common::sepstr<string>(timeStr, "-");
- if (vt.size() != 3)
- {
- return 0;
- }
- string &date = vt[0];
- string &time = vt[1];
- string &ms = vt[2];
- if (date.size() != 8 || time.size() != 6 || ms.size() != 3)
- {
- return 0;
- }
- int64_t lsec = TC_Common::str2time(date + time);
- int64_t lms = TC_Common::strto<int64_t>(ms);
- return lsec * 1000 + lms;
- }
- bool TC_Common::getSectionFromMs(int64_t ms, string &date, string &time, string &mstick)
- {
- string timeStr = msToTimeString(ms);
- vector<string> vt = TC_Common::sepstr<string>(timeStr, "-");
- if (vt.size() != 3)
- {
- return false;
- }
- date = vt[0];
- time = vt[1];
- mstick = vt[2];
- return true;
- }
- string TC_Common::getDateFromMs(int64_t ms)
- {
- string date;
- string time;
- string mstick;
- if (!getSectionFromMs(ms, date, time, mstick))
- {
- return "00000000";
- }
- return date;
- }
- string TC_Common::getTimeFromMs(int64_t ms)
- {
- string date;
- string time;
- string mstick;
- if (!getSectionFromMs(ms, date, time, mstick))
- {
- return "000000";
- }
- return time;
- }
- int TC_Common::msToNowSeconds(int64_t ms)
- {
- int64_t sec = ms / 1000;
- //换成当天的秒
- int64_t now = TC_Common::str2time(TC_Common::tm2str(sec, "%Y%m%d") + "000000", "%Y%m%d%H%M%S");
- return (sec - now);
- }
- int TC_Common::nowDaySeconds()
- {
- return TC_Common::msToNowSeconds(TC_Common::now2ms());
- }
- int64_t TC_Common::msToNowMs(int64_t ms)
- {
- int64_t sec = ms / 1000;
- //换成当天的秒
- int64_t now = TC_Common::str2time(TC_Common::tm2str(sec, "%Y%m%d") + "000000", "%Y%m%d%H%M%S");
- return now * 1000;
- }
- int64_t TC_Common::us()
- {
- struct timeval tv;
- TC_Common::gettimeofday(tv);
- return tv.tv_sec * (int64_t) 1000000 + tv.tv_usec;
- }
- int64_t TC_Common::dateToMs(const string &sDate)
- {
- int64_t now;
- if (sDate.find('-') != string::npos)
- {
- now = TC_Common::str2time(sDate + "000000", "%Y-%m-%d%H%M%S");
- }
- else
- {
- //换成当天的秒
- now = TC_Common::str2time(sDate + "000000", "%Y%m%d%H%M%S");
- }
- return now * 1000;
- }
- int64_t TC_Common::dateToSecond(const string &sDate)
- {
- int64_t now;
- if (sDate.find('-') != string::npos)
- {
- now = TC_Common::str2time(sDate + "000000", "%Y-%m-%d%H%M%S");
- }
- else
- {
- //换成当天的秒
- now = TC_Common::str2time(sDate + "000000", "%Y%m%d%H%M%S");
- }
- return now;
- }
- int TC_Common::dateTo(const string &sDate, const string &sPeriod)
- {
- if (sPeriod == "W")
- {
- return dateToWeek(sDate);
- }
- else if (sPeriod == "M")
- {
- return dateToMonth(sDate);
- }
- else if (sPeriod == "Q")
- {
- return dateToSeason(sDate);
- }
- else if (sPeriod == "S")
- {
- return dateToHalfYear(sDate);
- }
- else if (sPeriod == "Y")
- {
- return dateToYear(sDate);
- }
- return 0;
- }
- int TC_Common::dateToWeekday(const string &sDate)
- {
- struct tm date;
- TC_Common::str2tm(sDate, "%Y%m%d", date);
- return date.tm_wday;
- }
- int TC_Common::dateToWeek(const string &sDate)
- {
- struct tm date;
- TC_Common::str2tm(sDate, "%Y%m%d", date);
- return TC_Common::strto<int>(TC_Common::tm2str(date, "%W"));
- }
- int TC_Common::dateToMonth(const string &sDate)
- {
- return TC_Common::strto<int>(sDate.substr(4, 2));
- }
- int TC_Common::dateToSeason(const string &sDate)
- {
- string month = sDate.substr(4, 2);
- if (month == "01" || (month == "02") || (month == "03"))
- {
- return 1;
- }
- else if (month == "04" || (month == "05") || (month == "06"))
- {
- return 2;
- }
- else if (month == "07" || (month == "08") || (month == "09"))
- {
- return 3;
- }
- else if (month == "10" || (month == "11") || (month == "12"))
- {
- return 4;
- }
- return 0;
- }
- int TC_Common::dateToHalfYear(const string &sDate)
- {
- string month = sDate.substr(4, 2);
- if (month == "01" || (month == "02") || (month == "03") || (month == "04") || (month == "05") || (month == "06"))
- {
- return 1;
- }
- else if (month == "07" || (month == "08") || (month == "09") || (month == "10") || (month == "11") || (month == "12"))
- {
- return 2;
- }
- return 0;
- }
- int TC_Common::dateToYear(const string &sDate)
- {
- return TC_Common::strto<int>(sDate.substr(0, 4));
- }
- int64_t TC_Common::timeToDaySec(int64_t hour, int64_t min)
- {
- return hour * 3600 + min * 60;
- }
- int64_t TC_Common::getNextAbsClockMs(int64_t clockSec)
- {
- int64_t now = TC_Common::now2ms();
- int64_t nowSec = TC_Common::msToNowSeconds(now);
- int64_t currentDateMs = TC_Common::dateToMs(TC_Common::getDateFromMs(now));
- //如果已经超过了通知时间,则改到第二天继续通知
- int64_t notityRealTimeMs = 0;
- if (nowSec > clockSec + 1)
- {
- notityRealTimeMs = currentDateMs + clockSec * 1000 + ONE_DAY_MS;
- }
- else
- {
- notityRealTimeMs = currentDateMs + clockSec * 1000;
- }
- return notityRealTimeMs;
- }
- int TC_Common::nextDate(int iDate, int offset)
- {
- if (offset == 0)
- {
- return iDate;
- }
- else if (offset < 0)
- {
- return prevDate(iDate, std::abs(offset));
- }
- time_t t = TC_Common::str2time(TC_Common::tostr(iDate * 1000000LL));
- t = t + ONE_DAY_SEC * offset;
- return TC_Common::strto<int>(TC_Common::tm2str(t, "%Y%m%d"));
- }
- int TC_Common::prevDate(int iDate, int offset)
- {
- if (offset == 0)
- {
- return iDate;
- }
- else if (offset < 0)
- {
- return nextDate(iDate, std::abs(offset));
- }
- time_t t = TC_Common::str2time(TC_Common::tostr(iDate * 1000000LL));
- t = t - ONE_DAY_SEC * offset;
- return TC_Common::strto<int>(TC_Common::tm2str(t, "%Y%m%d"));
- }
- int TC_Common::lastDate(int iDate, const char period)
- {
- if (period == 'D')
- {
- return iDate;
- }
- switch (period)
- {
- case 'W': // 周日为一周的开始, 周六结束
- {
- struct tm t;
- int rc = TC_Common::str2tm(TC_Common::tostr(iDate), "%Y%m%d", t);
- if (rc != 0)
- {
- return rc;
- }
- if (t.tm_wday == 6)
- {
- return iDate;
- }
- int offset = 6 - t.tm_wday; // 下周六
- return nextDate(iDate, offset);
- }
- case 'M': // 下月一号的上一天是一个月的开始
- {
- int month = iDate / 10000;
- month = iDate - month * 10000;
- month = month / 100;
- int monthDateStart = ((iDate / 10000)) * 10000 + (month + 1) * 100 + 1; // 下月初
- if (month == 12)
- {
- monthDateStart = ((iDate / 10000) + 1) * 10000 + (0 + 1) * 100 + 1; // 下年一月初
- }
- return prevDate(monthDateStart, 1); // 上一天: 上月底
- }
- case 'Q': // 331, 630, 930, 1231
- {
- const int seasonDateEnd[4] = {331, 630, 930, 1231};
- std::function<int(int)> date2season = [](int date)
- {
- int month = date / 10000;
- month = date - month * 10000;
- month = month / 100;
- return ((month - 1) / 3);
- };
- return ((iDate / 10000)) * 10000 + seasonDateEnd[date2season(iDate)];
- }
- case 'S': // 631, 1231
- {
- int tmp = ((iDate / 10000)) * 10000 + 631;
- if (iDate > tmp)
- {
- return ((iDate / 10000)) * 10000 + 1231;
- }
- else
- {
- return tmp;
- }
- }
- break;
- case 'Y': // 1231
- {
- return ((iDate / 10000)) * 10000 + 1231;
- }
- default:
- return -1;
- }
- }
- // 判断两个日期是否在同一周期中
- inline bool TC_Common::matchPeriod(int lastDate, int date, const std::string &period)
- {
- if (lastDate == 0 || date == 0)
- {
- return false;
- }
- if (period == "W")
- {
- int a = TC_Common::dateToWeek(TC_Common::tostr(lastDate));
- int b = TC_Common::dateToWeek(TC_Common::tostr(date));
- return a == b;
- }
- else if (period == "M")
- {
- int a = TC_Common::dateToMonth(TC_Common::tostr(lastDate));
- int b = TC_Common::dateToMonth(TC_Common::tostr(date));
- return a == b;
- }
- else if (period == "Q")
- {
- int a = TC_Common::dateToSeason(TC_Common::tostr(lastDate));
- int b = TC_Common::dateToSeason(TC_Common::tostr(date));
- return a == b;
- }
- else if (period == "S")
- {
- int a = TC_Common::dateToHalfYear(TC_Common::tostr(lastDate));
- int b = TC_Common::dateToHalfYear(TC_Common::tostr(date));
- return a == b;
- }
- else if (period == "Y")
- {
- int a = TC_Common::dateToYear(TC_Common::tostr(lastDate));
- int b = TC_Common::dateToYear(TC_Common::tostr(date));
- return a == b;
- }
- return false;
- }
- int TC_Common::getMatchPeriodDays(const std::vector<int> &days, const std::pair<string, int> &period, std::vector<int> &matchDays)
- {
- std::map<std::string, int> periodList{{"W", 5},
- {"M", 25},
- {"Q", 25 * 3},
- {"S", 25 * 3 * 2},
- {"Y", 256}};
- std::string p = TC_Common::upper(period.first);
- if (periodList.find(p) == periodList.end())
- {
- return -1;
- }
- else if ((periodList.at(p) < std::abs(period.second)) || period.second == 0)
- {
- return -1;
- }
- // 按周期切片
- std::vector<std::vector<int>> slice;
- int lastDate = 0;
- int idx = 0;
- for (auto const d : days)
- {
- if (d <= 0)
- {
- continue;
- }
- // 第一次必然不匹配 lastDate == 0
- if (!TC_Common::matchPeriod(d, lastDate, p))
- {
- lastDate = d;
- slice.emplace_back(std::vector<int>());
- idx++;
- }
- slice[idx - 1].push_back(d);
- }
- // 在周期切片中按下标取对应的数据
- for (auto const &v : slice)
- {
- if (std::abs(period.second) > v.size())
- {
- continue;
- }
- if (period.second > 0)
- {
- matchDays.push_back(v.at(period.second - 1));
- }
- else if (period.second < 0)
- {
- matchDays.push_back(v.at(v.size() + period.second));
- }
- }
- return 0;
- }
- }
|