123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- #ifndef _SP_UTILITIES_H__
- #define _SP_UTILITIES_H__
- #pragma once
- #include <vector>
- #include <algorithm>
- #include <cctype>
- #include <iomanip>
- #include <sstream>
- #include <time.h>
- #include "toolkit.h"
- #include "ErrorCode.h"
- #include "SpBase.h"
- #include <winpr/synch.h>
- #ifndef ASSERT
- #include <assert.h>
- #define ASSERT assert
- #endif
- #define random(x) (rand() %x)
- inline static void InitializeRandomSeed(void)
- {
- srand((int)time(0));
- }
- inline static int GetRandomDigit(int greatEqual, int lowerThan)
- {
- int c = random(lowerThan);
- while (c < greatEqual) {
- c = random(lowerThan);
- }
- return c;
- }
- namespace SP {
- namespace Utility {
- inline bool IsStartWith(std::string const& s, std::string const& prefix)
- {
- return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());
- }
- inline bool IsStartWith(std::string const& s, char prefixChar)
- {
- return !s.empty() && s[0] == prefixChar;
- }
- inline bool IsEndWith(std::string const& s, std::string const& suffix)
- {
- return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
- }
- inline bool IsEndWith(std::string const& s, char suffixChar)
- {
- return !s.empty() && s[s.size() - 1] == suffixChar;
- }
- inline bool IsContains(std::string const& s, std::string const& infix)
- {
- return s.find(infix) != std::string::npos;
- }
- inline bool IsNum(const std::string& value);
- inline char ToLowerCh(char c)
- {
- return static_cast<char>(std::tolower(c));
- }
- inline bool CheckIPv4(const std::string& value);
- inline void toLowerInPlace(std::string& s)
- {
- std::transform(s.begin(), s.end(), s.begin(), ToLowerCh);
- }
- inline std::string ToLower(std::string const& s)
- {
- std::string lc = s;
- toLowerInPlace(lc);
- return lc;
- }
- inline std::string ToUpper(const std::string str)
- {
- std::string dest;
- dest.resize(str.size());
- std::transform(str.begin(), str.end(), dest.begin(), ::toupper);
- return dest;
- }
- inline std::string ToTrim(std::string const& str)
- {
- static char const* whitespaceChars = "\n\r\t ";
- std::string::size_type start = str.find_first_not_of(whitespaceChars);
- std::string::size_type end = str.find_last_not_of(whitespaceChars);
- return start != std::string::npos ? str.substr(start, 1 + end - start) : std::string();
- }
- inline bool replaceInPlace(std::string& str, std::string const& replaceThis, std::string const& withThis)
- {
- bool replaced = false;
- std::size_t i = str.find(replaceThis);
- while (i != std::string::npos) {
- replaced = true;
- str = str.substr(0, i) + withThis + str.substr(i + replaceThis.size());
- if (i < str.size() - withThis.size())
- i = str.find(replaceThis, i + withThis.size());
- else
- i = std::string::npos;
- }
- return replaced;
- }
- template<typename T>
- std::string fpToString(T value, int precision) {
- std::ostringstream oss;
- oss << std::setprecision(precision)
- << std::fixed
- << value;
- std::string d = oss.str();
- std::size_t i = d.find_last_not_of('0');
- if (i != std::string::npos && i != d.size() - 1) {
- if (d[i] == '.')
- i++;
- d = d.substr(0, i + 1);
- }
- return d;
- }
- inline static std::vector<std::string> Split(std::string str, char splitElem)
- {
- std::vector<std::string> strs;
- std::string::size_type pos1, pos2;
- pos2 = str.find(splitElem);
- pos1 = 0;
- while (std::string::npos != pos2) {
- strs.push_back(str.substr(pos1, pos2 - pos1));
- pos1 = pos2 + 1;
- pos2 = str.find(splitElem, pos1);
- }
- strs.push_back(str.substr(pos1));
- return strs;
- }
- /** TODO: Migrate from LocalMediaplyer::AdvManage, which is functionally similar as the above one [Gifur@2025822]
- 两者实现还有些不一样,参考find_first_of的用法,分隔符号更多是separator的其中之一个字符就生效
- */
- inline static void split2(const std::string& src, const std::string& separator, std::vector<std::string>& dest)
- {
- std::string str = src;
- std::string substring;
- std::string::size_type start = 0, index;
- do
- {
- index = str.find_first_of(separator, start);
- if (index != std::string::npos)
- {
- substring = str.substr(start, index - start);
- dest.push_back(substring);
- start = str.find_first_not_of(separator, index);
- if (start == std::string::npos) return;
- }
- } while (index != std::string::npos);
- //the last token
- substring = str.substr(start);
- dest.push_back(substring);
- }
- inline std::string ExtractClassName(std::string const& className)
- {
- std::string strClassName = className;
- if(IsStartWith(strClassName, '&'))
- {
- std::size_t lastColons = strClassName.rfind("::");
- std::size_t nextLastColons = strClassName.rfind("::", lastColons - 1);
- if (nextLastColons == std::string::npos)
- nextLastColons = 1;
- strClassName = strClassName.substr(nextLastColons, lastColons - nextLastColons);
- }
- return strClassName;
- }
- inline bool IsValidUrl(const std::string& value);
- SPBASE_API std::string W2S(const std::wstring wstr);
- SPBASE_API std::wstring S2W(const std::string str);
- SPBASE_API std::string GBK2UTF8(const std::string str);
- SPBASE_API std::string UTF8ToGBK(const std::string str);
- }
- namespace Toolkit {
- class CConditionVar;
- class CMutex
- {
- public:
- CMutex() :_in(false)
- {
- toolkit_mutex_init(&_mutex);
- }
- ~CMutex() {
- if (_in) { Leave(); }
- toolkit_mutex_destroy(&_mutex);
- }
- void Enter() {
- toolkit_mutex_lock(&_mutex);
- _in = true;
- }
- void Leave() {
- toolkit_mutex_unlock(&_mutex);
- _in = false;
- }
- bool TryEnter() {
- if (0 == toolkit_mutex_trylock(&_mutex)) {
- _in = true;
- return true;
- }
- return false;
- }
- friend class CConditionVar;
- private:
- toolkit_mutex_t _mutex;
- bool _in;
- };
- class CUniqueLock
- {
- public:
- CUniqueLock(CMutex& m) : mutex_(m)
- {
- innerLock();
- }
- ~CUniqueLock()
- {
- if (owns_) {
- innerUnlock();
- }
- }
- private:
- void innerLock()
- {
- mutex_.Enter();
- owns_ = true;
- }
- void innerUnlock()
- {
- owns_ = false;
- mutex_.Leave();
- }
- CMutex& mutex_;
- bool owns_;
- };
- class CConditionVar
- {
- public:
- CConditionVar(void) {
- toolkit_cond_init(&_cond);
- }
- ~CConditionVar(void) {
- toolkit_cond_destroy(&_cond);
- }
- void Signal() {
- toolkit_cond_signal(&_cond);
- }
- void Broadcast() {
- toolkit_cond_broadcast(&_cond);
- }
- void Wait(toolkit_mutex_t* mutex_) {
- toolkit_cond_wait(&_cond, mutex_);
- }
- void Wait(CMutex* mutex_) {
- toolkit_cond_wait(&_cond, &(mutex_->_mutex));
- }
- bool WaitTimeout(toolkit_mutex_t* CMutex, uint64_t millisec) {
- int ret = -1;
- ret = toolkit_cond_timedwait(&_cond, CMutex, (uint64_t)(millisec * 1e6));
- return ret == 0;
- }
- bool WaitTimeout(CMutex* mutex_, uint64_t millisec) {
- int ret = -1;
- ret = toolkit_cond_timedwait(&_cond, &(mutex_->_mutex), (uint64_t)(millisec * 1e6));
- return ret == 0;
- }
- private:
- toolkit_cond_t _cond;
- };
- class CConditionVarPlus
- {
- public:
- CConditionVarPlus(void) :_active(false) {
- toolkit_mutex_init(&_mutex);
- toolkit_cond_init(&_cond);
- }
- ~CConditionVarPlus(void) {
- toolkit_cond_destroy(&_cond);
- toolkit_mutex_destroy(&_mutex);
- }
- void Signal() {
- //it is usually considered a best practice to perform
- //the "signal"/"Signal" operation before releasing CMutex m
- if (!_active) {
- uint8_t times_ = 0;
- while (!_active && times_ < 3) {
- Sleep(100);
- times_++;
- }
- }
- toolkit_mutex_lock(&_mutex);
- toolkit_cond_signal(&_cond);
- _active = false;
- toolkit_mutex_unlock(&_mutex);
- }
- void Broadcast() {
- if (!_active) {
- uint8_t times_ = 0;
- while (!_active && times_ < 3) {
- Sleep(100);
- times_++;
- }
- }
- toolkit_mutex_lock(&_mutex);
- toolkit_cond_broadcast(&_cond);
- _active = false;
- toolkit_mutex_unlock(&_mutex);
- }
- void Wait() {
- ASSERT(_active == false);
- toolkit_mutex_lock(&_mutex);
- _active = true;
- toolkit_cond_wait(&_cond, &_mutex);
- toolkit_mutex_unlock(&_mutex);
- }
- bool WaitTimeout(uint64_t millisec) {
- int ret = -1;
- ASSERT(_active == false);
- toolkit_mutex_lock(&_mutex);
- _active = true;
- ret = toolkit_cond_timedwait(&_cond, &_mutex, (uint64_t)(millisec * 1e6));
- toolkit_mutex_unlock(&_mutex);
- return ret == 0;
- }
- int TryWaitTimeout(uint64_t millisec) {
- int ret;
- if (0 == toolkit_mutex_trylock(&_mutex)) {
- _active = true;
- ret = toolkit_cond_timedwait(&_cond, &_mutex, (uint64_t)(millisec * 1e6));
- if (ret == TOOLKIT_ETIMEDOUT) {
- ret = Error_TimeOut;
- _active = false;
- }
- toolkit_mutex_unlock(&_mutex);
- }
- else {
- ret = Error_Duplication;
- }
- return ret;
- }
- private:
- toolkit_mutex_t _mutex;
- toolkit_cond_t _cond;
- bool _active;
- };
- class CSemaphore
- {
- public:
- CSemaphore(void)
- {
- toolkit_sem_init(&_sem, 0);
- }
- explicit CSemaphore(int init_value)
- {
- toolkit_sem_init(&_sem, init_value);
- }
- virtual ~CSemaphore()
- {
- toolkit_sem_destroy(&_sem);
- }
- void Signal()
- {
- toolkit_sem_post(&_sem);
- }
- void Wait()
- {
- toolkit_sem_wait(&_sem);
- }
- bool TryWait()
- {
- return toolkit_sem_trywait(&_sem) == 0;
- }
- private:
- toolkit_sem_t _sem;
- };
- }
- }
- #endif //_SP_UTILITIES_H__
|