#include #include #include #include namespace a8 { std::string Bin2Hex(const std::string& binstr) { std::string result; for(unsigned int i = 0; i < binstr.size(); i++){ assert(false); } return result; } const char* GetValidStr1(const char* szLine, char **pp, int& iLen, const char* szIngore) { //skip ingorechars *pp = (char*)szLine; while(*pp && **pp && strchr(szIngore, **pp)) (*pp)++; //read validchars iLen = 0; while((*pp + iLen) && *(*pp + iLen) && !strchr(szIngore, *(*pp + iLen++))) ; if (!strchr(szIngore, *(*pp + iLen))){ iLen--; } return *pp + iLen ; } std::string GetValidStr(const std::string& strLine, std::string& strVal, const char* szIngore) { char *pp = NULL; int iLen = 0; const char *result = a8::GetValidStr1(strLine.c_str(), &pp, iLen, szIngore); strVal.assign(pp, iLen); return result ? std::string(result) : ""; } std::string Trim(const std::string& str) { std::string text = str; if(!text.empty()){ text.erase(0, text.find_first_not_of(" \n\r\t")); text.erase(text.find_last_not_of(" \n\r\t") + 1); } return text; } std::string FormatEx(const char* fmt, std::initializer_list& args) { std::string result; result.reserve(1024); const char *p = fmt; auto itr = args.begin(); while(*p){ if(*p == '%' && *(p+1)){ p++; switch(*p){ case 'd': assert(itr != args.end()); result.append(itr->GetString().c_str()); itr++; break; case 'f': assert(itr != args.end()); result.append(itr->GetString().c_str()); itr++; break; case 's': assert(itr != args.end()); result.append(itr->GetString().c_str()); itr++; break; default:{ result.push_back('%'); result.push_back(*p); } } }else{ result.push_back(*p); } p++; } return result; } std::string Format(const char* fmt, std::initializer_list args) { return a8::FormatEx(fmt, args); } std::string FormatEx2(const char* fmt, std::vector& args) { std::string result; result.reserve(1024); const char *p = fmt; auto itr = args.begin(); while(*p){ if(*p == '%' && *(p+1)){ p++; switch(*p){ case 'd': assert(itr != args.end()); result.append(itr->GetString().c_str()); itr++; break; case 'f': assert(itr != args.end()); result.append(itr->GetString().c_str()); itr++; break; case 's': assert(itr != args.end()); result.append(itr->GetString().c_str()); itr++; break; default:{ result.push_back('%'); result.push_back(*p); } } }else{ result.push_back(*p); } p++; } return result; } std::string Format2(const char* fmt, std::vector args) { return a8::FormatEx2(fmt, args); } void Split(const std::string& str, std::vector& list, char separator) { const char *p = str.c_str(); const char *pv = p; while(*p){ if(*p == separator){ if(p > pv){ list.push_back(std::string(pv, p - pv)); }else{ list.push_back(""); } pv = p + 1; } p++; } if(*p == separator){ list.push_back(""); }else if(p > pv){ list.push_back(std::string(pv, p - pv)); } } unsigned char FromHex(unsigned char x) { return isdigit(x) ? x-'0' : x-'A'+10; } unsigned char ToHex(unsigned char x) { return x > 9 ? x + 55 : x + 48; } std::string HexEncode(const std::string& str) { std::string strTemp; strTemp.reserve(str.size() * 2); for (unsigned int i = 0; i < str.size(); i++) { char buf[3] = {'\0'}; sprintf(buf, "%x", (int)str[i]); strTemp += std::string(strTemp); } return strTemp; } bool HexDecode(const std::string& str, std::string& outstr) { for (unsigned int i = 0; i + 1 < str.size(); i += 2) { int int_c = 0; char buf[3] = {str[i], str[i + 1], '\0'}; sscanf(buf, "%x", &int_c); outstr.push_back((char)int_c); } return str.size() % 2 == 0; } std::string UrlEncode(const std::string& str) { std::string strTemp = ""; size_t length = str.length(); for (size_t i = 0; i < length; i++) { if (isalnum((unsigned char)str[i]) || (str[i] == '-') || (str[i] == '_') || (str[i] == '.') || (str[i] == '~')) { strTemp += str[i]; } else if (str[i] == ' ') { strTemp += "+"; } else { strTemp += '%'; strTemp += ToHex((unsigned char)str[i] >> 4); strTemp += ToHex((unsigned char)str[i] % 16); } } return strTemp; } std::string UrlDecode(const std::string &sIn) { std::string sOut; for(unsigned int i = 0; i < sIn.size(); i++ ){ unsigned char ch = 0; if(sIn[i] == '%'){ ch = (a8::FromHex(sIn[i + 1]) << 4); ch |= a8::FromHex(sIn[i + 2]); i += 2; }else if(sIn[i] == '+'){ ch = ' '; } else{ ch = sIn[i]; } sOut += (char)ch; } return sOut; } void ParserQueryStr(char* buf, std::string& url, std::string& querystr) { char *p_query_start = strstr(buf, "?"); if (p_query_start) { url.assign(buf, p_query_start - buf); p_query_start++; char *p_query_end = strstr(p_query_start, " "); if (p_query_end) { querystr.assign(p_query_start, p_query_end - p_query_start); } else { querystr.assign(p_query_start); } } else { p_query_start = buf; char *p_end = strstr(p_query_start, " "); if (p_end) { url.assign(p_query_start, p_end - p_query_start); } else { url.assign(p_query_start); } } } void ParserUrlQueryString(const char* querystring, std::map& query) { if(!querystring || *querystring == 0){ return; } std::vector params; a8::Split(std::string(querystring), params, '&'); for(unsigned int i = 0; i < params.size(); i++){ int pos = params[i].find('='); if(pos > 0){ std::string key = params[i].substr(0, pos); std::string val = params[i].substr(pos + 1, params[i].size() - pos); val = a8::UrlDecode(val); // query[key] = a8::XValue(val); query.insert(std::pair(key, a8::XValue(val))); } } } void ReplaceString(std::string& basestr, const std::string& srcstr, const std::string& deststr) { std::string::size_type pos = 0; std::string::size_type srcLen = srcstr.size(); std::string::size_type desLen = deststr.size(); pos = basestr.find(srcstr, pos); while((pos != std::string::npos)){ basestr.replace(pos, srcLen, deststr); pos = basestr.find(srcstr, (pos + desLen)); } } std::string HttpResponse(const std::string& content) { return HttpResponse(200, content); } std::string HttpResponse(int code, const std::string& content) { std::string response = a8::Format( "HTTP/1.1 %d OK\r\n" "Connection: close\r\n" "Content-Type: text/plain\r\n" "Content-Length: %d\r\n\r\n%s", { code, content.size(), content }); return response; } std::string JsonEscapeString(const std::string& str) { std::string result; result.reserve(str.size() * 2); const char* p = str.data(); while(*p){ if(*p >=0 && *p < ' '){ switch(*p){ case '\b': result.append("\\b"); break; case '\t': result.append("\\t"); break; case '\n': result.append("\\n"); break; case '\f': result.append("\\f"); break; case '\r': result.append("\\r"); break; default: { char unicodehex[6] = {'\\', 'u', '0', '0', '0', '0'}; char *pu = &unicodehex[5]; int n = *p; do{ *pu-- = "0123456789abcdef"[n % 16]; n /= 16; }while(n); result.append(unicodehex); } } }else if (*p == '"'){ result.append("\\\""); }else if (*p == '\\'){ result.append("\\\\"); }else{ result.push_back(*p); }//end if p++; } return result; } std::string IntToFixedString(int val, int n) { if (n < 1 || n > 10) { abort(); } char buf_fmt[20]; sprintf(buf_fmt, "%%%dd", n); char buf[20]; sprintf(buf, buf_fmt, val); std::string result = std::string((char*)buf); a8::ReplaceString(result, " ", "0"); return result; } bool ReadStringFromFile(const std::string& filename, std::string& data) { FILE *fp = fopen(filename.c_str(), "rb"); if (!fp) { return false; } fseek(fp, 0, SEEK_END); int fileSize = ftell(fp); if(fileSize){ char *p = (char*)malloc(fileSize + 1); if(p){ *(p + fileSize) = '\0'; fseek(fp, 0, SEEK_SET); fread(p, 1, fileSize, fp); if (fileSize > 0) { data.append(p, fileSize); } free(p); } } fclose(fp); return true; } int SafeStrCmp(const char* s1, const char* s2) { return strcmp(s1 ? s1 : "", s2 ? s2 : ""); } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #pragma GCC diagnostic ignored "-Wunused-but-set-variable" size_t GetUtf8Length(const char *str) { static unsigned char utf8_look_for_table[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1 }; #define UTFLEN(x) utf8_look_for_table[(x)] auto utf8_char_len = [] (char firstByte) -> int { const unsigned char kFirstBitMask = 128; // 1000000 const unsigned char kSecondBitMask = 64; // 0100000 const unsigned char kThirdBitMask = 32; // 0010000 const unsigned char kFourthBitMask = 16; // 0001000 const unsigned char kFifthBitMask = 8; // 0000100 std::string::difference_type offset = 1; if (firstByte & kFirstBitMask) { // This means the first byte has a value greater than 127, and so is beyond the ASCII range. if (firstByte & kThirdBitMask) { // This means that the first byte has a value greater than 224, and so it must be at least a three-octet code point. if (firstByte & kFourthBitMask) { // This means that the first byte has a value greater than 240, and so it must be a four-octet code point. offset = 4; }else{ offset = 3; } }else{ offset = 2; } } return offset; }; int clen = strlen(str); int len = 0; for (const char *ptr = str; *ptr!=0&&len