/** @file JCCommonMethed.cpp @brief @author James @version 1.0 @date 2016_5_12 */ #include #include #include #include "JCCommonMethod.h" #ifndef WEBASM #include "../util/JCLayaUrl.h" #endif #include "Log.h" #if __APPLE__ #include #include #include #elif ANDROID #include #elif WIN32 #include #include #include #pragma comment(lib,"psapi.lib") #endif #ifdef WEBASM extern "C" { double DateNow(); } #endif namespace laya { //------------------------------------------------------------------------------ int mathCeilPowerOfTwo(int x) { x--; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; x++; return x; } //------------------------------------------------------------------------------ unsigned int hexStringToInt( const char* str ) { int len = strlen(str); if(len>8) return 0; unsigned char* pCur = (unsigned char*)(str+len-1); unsigned char c = *pCur; int ret=0; int off=0; while((long)pCur>=(long)str){ if(c!=' '){ if(c>='0'&&c<='9') c=c-'0'; else if(c>='a'&&c<='f') c=c-'a'+10; else if(c>='A'&&c<='F') c=c-'A'+10; else return 0; ret+=(c<& p_pOutVector, char* p_sBuffer, char p_pSeperator) { //TODO这样会修改 p_sBuffer 需要重新写 p_pOutVector.clear(); if (p_sBuffer == NULL) return; char* pCur = p_sBuffer; p_pOutVector.push_back(pCur); for (; 0 != *pCur;) { if (p_pSeperator == *pCur) { *pCur = 0; if (0 != *(pCur + 1)) { p_pOutVector.push_back(pCur + 1); } } pCur++; } } //------------------------------------------------------------------------------ int stringToInt(const char *p_pszStr) { if (0 == p_pszStr) return 0; char *p; const char *pValue; int i; if (p_pszStr[0] == '#') { pValue = p_pszStr + 1; i = 16; } else if (p_pszStr[0] == '0' && p_pszStr[1] == 'x') { pValue = p_pszStr; i = 16; } else { pValue = p_pszStr; i = 10; } return strtol(pValue, &p, i); } //------------------------------------------------------------------------------ float stringToFloat(const char *p_pszStr) { if (0 == p_pszStr) return 0.0f; char *pendptr; return (float)strtod(p_pszStr, &pendptr); } //------------------------------------------------------------------------------ const char* getExtName(const char* p_sFileName) { std::vector vString; splitString(vString, (char*)(p_sFileName), '.'); int nSize = (int)(vString.size()); if (nSize <= 0) { return p_sFileName; } else { return vString[nSize - 1]; } } //------------------------------------------------------------------------------ std::string stringReplace(std::string & str, const std::string & strsrc, const std::string &strdst) { std::string::size_type pos = 0;//位置 std::string::size_type srclen = strsrc.size();//要替换的字符串大小 std::string::size_type dstlen = strdst.size();//目标字符串大小 while ((pos = str.find(strsrc, pos)) != std::string::npos) { str.replace(pos, srclen, strdst); pos += dstlen; } return str; } //------------------------------------------------------------------------------ int UTF8ToUnicode(unsigned char *ch, int *unicode) { unsigned char *p = NULL; int e = 0, n = 0; if ((p = ch) && unicode) { if (*p >= 0xfc) { e = (p[0] & 0x01) << 30; e |= (p[1] & 0x3f) << 24; e |= (p[2] & 0x3f) << 18; e |= (p[3] & 0x3f) << 12; e |= (p[4] & 0x3f) << 6; e |= (p[5] & 0x3f); n = 6; } else if (*p >= 0xf8) { e = (p[0] & 0x03) << 24; e |= (p[1] & 0x3f) << 18; e |= (p[2] & 0x3f) << 12; e |= (p[3] & 0x3f) << 6; e |= (p[4] & 0x3f); n = 5; } else if (*p >= 0xf0) { e = (p[0] & 0x07) << 18; e |= (p[1] & 0x3f) << 12; e |= (p[2] & 0x3f) << 6; e |= (p[3] & 0x3f); n = 4; } else if (*p >= 0xe0) { e = (p[0] & 0x0f) << 12; e |= (p[1] & 0x3f) << 6; e |= (p[2] & 0x3f); n = 3; } else if (*p >= 0xc0) { e = (p[0] & 0x1f) << 6; e |= (p[1] & 0x3f); n = 2; } else { e = p[0]; n = 1; } *unicode = e; } return n; } //------------------------------------------------------------------------------ int UTF8StrToUnicodeStr(unsigned char * utf8_str, unsigned short * unicode_str, int unicode_str_size) { int unicode = 0; int n = 0; int count = 0; unsigned char *s = NULL; unsigned short *e = NULL; s = utf8_str; e = unicode_str; if ((utf8_str) && (unicode_str)) { while (*s) { if ((n = UTF8ToUnicode(s, &unicode)) > 0) { if ((count++) >= unicode_str_size) { return count; } else { *e = (unsigned short)unicode; e++; *e = 0; s += n; } } else { return count; } } } return count; } //------------------------------------------------------------------------------ char * UnicodeToUTF8(unsigned int unicode, char *p) { char *e = p; if (!e) return NULL; if (unicode < 0x80) { *e++ = unicode; } else if (unicode < 0x800) { /* <11011111> < 000 0000 0000> */ *e++ = ((unicode >> 6) & 0x1f) | 0xc0; *e++ = (unicode & 0x3f) | 0x80; } else if (unicode < 0x10000) { /* <11101111> <0000 0000 0000 0000> */ *e++ = ((unicode >> 12) & 0x0f) | 0xe0; *e++ = ((unicode >> 6) & 0x3f) | 0x80; *e++ = (unicode & 0x3f) | 0x80; } else if (unicode < 0x200000) { /* <11110111> <0 0000 0000 0000 0000 0000> */ *e++ = ((unicode >> 18) & 0x07) | 0xf0; *e++ = ((unicode >> 12) & 0x3f) | 0x80; *e++ = ((unicode >> 6) & 0x3f) | 0x80; *e++ = (unicode & 0x3f) | 0x80; } else if (unicode < 0x4000000) { /* <11111011> <00 0000 0000 0000 0000 0000 0000> */ *e++ = ((unicode >> 24) & 0x03) | 0xf8; *e++ = ((unicode >> 18) & 0x3f) | 0x80; *e++ = ((unicode >> 12) & 0x3f) | 0x80; *e++ = ((unicode >> 6) & 0x3f) | 0x80; *e++ = (unicode & 0x3f) | 0x80; } else { /* <11111101> <0000 0000 0000 0000 0000 0000 0000 0000> */ *e++ = ((unicode >> 30) & 0x01) | 0xfc; *e++ = ((unicode >> 24) & 0x3f) | 0x80; *e++ = ((unicode >> 18) & 0x3f) | 0x80; *e++ = ((unicode >> 12) & 0x3f) | 0x80; *e++ = ((unicode >> 6) & 0x3f) | 0x80; *e++ = (unicode & 0x3f) | 0x80; } /* Return One step over the end of the utf-8 character buffer */ return e; } //------------------------------------------------------------------------------ char * UnicodeStrToUTF8Str(short * unicode_str, char * utf8_str, int utf8_str_size, int& transedUni, int& usedBuff) { int unicode = 0; transedUni = 0; unsigned short* puni = (unsigned short*)unicode_str; char* s = utf8_str; while ((unicode = (int)*puni++)) { //如果超出了。 usedBuff = s - utf8_str; if (usedBuff > utf8_str_size) { return NULL; } s = UnicodeToUTF8(unicode, s); transedUni++; } usedBuff = s - utf8_str; usedBuff += 1; //最後的0 if (usedBuff > utf8_str_size) return NULL; utf8_str[usedBuff - 1] = 0; return utf8_str; } //------------------------------------------------------------------------------ std::wstring utf8_unicode(const char* str) { int nLen = strlen(str); static unsigned short ucStr[64]; if (nLen<64) { nLen = UTF8StrToUnicodeStr((unsigned char*)str, ucStr, 64); std::wstring ret = (wchar_t*)ucStr; return ret; } else { unsigned short* pout = new unsigned short[nLen + 3]; nLen = UTF8StrToUnicodeStr((unsigned char*)str, pout, nLen + 3); std::wstring ret = (wchar_t*)pout; delete[] pout; return ret; } } //------------------------------------------------------------------------------ inline void advSep(const char*& p_pData) { while ((*p_pData == '\\' || *p_pData == '/') && *p_pData != 0) { p_pData++; } } //------------------------------------------------------------------------------ inline void advPath(const char*& p_pData) { while (*p_pData != '\\'&&*p_pData != '/'&& *p_pData != 0) { p_pData++; } } //------------------------------------------------------------------------------ bool splitPath(const char* p_pszPath, std::vector& out) { const char* pCurData = p_pszPath; while (*pCurData != 0) { advSep(pCurData); if (*pCurData == 0) break; const char* pathst = pCurData; advPath(pCurData); out.push_back(std::string().append(pathst, pCurData - pathst)); } return out.size() > 0; } //------------------------------------------------------------------------------ //TODO 没有处理..的情况 //应该不是很可靠,没有处理大小写等,临时拼凑的。 std::string normalizePath(const char* p_pszPath, bool toLowerCase, int& p_nProtocol) { #ifndef WEBASM JCUrl url; url.parse(p_pszPath); p_nProtocol = (int)url.m_nProto; if (url.m_nProto == JCUrl::file) { std::string ret = url.m_strPath + "/" + url.m_vPath[url.m_vPath.size() - 1]; if (toLowerCase) UTF8ToLowercase((char*)ret.c_str()); return ret; } std::string file = url.m_vPath.size()>0 ? url.m_vPath[url.m_vPath.size() - 1] : ""; std::string attFile = file.length()>0 ? ("/" + file) : "/"; std::string& query = url.m_Query; std::string attQuery = query.length()>0 ? (query) : ""; std::string ret = url.m_strPath + attFile; if (toLowerCase) UTF8ToLowercase((char*)ret.c_str()); ret += attQuery; return ret; /* char* pPos = strchr((char*)p_pszPath,'?'); //p_pszPath 需要是utf8编码 std::string url = p_pszPath; std::string query=""; if(pPos){ url = url.substr(0,pPos-p_pszPath); query = pPos; } if(toLowerCase) UTF8ToLowercase((char*)url.c_str()); std::string ret; std::vector paths; if(!SplitPath(url.c_str(), paths)) return ret; if( paths[0]=="http:") ret="http:/"; else if(paths[0]=="https:")ret="https:/"; else if(paths[0].length()==2&&paths[0][1]==':')ret=paths[0]; else{ ret="/"+paths[0]; }; for( int i=1,sz=paths.size(); i& p_vOut) { p_vOut.clear(); unsigned char* start = (unsigned char*)p_sBuffer.c_str(); unsigned char* end = (unsigned char*)p_sBuffer.c_str() + p_nSize; while (start < end) { if (*start < 0x80) { std::string s(""); s.append((char*)start, 1); p_vOut.push_back(s); start++; } else if (*start < 0xC0) { break; } else if (*start < 0xE0) { if (start >= end - 1) break; if ((start[1] & (0xC0)) != 0x80) { break; } std::string s(""); s.append((char*)start, 2); p_vOut.push_back(s); start += 2; } else if (*start < 0xF0) { if (start >= end - 2) break; if ((start[1] & 0xC0) != 0x80 || (start[2] & 0xC0) != 0x80) { break; } std::string s(""); s.append((char*)start, 3); p_vOut.push_back(s); start += 3; } else if (*start < 0xf8) { std::string s(""); s.append((char*)start, 4); p_vOut.push_back(s); start += 4; } else if (*start < 0xfc) { std::string s(""); s.append((char*)start, 5); p_vOut.push_back(s); start += 5; } else { //这个不知道了,不应该吧 std::string s(""); s.append((char*)start, 6); p_vOut.push_back(s); start += 6; } } } //------------------------------------------------------------------------------ char* LayaStrlwr(char* p_str) { #ifdef WIN32 return _strlwr(p_str); #else char* orig = p_str; for (; *p_str != '\0'; p_str++) *p_str = tolower(*p_str); return orig; #endif } //------------------------------------------------------------------------------ char* LayaStrupr(char* p_str) { #ifdef WIN32 return _strupr(p_str); #else char * orign = p_str; for (; *p_str != '\0'; p_str++) *p_str = toupper(*p_str); return orign; #endif } //------------------------------------------------------------------------------ char* UTF8ToLowercase(char* p_pszStr) { char* pPtr = p_pszStr; while ((*pPtr) != 0) { int v = *pPtr; if (v >= 0xfc)pPtr += 6; else if (v >= 0xf8)pPtr += 5; else if (v >= 0xf0)pPtr += 4; else if (v >= 0xe0)pPtr += 3; else if (v >= 0xc0)pPtr += 2; else { //>0x80的不用管 if (v >= 'A' && v <= 'Z') { *pPtr -= ('A' - 'a'); } pPtr += 1; } } return p_pszStr; } //------------------------------------------------------------------------------ std::string getLowercaseExtOfUrl(const char* p_pszUrl) { if (!p_pszUrl)return ""; const char* pQuery = strchr(p_pszUrl, '?'); char* pStart = (char*)(pQuery ? (pQuery - 1) : (p_pszUrl + strlen(p_pszUrl) - 1)); char* pDot = pStart; while (pDot != p_pszUrl && *pDot != '.') { pDot--; } if (pDot != p_pszUrl) { static char tmpbuf[64]; memset(tmpbuf, 0, sizeof(tmpbuf)); int extlen = pStart - pDot + 1;//算上点了 if (extlen > sizeof(tmpbuf)) { return ""; } //转成小写 memcpy(tmpbuf, pDot, extlen); for (int ci = 0; ci < extlen; ci++) { if (tmpbuf[ci] >= 'A'&&tmpbuf[ci] <= 'Z') { tmpbuf[ci] += ('a' - 'A'); } } return std::string(tmpbuf); } else return ""; } //------------------------------------------------------------------------------ unsigned char _ToHex(unsigned char x) { return x > 9 ? x + 55 : x + 48; } //------------------------------------------------------------------------------ unsigned char _FromHex(unsigned char x) { unsigned char y; if (x >= 'A' && x <= 'Z') y = x - 'A' + 10; else if (x >= 'a' && x <= 'z') y = x - 'a' + 10; else if (x >= '0' && x <= '9') y = x - '0'; else { LOGE("_FromHex error:%d", x); y = 0; } return y; } //------------------------------------------------------------------------------ std::string UrlEncode(const char* str) { std::string strTemp = ""; size_t length = strlen(str); for (size_t i = 0; i < length; i++) { if (isalnum((unsigned char)str[i]) || (str[i] == '-') || (str[i] == '_') || (str[i] == '.') || (str[i] == '~') || (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 char* str) { std::string strTemp = ""; size_t length = strlen(str); for (size_t i = 0; i < length; i++) { if (str[i] == '+') strTemp += ' '; else if (str[i] == '%') { if (i + 2 < length) { unsigned char high = _FromHex((unsigned char)str[++i]); unsigned char low = _FromHex((unsigned char)str[++i]); strTemp += high * 16 + low; } else { LOGE("UrlDecode length error:%s", str); } } else strTemp += str[i]; } return strTemp; } //------------------------------------------------------------------------------ double tmGetCurms() { #ifdef WEBASM return DateNow(); #else #ifdef __APPLE__ //下面的方法好像也可以达到精度 // struct timeval tv; // gettimeofday(&tv, NULL); // return (tv.tv_sec*1000 + tv.tv_usec/1000); //根据cpu频率获得的时间 static mach_timebase_info_data_t info; if (info.denom == 0) { if (mach_timebase_info(&info) != KERN_SUCCESS) return 0; } int64_t nanosec = mach_absolute_time()*info.numer / info.denom; return (nanosec / 1e6); #elif ANDROID struct timespec now; clock_gettime(CLOCK_MONOTONIC, &now); return now.tv_sec * 1000.0 + now.tv_nsec / 1e6; #elif WIN32 static __int64 freq = 0; if (freq == 0) { LARGE_INTEGER lifreq; QueryPerformanceFrequency(&lifreq); freq = lifreq.QuadPart; } LARGE_INTEGER tm; double ret; QueryPerformanceCounter(&tm); ret = tm.QuadPart * 1000.0 / freq; return ret;//GetTickCount(); //return ret; #else return 0; #endif #endif } int getAppUsedMem() { #ifdef WIN32 HANDLE handle = GetCurrentProcess(); PROCESS_MEMORY_COUNTERS pmc; GetProcessMemoryInfo(handle, &pmc, sizeof(pmc)); //WorkingSetSize 使用的内存 //PeakWorkingSetSize 峰值内存 //PagefileUsage 虚拟内存 //PeakPagefileUsage 峰值虚拟内存 return pmc.WorkingSetSize / 1024; #elif ANDROID return 0; #elif __APPLE__ return 0; #endif } int hashstr(const char *s) { int even, odd; int i = 0; int mask = 0x1F; int ret; even = odd = 0; while (*s != '\0') { if (i & 1) { odd ^= *s; } else { even ^= *s; } ++s; ++i; } ret = even & mask; ret <<= 5; ret += (odd & mask); return ret; } void mulMatrixArray(float* leftMatrixE, float* rightMatrix, float* outArray, int nOffset) { int i = 0; float ai0 = 0, ai1 = 0, ai2 = 0, ai3 = 0; float m11 = rightMatrix[0], m12 = rightMatrix[1], m13 = rightMatrix[2], m14 = rightMatrix[3]; float m21 = rightMatrix[4], m22 = rightMatrix[5], m23 = rightMatrix[6], m24 = rightMatrix[7]; float m31 = rightMatrix[8], m32 = rightMatrix[9], m33 = rightMatrix[10], m34 = rightMatrix[11]; float m41 = rightMatrix[12], m42 = rightMatrix[13], m43 = rightMatrix[14], m44 = rightMatrix[15]; int ai0OutOffset = nOffset; int ai1OutOffset = nOffset + 4; int ai2OutOffset = nOffset + 8; int ai3OutOffset = nOffset + 12; for (i = 0; i < 4; i++) { ai0 = leftMatrixE[i]; ai1 = leftMatrixE[i + 4]; ai2 = leftMatrixE[i + 8]; ai3 = leftMatrixE[i + 12]; outArray[ai0OutOffset + i] = ai0 * m11 + ai1 * m12 + ai2 * m13 + ai3 * m14; outArray[ai1OutOffset + i] = ai0 * m21 + ai1 * m22 + ai2 * m23 + ai3 * m24; outArray[ai2OutOffset + i] = ai0 * m31 + ai1 * m32 + ai2 * m33 + ai3 * m34; outArray[ai3OutOffset + i] = ai0 * m41 + ai1 * m42 + ai2 * m43 + ai3 * m44; } } void flipPixelsY(uint8_t* pixels, int bytesPerRow, int rows) { if (!pixels) { return; } uint32_t middle = rows / 2; uint32_t intsPerRow = bytesPerRow / sizeof(uint32_t); uint32_t remainingBytes = bytesPerRow - intsPerRow * sizeof(uint32_t); for (uint32_t rowTop = 0, rowBottom = rows - 1; rowTop < middle; rowTop++, rowBottom--) { // Swap bytes in packs of sizeof(GLuint) bytes uint32_t *iTop = (uint32_t *)(pixels + rowTop * bytesPerRow); uint32_t *iBottom = (uint32_t *)(pixels + rowBottom * bytesPerRow); uint32_t itmp; int32_t n = intsPerRow; do { itmp = *iTop; *iTop++ = *iBottom; *iBottom++ = itmp; } while (--n > 0); // Swap the remaining bytes uint8_t *bTop = (uint8_t *)iTop; uint8_t *bBottom = (uint8_t *)iBottom; uint8_t btmp; switch (remainingBytes) { case 3: btmp = *bTop; *bTop++ = *bBottom; *bBottom++ = btmp; case 2: btmp = *bTop; *bTop++ = *bBottom; *bBottom++ = btmp; case 1: btmp = *bTop; *bTop = *bBottom; *bBottom = btmp; } } } } //------------------------------------------------------------------------------ //-----------------------------END FILE--------------------------------