open source
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
/**
|
||||
@file JCColor.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2013_12_19
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "JCColor.h"
|
||||
#pragma warning (disable: 4996)
|
||||
|
||||
namespace laya
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
JCColorInt::JCColorInt( unsigned char p_nR,unsigned char p_nG,unsigned char p_nB,unsigned char p_nA )
|
||||
{
|
||||
setARGB( p_nR,p_nG,p_nB,p_nA );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColorInt::setColor( unsigned int p_nColor )
|
||||
{
|
||||
color = p_nColor;
|
||||
b=(color&255);
|
||||
g=((color>>8)&255);
|
||||
r=((color>>16)&255);
|
||||
a=((color>>24)&255);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColorInt::setARGB( unsigned char p_nR,unsigned char p_nG,unsigned char p_nB,unsigned char p_nA )
|
||||
{
|
||||
r = p_nR;
|
||||
g = p_nG;
|
||||
b = p_nB;
|
||||
a = p_nA;
|
||||
color = (a<<24) + (r<<16) + (g<<8) + b;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColorInt::setColorFromString( const char* p_sColor )
|
||||
{
|
||||
unsigned int nColor = JCColor::getColorUintFromString( p_sColor );
|
||||
setColor( nColor );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCColorFloat::JCColorFloat( float p_nR,float p_nG,float p_nB,float p_nA )
|
||||
{
|
||||
setARGB( p_nR,p_nG,p_nB,p_nA );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColorFloat::setColor( unsigned int p_nColor )
|
||||
{
|
||||
color = p_nColor;
|
||||
b=(color&255)/255.0f;
|
||||
g=((color>>8)&255)/255.0f;
|
||||
r=((color>>16)&255)/255.0f;
|
||||
a=((color>>24)&255)/255.0f;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColorFloat::setARGB( float p_nR,float p_nG,float p_nB,float p_nA )
|
||||
{
|
||||
r = p_nR;
|
||||
g = p_nG;
|
||||
b = p_nB;
|
||||
a = p_nA;
|
||||
color = ( (int)(a*255)<<24 ) + ( (int)(r*255)<<16 ) + ( (int)(g*255)<<8 ) + ( (int)(b*255) );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColorFloat::setColorFromString( const char* p_sColor )
|
||||
{
|
||||
unsigned int nColor = JCColor::getColorUintFromString( p_sColor );
|
||||
setColor( nColor );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned int JCColor::hexstrtoint( const char* str )
|
||||
{
|
||||
char szValue[32]={0};
|
||||
szValue[0]='0';
|
||||
szValue[1]='x';
|
||||
strcpy( &szValue[2],str );
|
||||
unsigned int nValude = 0;
|
||||
sscanf(szValue,"%x",&nValude);
|
||||
return nValude;
|
||||
/*
|
||||
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 << off);
|
||||
off += 4;
|
||||
}
|
||||
c = *(--pCur);
|
||||
}
|
||||
return ret;
|
||||
*/
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
int JCColor::getColorUintFromString( const char* p_sColor )
|
||||
{
|
||||
const char* pData = strchr( p_sColor,'#' );
|
||||
if( pData )
|
||||
{
|
||||
int nLen = strlen( pData );
|
||||
bool bNoAlpha = nLen < 9;
|
||||
unsigned int color= hexstrtoint( pData+1 );
|
||||
if( bNoAlpha ) color |= 0xff000000;
|
||||
return color;
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColor::getColorRGBIntFromString( const char* p_sColor,JCColorInt& p_pOutColorInit )
|
||||
{
|
||||
unsigned int nColor = getColorUintFromString( p_sColor );
|
||||
p_pOutColorInit.setColor( nColor );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColor::getColorRGBIntFromInt( int p_nColor,JCColorInt& p_pOutColorInit )
|
||||
{
|
||||
p_pOutColorInit.setColor( p_nColor );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColor::getColorRGBFloatFromString( const char* p_sColor,JCColorFloat& p_pOutColorFloat )
|
||||
{
|
||||
unsigned int nColor = getColorUintFromString( p_sColor );
|
||||
p_pOutColorFloat.setColor( nColor );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCColor::getColorRGBFloatFromInt( int p_nColor,JCColorFloat& p_pOutColorFloat )
|
||||
{
|
||||
p_pOutColorFloat.setColor( p_nColor );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
@file JCColor.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2013_12_19
|
||||
*/
|
||||
|
||||
#ifndef __JCColor_H__
|
||||
#define __JCColor_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
|
||||
#define EXTRACT_COLOR_R(color) ((color & 0xff) / 255.0f)
|
||||
#define EXTRACT_COLOR_G(color) (((color >> 8) & 0xff) / 255.0f)
|
||||
#define EXTRACT_COLOR_B(color) (((color >> 16) & 0xff) / 255.0f)
|
||||
#define EXTRACT_COLOR_A(color) (((color >> 24) & 0xff) / 255.0f)
|
||||
|
||||
namespace laya
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
class JCColorInt
|
||||
{
|
||||
public:
|
||||
|
||||
JCColorInt( unsigned char p_nR=0,unsigned char p_nG=0,unsigned char p_nB=0,unsigned char p_nA=0 );
|
||||
|
||||
void setColor( unsigned int p_nColor );
|
||||
|
||||
void setARGB( unsigned char p_nR,unsigned char p_nG,unsigned char p_nB,unsigned char p_nA );
|
||||
|
||||
void setColorFromString( const char* p_sColor );
|
||||
|
||||
public:
|
||||
|
||||
unsigned int color;
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
class JCColorFloat
|
||||
{
|
||||
public:
|
||||
|
||||
JCColorFloat( float p_nR=0.0f,float p_nG=0.0f,float p_nB=0.0f,float p_nA=0.0f );
|
||||
|
||||
void setColor( unsigned int p_nColor );
|
||||
|
||||
void setARGB( float p_nR,float p_nG,float p_nB,float p_nA );
|
||||
|
||||
void setColorFromString( const char* p_sColor );
|
||||
|
||||
public:
|
||||
|
||||
unsigned int color;
|
||||
float r;
|
||||
float g;
|
||||
float b;
|
||||
float a;
|
||||
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
class JCColor
|
||||
{
|
||||
public:
|
||||
|
||||
//str没有0x,直接是数字,例如"a0"
|
||||
static unsigned int hexstrtoint(const char* str);
|
||||
|
||||
static int getColorUintFromString( const char* p_sColor );
|
||||
|
||||
static void getColorRGBIntFromString( const char* p_sColor,JCColorInt& p_pOutColorInit );
|
||||
|
||||
static void getColorRGBIntFromInt( int p_nColor,JCColorInt& p_pOutColorInit );
|
||||
|
||||
static void getColorRGBFloatFromString( const char* p_sColor,JCColorFloat& p_pOutColorFloat );
|
||||
|
||||
static void getColorRGBFloatFromInt( int p_nColor,JCColorFloat& p_pOutColorFloat );
|
||||
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
#endif //__JCColor_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,785 @@
|
||||
/**
|
||||
@file JCCommonMethed.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "JCCommonMethod.h"
|
||||
#ifndef WEBASM
|
||||
#include "../util/JCLayaUrl.h"
|
||||
#endif
|
||||
#include "Log.h"
|
||||
|
||||
#if __APPLE__
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <mach/mach_time.h>
|
||||
#elif ANDROID
|
||||
#include <time.h>
|
||||
#elif WIN32
|
||||
#include <windows.h>
|
||||
#include <psapi.h>
|
||||
#include <iostream>
|
||||
#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<<off);
|
||||
off+=4;
|
||||
}
|
||||
c=*(--pCur);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void splitString(std::vector<char*>& 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<char*> 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<std::string>& 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<std::string> 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<sz; i++){
|
||||
ret=ret+"/"+paths[i];
|
||||
}
|
||||
return ret+query;
|
||||
*/
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void paserUTF8(std::string p_sBuffer, long p_nSize, std::vector<std::string>& 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--------------------------------
|
||||
@@ -0,0 +1,189 @@
|
||||
|
||||
/**
|
||||
@file JCCommonMethod.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#ifndef __JCCommonMethod_H__
|
||||
#define __JCCommonMethod_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#define MAX_CHARACTER_SIZE 8
|
||||
|
||||
namespace laya
|
||||
{
|
||||
#define PI 3.1415926535897932f
|
||||
#define ARC_TO_RAD 0.0174532925199433f
|
||||
|
||||
/** @brief 转成2的N次方
|
||||
* @param[in] 输入的值
|
||||
* @return 返回2的n次方
|
||||
*/
|
||||
int mathCeilPowerOfTwo(int x);
|
||||
|
||||
/** @brief 把字符串转换成int
|
||||
* @param[in] 字符串 "#ff00ff"
|
||||
* @return
|
||||
*/
|
||||
unsigned int hexStringToInt( const char* str );
|
||||
|
||||
/** @brief 分割字符串
|
||||
* @param[out] 返回到verctor中
|
||||
* @param[in] 字符串
|
||||
* @param[in] 哪个字符分割
|
||||
*/
|
||||
void splitString(std::vector<char*>& p_vOutVector, char* p_sBuffer, char p_pSeperator);
|
||||
|
||||
/** @brief string转换成int
|
||||
* @param[in] 字符串
|
||||
* @return 返回int值
|
||||
*/
|
||||
int stringToInt(const char *p_pszStr);
|
||||
|
||||
/** @brief string转换成float
|
||||
* @param[in] 字符串
|
||||
* @return 返回float值
|
||||
*/
|
||||
float stringToFloat(const char *p_pszStr);
|
||||
|
||||
/** @brief 返回文件的扩展名字
|
||||
* @param[in] 文件名字
|
||||
* @return 返回扩展名
|
||||
*/
|
||||
const char* getExtName(const char* p_sFileName);
|
||||
|
||||
/** @brief 替换字符串
|
||||
*/
|
||||
std::string stringReplace(std::string & str, const std::string & strsrc, const std::string &strdst);
|
||||
|
||||
/** @brief UTF8转unicode
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @return
|
||||
*/
|
||||
int UTF8ToUnicode(unsigned char *ch, int *unicode);
|
||||
|
||||
/** @brief 把utf8的字符串转成unicode的字符串。
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @return 转换后的字符的个数
|
||||
*/
|
||||
int UTF8StrToUnicodeStr(unsigned char * utf8_str, unsigned short * unicode_str, int unicode_str_size);
|
||||
|
||||
/** @brief 把一个unicode的字符拷贝到p中(不管16还是32),会在p中前进,返回当前位置(下一个位置)。
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @return 返回当前位置(下一个位置)。
|
||||
*/
|
||||
char* UnicodeToUTF8(unsigned int unicode, char *p);
|
||||
|
||||
/** @brief utf8_str_size 是提供的buffer的大小。如果空间不足,则返回NULL。 transedNum 为实际转换了多少个unicode字符。
|
||||
* usedBuff是使用了多少空间,如果转换成功了,最后会有一个0
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @return 如果空间不足,则返回NULL
|
||||
*/
|
||||
char* UnicodeStrToUTF8Str(short * unicode_str, char * utf8_str, int utf8_str_size, int& transedUni, int& usedBuff);
|
||||
|
||||
/** @brief utf8 to unicode
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @param[out]
|
||||
* @return
|
||||
*/
|
||||
std::wstring utf8_unicode(const char* str);
|
||||
|
||||
/** @brief 分割路径
|
||||
* @param[in] 文件名字
|
||||
* @param[in] 返回vertor
|
||||
* @return 是否成功
|
||||
*/
|
||||
bool splitPath(const char* p_pszPath, std::vector<std::string>& out);
|
||||
|
||||
/** @brief nomailizePath
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @param[out]
|
||||
* @return
|
||||
*/
|
||||
std::string normalizePath(const char* p_pszPath, bool toLowerCase, int& p_nProtocol);
|
||||
|
||||
/** @brief paserUTF8
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @return
|
||||
*/
|
||||
void paserUTF8(std::string p_sBuffer, long p_nSize, std::vector<std::string>& p_vOut);
|
||||
|
||||
/** @brief 字符串转小写
|
||||
* @param[in] 字符串
|
||||
* @return 转换后的字符串
|
||||
*/
|
||||
char* LayaStrlwr(char* p_str);
|
||||
|
||||
/** @brief 字符串转大写
|
||||
* @param[in] 字符串
|
||||
* @return 转换后的字符串
|
||||
*/
|
||||
char* LayaStrupr(char* p_str);
|
||||
|
||||
/** @brief 把一个字符串转为小写。直接修改字符串. 如果是utf8的则没问题。否则不要调用这个。
|
||||
* @param[in] 字符串
|
||||
* @return 转换后的字符串
|
||||
*/
|
||||
char* UTF8ToLowercase(char* p_pszStr);
|
||||
|
||||
/** @brief 得到一个url的转为小写的扩展名
|
||||
* @param[in] 输入的url
|
||||
* @return 返回扩展名
|
||||
*/
|
||||
std::string getLowercaseExtOfUrl(const char* p_pszUrl);
|
||||
|
||||
/** @brief UrlEncode
|
||||
* @param[in] 输入的字符串
|
||||
* @return 返回的字符串
|
||||
*/
|
||||
std::string UrlEncode(const char* str);
|
||||
|
||||
/** @brief UrlDecode
|
||||
* @param[in] 输入的字符串
|
||||
* @return 返回的字符串
|
||||
*/
|
||||
std::string UrlDecode(const char* str);
|
||||
|
||||
|
||||
/** @brief 获得当前时间
|
||||
* @return 返回当前时间
|
||||
*/
|
||||
double tmGetCurms();
|
||||
|
||||
|
||||
/** @brief 获得app使用的内存
|
||||
* @return 返回内存值
|
||||
*/
|
||||
int getAppUsedMem();
|
||||
|
||||
int hashstr(const char *s);
|
||||
|
||||
void mulMatrixArray(float* leftMatrixE, float* rightMatrix, float* outArray, int nOffset);
|
||||
|
||||
void flipPixelsY(uint8_t* pixels, int bytesPerRow, int rows);
|
||||
|
||||
bool IsTextUTF8(char* str, unsigned long length);
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCCommonMethod_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
|
||||
@@ -0,0 +1,742 @@
|
||||
/**
|
||||
@file JCCrypto.cpp
|
||||
@brief
|
||||
@author hugao
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#include "JCCrypto.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
unsigned char decodeGetByte(char c);
|
||||
char encodeGetChar(unsigned char num);
|
||||
|
||||
unsigned char decodeGetByte(char c)
|
||||
{
|
||||
if (c == '+')
|
||||
return 62;
|
||||
else if (c == '/')
|
||||
return 63;
|
||||
else if (c <= '9')
|
||||
return (unsigned char)(c - '0' + 52);
|
||||
else if (c == '=')
|
||||
return 64;
|
||||
else if (c <= 'Z')
|
||||
return (unsigned char)(c - 'A');
|
||||
else if (c <= 'z')
|
||||
return (unsigned char)(c - 'a' + 26);
|
||||
return 64;
|
||||
}
|
||||
unsigned int encodeGetChar(char *pDest, const char *pSrc, unsigned int srclen)
|
||||
{
|
||||
unsigned char input[4];
|
||||
unsigned int i, index = 0;
|
||||
for (i = 0; i < srclen; i += 4)
|
||||
{
|
||||
//byte[0]
|
||||
input[0] = decodeGetByte(pSrc[i]);
|
||||
input[1] = decodeGetByte(pSrc[i + 1]);
|
||||
pDest[index++] = (input[0] << 2) + (input[1] >> 4);
|
||||
|
||||
//byte[1]
|
||||
if (pSrc[i + 2] != '=')
|
||||
{
|
||||
input[2] = decodeGetByte(pSrc[i + 2]);
|
||||
pDest[index++] = ((input[1] & 0x0f) << 4) + (input[2] >> 2);
|
||||
}
|
||||
|
||||
//byte[2]
|
||||
if (pSrc[i + 3] != '=')
|
||||
{
|
||||
input[3] = decodeGetByte(pSrc[i + 3]);
|
||||
pDest[index++] = ((input[2] & 0x03) << 6) + (input[3]);
|
||||
}
|
||||
}
|
||||
|
||||
//null-terminator
|
||||
pDest[index] = 0;
|
||||
return index;
|
||||
}
|
||||
inline char encodeGetChar(unsigned char num)
|
||||
{
|
||||
return
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789"
|
||||
"+/="[num];
|
||||
}
|
||||
unsigned int base64Encode(char *pDest, const char *pSrc, unsigned int srclen)
|
||||
{
|
||||
unsigned char input[3], output[4];
|
||||
unsigned int i, index_src = 0, index_dest = 0;
|
||||
for (i = 0; i < srclen; i += 3)
|
||||
{
|
||||
//char [0]
|
||||
input[0] = pSrc[index_src++];
|
||||
output[0] = (unsigned char)(input[0] >> 2);
|
||||
pDest[index_dest++] = encodeGetChar(output[0]);
|
||||
|
||||
//char [1]
|
||||
if (index_src < srclen)
|
||||
{
|
||||
input[1] = pSrc[index_src++];
|
||||
output[1] = (unsigned char)(((input[0] & 0x03) << 4) + (input[1] >> 4));
|
||||
pDest[index_dest++] = encodeGetChar(output[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
output[1] = (unsigned char)((input[0] & 0x03) << 4);
|
||||
pDest[index_dest++] = encodeGetChar(output[1]);
|
||||
pDest[index_dest++] = '=';
|
||||
pDest[index_dest++] = '=';
|
||||
break;
|
||||
}
|
||||
|
||||
//char [2]
|
||||
if (index_src < srclen)
|
||||
{
|
||||
input[2] = pSrc[index_src++];
|
||||
output[2] = (unsigned char)(((input[1] & 0x0f) << 2) + (input[2] >> 6));
|
||||
pDest[index_dest++] = encodeGetChar(output[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
output[2] = (unsigned char)((input[1] & 0x0f) << 2);
|
||||
pDest[index_dest++] = encodeGetChar(output[2]);
|
||||
pDest[index_dest++] = '=';
|
||||
break;
|
||||
}
|
||||
|
||||
//char [3]
|
||||
output[3] = (unsigned char)(input[2] & 0x3f);
|
||||
pDest[index_dest++] = encodeGetChar(output[3]);
|
||||
}
|
||||
//null-terminator
|
||||
pDest[index_dest] = 0;
|
||||
return index_dest;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#define GET_UINT32(n,b,i) \
|
||||
{ \
|
||||
(n) = (unsigned int) ((unsigned char *) b)[(i)] \
|
||||
| (((unsigned int) ((unsigned char *) b)[(i)+1]) << 8) \
|
||||
| (((unsigned int) ((unsigned char *) b)[(i)+2]) << 16) \
|
||||
| (((unsigned int) ((unsigned char *) b)[(i)+3]) << 24); \
|
||||
}
|
||||
|
||||
#define PUT_UINT32(n,b,i) \
|
||||
{ \
|
||||
(((unsigned char *) b)[(i)] ) = (unsigned char) (((n) ) & 0xFF); \
|
||||
(((unsigned char *) b)[(i)+1]) = (unsigned char) (((n) >> 8) & 0xFF); \
|
||||
(((unsigned char *) b)[(i)+2]) = (unsigned char) (((n) >> 16) & 0xFF); \
|
||||
(((unsigned char *) b)[(i)+3]) = (unsigned char) (((n) >> 24) & 0xFF); \
|
||||
}
|
||||
#ifndef WEBASM
|
||||
void JCMD5::md5_starts(struct md5_context *ctx)
|
||||
{
|
||||
ctx->total[0] = 0;
|
||||
ctx->total[1] = 0;
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xEFCDAB89;
|
||||
ctx->state[2] = 0x98BADCFE;
|
||||
ctx->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
void JCMD5::md5_process(struct md5_context *ctx, unsigned char data[64])
|
||||
{
|
||||
unsigned int A, B, C, D, X[16];
|
||||
|
||||
GET_UINT32(X[0], data, 0);
|
||||
GET_UINT32(X[1], data, 4);
|
||||
GET_UINT32(X[2], data, 8);
|
||||
GET_UINT32(X[3], data, 12);
|
||||
GET_UINT32(X[4], data, 16);
|
||||
GET_UINT32(X[5], data, 20);
|
||||
GET_UINT32(X[6], data, 24);
|
||||
GET_UINT32(X[7], data, 28);
|
||||
GET_UINT32(X[8], data, 32);
|
||||
GET_UINT32(X[9], data, 36);
|
||||
GET_UINT32(X[10], data, 40);
|
||||
GET_UINT32(X[11], data, 44);
|
||||
GET_UINT32(X[12], data, 48);
|
||||
GET_UINT32(X[13], data, 52);
|
||||
GET_UINT32(X[14], data, 56);
|
||||
GET_UINT32(X[15], data, 60);
|
||||
|
||||
#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
|
||||
|
||||
#define P(a,b,c,d,k,s,t) \
|
||||
{ \
|
||||
a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
|
||||
}
|
||||
|
||||
A = ctx->state[0];
|
||||
B = ctx->state[1];
|
||||
C = ctx->state[2];
|
||||
D = ctx->state[3];
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
|
||||
P(A, B, C, D, 0, 7, 0xD76AA478);
|
||||
P(D, A, B, C, 1, 12, 0xE8C7B756);
|
||||
P(C, D, A, B, 2, 17, 0x242070DB);
|
||||
P(B, C, D, A, 3, 22, 0xC1BDCEEE);
|
||||
P(A, B, C, D, 4, 7, 0xF57C0FAF);
|
||||
P(D, A, B, C, 5, 12, 0x4787C62A);
|
||||
P(C, D, A, B, 6, 17, 0xA8304613);
|
||||
P(B, C, D, A, 7, 22, 0xFD469501);
|
||||
P(A, B, C, D, 8, 7, 0x698098D8);
|
||||
P(D, A, B, C, 9, 12, 0x8B44F7AF);
|
||||
P(C, D, A, B, 10, 17, 0xFFFF5BB1);
|
||||
P(B, C, D, A, 11, 22, 0x895CD7BE);
|
||||
P(A, B, C, D, 12, 7, 0x6B901122);
|
||||
P(D, A, B, C, 13, 12, 0xFD987193);
|
||||
P(C, D, A, B, 14, 17, 0xA679438E);
|
||||
P(B, C, D, A, 15, 22, 0x49B40821);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (y ^ (z & (x ^ y)))
|
||||
|
||||
P(A, B, C, D, 1, 5, 0xF61E2562);
|
||||
P(D, A, B, C, 6, 9, 0xC040B340);
|
||||
P(C, D, A, B, 11, 14, 0x265E5A51);
|
||||
P(B, C, D, A, 0, 20, 0xE9B6C7AA);
|
||||
P(A, B, C, D, 5, 5, 0xD62F105D);
|
||||
P(D, A, B, C, 10, 9, 0x02441453);
|
||||
P(C, D, A, B, 15, 14, 0xD8A1E681);
|
||||
P(B, C, D, A, 4, 20, 0xE7D3FBC8);
|
||||
P(A, B, C, D, 9, 5, 0x21E1CDE6);
|
||||
P(D, A, B, C, 14, 9, 0xC33707D6);
|
||||
P(C, D, A, B, 3, 14, 0xF4D50D87);
|
||||
P(B, C, D, A, 8, 20, 0x455A14ED);
|
||||
P(A, B, C, D, 13, 5, 0xA9E3E905);
|
||||
P(D, A, B, C, 2, 9, 0xFCEFA3F8);
|
||||
P(C, D, A, B, 7, 14, 0x676F02D9);
|
||||
P(B, C, D, A, 12, 20, 0x8D2A4C8A);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (x ^ y ^ z)
|
||||
|
||||
P(A, B, C, D, 5, 4, 0xFFFA3942);
|
||||
P(D, A, B, C, 8, 11, 0x8771F681);
|
||||
P(C, D, A, B, 11, 16, 0x6D9D6122);
|
||||
P(B, C, D, A, 14, 23, 0xFDE5380C);
|
||||
P(A, B, C, D, 1, 4, 0xA4BEEA44);
|
||||
P(D, A, B, C, 4, 11, 0x4BDECFA9);
|
||||
P(C, D, A, B, 7, 16, 0xF6BB4B60);
|
||||
P(B, C, D, A, 10, 23, 0xBEBFBC70);
|
||||
P(A, B, C, D, 13, 4, 0x289B7EC6);
|
||||
P(D, A, B, C, 0, 11, 0xEAA127FA);
|
||||
P(C, D, A, B, 3, 16, 0xD4EF3085);
|
||||
P(B, C, D, A, 6, 23, 0x04881D05);
|
||||
P(A, B, C, D, 9, 4, 0xD9D4D039);
|
||||
P(D, A, B, C, 12, 11, 0xE6DB99E5);
|
||||
P(C, D, A, B, 15, 16, 0x1FA27CF8);
|
||||
P(B, C, D, A, 2, 23, 0xC4AC5665);
|
||||
|
||||
#undef F
|
||||
|
||||
#define F(x,y,z) (y ^ (x | ~z))
|
||||
|
||||
P(A, B, C, D, 0, 6, 0xF4292244);
|
||||
P(D, A, B, C, 7, 10, 0x432AFF97);
|
||||
P(C, D, A, B, 14, 15, 0xAB9423A7);
|
||||
P(B, C, D, A, 5, 21, 0xFC93A039);
|
||||
P(A, B, C, D, 12, 6, 0x655B59C3);
|
||||
P(D, A, B, C, 3, 10, 0x8F0CCC92);
|
||||
P(C, D, A, B, 10, 15, 0xFFEFF47D);
|
||||
P(B, C, D, A, 1, 21, 0x85845DD1);
|
||||
P(A, B, C, D, 8, 6, 0x6FA87E4F);
|
||||
P(D, A, B, C, 15, 10, 0xFE2CE6E0);
|
||||
P(C, D, A, B, 6, 15, 0xA3014314);
|
||||
P(B, C, D, A, 13, 21, 0x4E0811A1);
|
||||
P(A, B, C, D, 4, 6, 0xF7537E82);
|
||||
P(D, A, B, C, 11, 10, 0xBD3AF235);
|
||||
P(C, D, A, B, 2, 15, 0x2AD7D2BB);
|
||||
P(B, C, D, A, 9, 21, 0xEB86D391);
|
||||
|
||||
#undef F
|
||||
|
||||
ctx->state[0] += A;
|
||||
ctx->state[1] += B;
|
||||
ctx->state[2] += C;
|
||||
ctx->state[3] += D;
|
||||
}
|
||||
|
||||
void JCMD5::md5_update(struct md5_context *ctx, unsigned char *input, size_t length)
|
||||
{
|
||||
unsigned int left, fill;
|
||||
|
||||
if (!length) return;
|
||||
|
||||
left = (ctx->total[0] >> 3) & 0x3F;
|
||||
fill = 64 - left;
|
||||
|
||||
ctx->total[0] += length << 3;
|
||||
ctx->total[1] += length >> 29;
|
||||
|
||||
ctx->total[0] &= 0xFFFFFFFF;
|
||||
ctx->total[1] += ctx->total[0] < length << 3;
|
||||
|
||||
if (left && length >= fill)
|
||||
{
|
||||
memcpy((void *)(ctx->buffer + left), (void *)input, fill);
|
||||
md5_process(ctx, ctx->buffer);
|
||||
length -= fill;
|
||||
input += fill;
|
||||
left = 0;
|
||||
}
|
||||
|
||||
while (length >= 64)
|
||||
{
|
||||
md5_process(ctx, input);
|
||||
length -= 64;
|
||||
input += 64;
|
||||
}
|
||||
|
||||
if (length)
|
||||
{
|
||||
memcpy((void *)(ctx->buffer + left), (void *)input, length);
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char md5_padding[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
void JCMD5::md5_finish(struct md5_context *ctx, unsigned char digest[16])
|
||||
{
|
||||
unsigned int last, padn;
|
||||
unsigned char msglen[8];
|
||||
|
||||
PUT_UINT32(ctx->total[0], msglen, 0);
|
||||
PUT_UINT32(ctx->total[1], msglen, 4);
|
||||
|
||||
last = (ctx->total[0] >> 3) & 0x3F;
|
||||
padn = (last < 56) ? (56 - last) : (120 - last);
|
||||
|
||||
md5_update(ctx, md5_padding, padn);
|
||||
md5_update(ctx, msglen, 8);
|
||||
|
||||
PUT_UINT32(ctx->state[0], digest, 0);
|
||||
PUT_UINT32(ctx->state[1], digest, 4);
|
||||
PUT_UINT32(ctx->state[2], digest, 8);
|
||||
PUT_UINT32(ctx->state[3], digest, 12);
|
||||
}
|
||||
|
||||
void JCMD5::GenerateMD5(unsigned char* buffer, size_t bufferlen)
|
||||
{
|
||||
struct md5_context context;
|
||||
md5_starts(&context);
|
||||
md5_update(&context, buffer, bufferlen);
|
||||
md5_finish(&context, (unsigned char*)m_data);
|
||||
}
|
||||
|
||||
JCMD5::JCMD5()
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_data[i] = 0;
|
||||
}
|
||||
|
||||
JCMD5::JCMD5(unsigned long* md5src)
|
||||
{
|
||||
memcpy(m_data, md5src, 16);
|
||||
}
|
||||
int _httoi(const char *value)
|
||||
{
|
||||
struct CHexMap
|
||||
{
|
||||
char chr;
|
||||
int value;
|
||||
};
|
||||
const int HexMapL = 16;
|
||||
CHexMap HexMap[HexMapL] =
|
||||
{
|
||||
{ '0', 0 },{ '1', 1 },
|
||||
{ '2', 2 },{ '3', 3 },
|
||||
{ '4', 4 },{ '5', 5 },
|
||||
{ '6', 6 },{ '7', 7 },
|
||||
{ '8', 8 },{ '9', 9 },
|
||||
{ 'a', 10 },{ 'b', 11 },
|
||||
{ 'c', 12 },{ 'd', 13 },
|
||||
{ 'e', 14 },{ 'f', 15 }
|
||||
};
|
||||
char *mstr = strdup(value);
|
||||
char *s = mstr;
|
||||
int result = 0;
|
||||
if (*s == '0' && *(s + 1) == 'X') s += 2;
|
||||
bool firsttime = true;
|
||||
while (*s != '\0')
|
||||
{
|
||||
bool found = false;
|
||||
for (int i = 0; i < HexMapL; i++)
|
||||
{
|
||||
if (*s == HexMap[i].chr)
|
||||
{
|
||||
if (!firsttime) result <<= 4;
|
||||
result |= HexMap[i].value;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) break;
|
||||
s++;
|
||||
firsttime = false;
|
||||
}
|
||||
free(mstr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
JCMD5::JCMD5(const char* md5src)
|
||||
{
|
||||
if (strcmp(md5src, "") == 0)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_data[i] = 0;
|
||||
return;
|
||||
}
|
||||
for (int j = 0; j < 16; j++)
|
||||
{
|
||||
char buf[10];
|
||||
strncpy(buf, md5src, 2);
|
||||
md5src += 2;
|
||||
((unsigned char*)m_data)[j] = _httoi(buf);
|
||||
}
|
||||
}
|
||||
|
||||
JCMD5 JCMD5::operator +(JCMD5 adder)
|
||||
{
|
||||
unsigned long m_newdata[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
m_newdata[i] = m_data[i] ^ (adder.m_data[i]);
|
||||
return JCMD5(m_newdata);
|
||||
}
|
||||
|
||||
bool JCMD5::operator ==(JCMD5 cmper)
|
||||
{
|
||||
return (memcmp(cmper.m_data, m_data, 16) == 0);
|
||||
}
|
||||
|
||||
//void CMD5::operator =(CMD5 equer)
|
||||
//{
|
||||
// memcpy(m_data,equer.m_data ,16);
|
||||
//}
|
||||
|
||||
string JCMD5::ToString()
|
||||
{
|
||||
char output[33];
|
||||
for (int j = 0; j < 16; j++)
|
||||
{
|
||||
sprintf(output + j * 2, "%02x", ((unsigned char*)m_data)[j]);
|
||||
}
|
||||
return string(output);
|
||||
}
|
||||
#ifndef THIN_COMMON_WITHOUT_DOWNLOAD
|
||||
string JCEncrypt::s_sPassCode = "LayaBoxChgTWorld";
|
||||
string JCEncrypt::s_sPreCode = "!#$LAYABOX";
|
||||
int JCEncrypt::s_nPreLen = s_sPreCode.size();
|
||||
string JCEncrypt::s_sPassMd5;
|
||||
JCEncrypt::JCEncrypt()
|
||||
{
|
||||
|
||||
}
|
||||
JCEncrypt::~JCEncrypt()
|
||||
{
|
||||
|
||||
}
|
||||
string JCEncrypt::getpassCode(string url)
|
||||
{
|
||||
int len = url.size();
|
||||
JCMD5 imd5;
|
||||
imd5.GenerateMD5((unsigned char *)url.c_str(), len);
|
||||
string result = imd5.ToString();
|
||||
for (int i = 0, len = result.size(); i < len; i++)
|
||||
{
|
||||
result[i] ^= s_sPassCode[i % 16];
|
||||
}
|
||||
s_sPassMd5 = result;
|
||||
return result;
|
||||
}
|
||||
bool JCEncrypt::decrypt(char *buf, int len)
|
||||
{
|
||||
if (strncmp(buf, s_sPreCode.c_str(), s_nPreLen) == 0)
|
||||
{
|
||||
for (int i = 0; i < len - s_nPreLen; i++)
|
||||
{
|
||||
buf[i] = buf[i + s_nPreLen] ^ s_sPassMd5[i % 32];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
unsigned int JCBKDRHash::hashStr(const unsigned char* str){
|
||||
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
|
||||
unsigned int hash = 0;
|
||||
while (*str) {
|
||||
hash = hash * seed + (*str++);
|
||||
}
|
||||
return (hash & 0x7FFFFFFF);
|
||||
}
|
||||
|
||||
unsigned int JCBKDRHash::hashMem(const unsigned char* mem, int len){
|
||||
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
|
||||
unsigned int hash = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
hash = hash * seed + (*mem++);
|
||||
}
|
||||
hash = hash & 0x7FFFFFFF;
|
||||
return hash;
|
||||
}
|
||||
|
||||
static const uint32_t crc32tab[] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL,
|
||||
0x076dc419L, 0x706af48fL, 0xe963a535L, 0x9e6495a3L,
|
||||
0x0edb8832L, 0x79dcb8a4L, 0xe0d5e91eL, 0x97d2d988L,
|
||||
0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 0x90bf1d91L,
|
||||
0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L,
|
||||
0x136c9856L, 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL,
|
||||
0x14015c4fL, 0x63066cd9L, 0xfa0f3d63L, 0x8d080df5L,
|
||||
0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 0xa2677172L,
|
||||
0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L,
|
||||
0x32d86ce3L, 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L,
|
||||
0x26d930acL, 0x51de003aL, 0xc8d75180L, 0xbfd06116L,
|
||||
0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 0xb8bda50fL,
|
||||
0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL,
|
||||
0x76dc4190L, 0x01db7106L, 0x98d220bcL, 0xefd5102aL,
|
||||
0x71b18589L, 0x06b6b51fL, 0x9fbfe4a5L, 0xe8b8d433L,
|
||||
0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 0xe10e9818L,
|
||||
0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL,
|
||||
0x6c0695edL, 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L,
|
||||
0x65b0d9c6L, 0x12b7e950L, 0x8bbeb8eaL, 0xfcb9887cL,
|
||||
0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 0xfbd44c65L,
|
||||
0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL,
|
||||
0x4369e96aL, 0x346ed9fcL, 0xad678846L, 0xda60b8d0L,
|
||||
0x44042d73L, 0x33031de5L, 0xaa0a4c5fL, 0xdd0d7cc9L,
|
||||
0x5005713cL, 0x270241aaL, 0xbe0b1010L, 0xc90c2086L,
|
||||
0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L,
|
||||
0x59b33d17L, 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL,
|
||||
0xedb88320L, 0x9abfb3b6L, 0x03b6e20cL, 0x74b1d29aL,
|
||||
0xead54739L, 0x9dd277afL, 0x04db2615L, 0x73dc1683L,
|
||||
0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L,
|
||||
0xf00f9344L, 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL,
|
||||
0xf762575dL, 0x806567cbL, 0x196c3671L, 0x6e6b06e7L,
|
||||
0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 0x67dd4accL,
|
||||
0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L,
|
||||
0xd1bb67f1L, 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL,
|
||||
0xd80d2bdaL, 0xaf0a1b4cL, 0x36034af6L, 0x41047a60L,
|
||||
0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 0x4669be79L,
|
||||
0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL,
|
||||
0xc5ba3bbeL, 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L,
|
||||
0xc2d7ffa7L, 0xb5d0cf31L, 0x2cd99e8bL, 0x5bdeae1dL,
|
||||
0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 0x026d930aL,
|
||||
0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L,
|
||||
0x92d28e9bL, 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L,
|
||||
0x86d3d2d4L, 0xf1d4e242L, 0x68ddb3f8L, 0x1fda836eL,
|
||||
0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 0x18b74777L,
|
||||
0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L,
|
||||
0xa00ae278L, 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L,
|
||||
0xa7672661L, 0xd06016f7L, 0x4969474dL, 0x3e6e77dbL,
|
||||
0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 0x37d83bf0L,
|
||||
0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L,
|
||||
0xbad03605L, 0xcdd70693L, 0x54de5729L, 0x23d967bfL,
|
||||
0xb3667a2eL, 0xc4614ab8L, 0x5d681b02L, 0x2a6f2b94L,
|
||||
0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 0x2d02ef8dL
|
||||
};
|
||||
|
||||
uint32_t crc32(const unsigned char *buf, uint32_t size){
|
||||
uint32_t i, crc;
|
||||
crc = 0xFFFFFFFF;
|
||||
for (i = 0; i < size; i++)
|
||||
crc = crc32tab[(crc ^ buf[i]) & 0xff] ^ (crc >> 8);
|
||||
return crc ^ 0xFFFFFFFF;
|
||||
}
|
||||
static const char base64_table[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
|
||||
};
|
||||
|
||||
static const char base64_pad = '=';
|
||||
|
||||
static const short base64_reverse_table[256] = {
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2,
|
||||
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
|
||||
-1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
|
||||
-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
|
||||
-2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -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, -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, -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, -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, -2, -2, -2, -2, -2
|
||||
};
|
||||
|
||||
|
||||
char* base64_encode(const unsigned char *str, int length, int *ret_length) /* {{{ */
|
||||
{
|
||||
const unsigned char *current = str;
|
||||
char *p;
|
||||
char *result;
|
||||
|
||||
if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
|
||||
if (ret_length != NULL) {
|
||||
*ret_length = 0;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//result = (char *)malloc((((length + 2) / 3) * 4)*(sizeof(char))+(1));
|
||||
result = new char[(((length + 2) / 3) * 4)*(sizeof(char)) + (1)];
|
||||
if (result == NULL) {
|
||||
//fprintf(stderr, "out of memory!\n");
|
||||
//exit(1);
|
||||
return NULL;
|
||||
}
|
||||
p = result;
|
||||
|
||||
while (length > 2) {
|
||||
*p++ = base64_table[current[0] >> 2];
|
||||
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
|
||||
*p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
|
||||
*p++ = base64_table[current[2] & 0x3f];
|
||||
|
||||
current += 3;
|
||||
length -= 3;
|
||||
}
|
||||
|
||||
if (length != 0) {
|
||||
*p++ = base64_table[current[0] >> 2];
|
||||
if (length > 1) {
|
||||
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
|
||||
*p++ = base64_table[(current[1] & 0x0f) << 2];
|
||||
*p++ = base64_pad;
|
||||
}
|
||||
else {
|
||||
*p++ = base64_table[(current[0] & 0x03) << 4];
|
||||
*p++ = base64_pad;
|
||||
*p++ = base64_pad;
|
||||
}
|
||||
}
|
||||
if (ret_length != NULL) {
|
||||
*ret_length = (int)(p - result);
|
||||
}
|
||||
*p = '\0';
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
char *base64_decode(const unsigned char *str, int length, int *ret_length)
|
||||
{
|
||||
const unsigned char *current = str;
|
||||
int ch, i = 0, j = 0, k;
|
||||
char *result;
|
||||
|
||||
//result = (char *)malloc(length+1);
|
||||
result = new char[length + 1];
|
||||
if (result == NULL) {
|
||||
//fprintf(stderr, "out of memory!\n");
|
||||
//exit(1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ((ch = *current++) != '\0' && length-- > 0) {
|
||||
if (ch == base64_pad) {
|
||||
if (*current != '=' && (i % 4) == 1) {
|
||||
//free(result);
|
||||
delete[] result;
|
||||
return NULL;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
ch = base64_reverse_table[ch];
|
||||
if ((1 && ch < 0) || ch == -1) {
|
||||
continue;
|
||||
}
|
||||
else if (ch == -2) {
|
||||
//free(result);
|
||||
delete[] result;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (i % 4) {
|
||||
case 0:
|
||||
result[j] = ch << 2;
|
||||
break;
|
||||
case 1:
|
||||
result[j++] |= ch >> 4;
|
||||
result[j] = (ch & 0x0f) << 4;
|
||||
break;
|
||||
case 2:
|
||||
result[j++] |= ch >> 2;
|
||||
result[j] = (ch & 0x03) << 6;
|
||||
break;
|
||||
case 3:
|
||||
result[j++] |= ch;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
k = j;
|
||||
|
||||
if (ch == base64_pad) {
|
||||
switch (i % 4) {
|
||||
case 1:
|
||||
//free(result);
|
||||
delete[] result;
|
||||
return NULL;
|
||||
case 2:
|
||||
k++;
|
||||
case 3:
|
||||
result[k] = 0;
|
||||
}
|
||||
}
|
||||
if (ret_length) {
|
||||
*ret_length = j;
|
||||
}
|
||||
result[j] = '\0';
|
||||
return result;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
@file JCCrypto.h
|
||||
@brief
|
||||
@author hugao
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#ifndef __JCCrypto_H__
|
||||
#define __JCCrypto_H__
|
||||
|
||||
#pragma warning(disable:4786)
|
||||
#define NORMAL_SIZE BUFSIZ
|
||||
#include <string>
|
||||
using namespace std;
|
||||
namespace laya
|
||||
{
|
||||
char *base64_decode(const unsigned char *str, int length, int *ret_length);
|
||||
char* base64_encode(const unsigned char *str, int length, int *ret_length);
|
||||
|
||||
unsigned int base64Decode(char *pDest, const char *pSrc, unsigned int srclen);
|
||||
unsigned int base64Encode(char *pDest, const char *pSrc, unsigned int srclen);
|
||||
class JCBKDRHash {
|
||||
public:
|
||||
static unsigned int hashStr(const unsigned char* str);
|
||||
|
||||
static unsigned int hashMem(const unsigned char* mem, int len);
|
||||
};
|
||||
#ifndef WEBASM
|
||||
struct MD5_DATA
|
||||
{
|
||||
unsigned long data[4];
|
||||
bool operator < (const MD5_DATA& p) const
|
||||
{
|
||||
return memcmp(data, p.data, 4 * sizeof(long))>0;
|
||||
}
|
||||
};
|
||||
|
||||
class JCMD5
|
||||
{
|
||||
private:
|
||||
|
||||
struct md5_context
|
||||
{
|
||||
unsigned int total[2];
|
||||
unsigned int state[4];
|
||||
unsigned char buffer[64];
|
||||
};
|
||||
|
||||
void md5_starts(struct md5_context *ctx);
|
||||
void md5_process(struct md5_context *ctx, unsigned char data[64]);
|
||||
void md5_update(struct md5_context *ctx, unsigned char *input, size_t length);
|
||||
void md5_finish(struct md5_context *ctx, unsigned char digest[16]);
|
||||
|
||||
public:
|
||||
//! construct a CMD5 from any buffer
|
||||
void GenerateMD5(unsigned char* buffer, size_t bufferlen);
|
||||
|
||||
//! construct a CMD5
|
||||
JCMD5();
|
||||
|
||||
//! construct a md5src from char *
|
||||
JCMD5(const char * md5src);
|
||||
|
||||
//! construct a CMD5 from a 16 bytes md5
|
||||
JCMD5(unsigned long* md5src);
|
||||
|
||||
//! add a other md5
|
||||
JCMD5 operator +(JCMD5 adder);
|
||||
|
||||
//! just if equal
|
||||
bool operator ==(JCMD5 cmper);
|
||||
|
||||
//! give the value from equer
|
||||
// void operator =(CMD5 equer);
|
||||
|
||||
//! to a string
|
||||
string ToString();
|
||||
|
||||
unsigned long m_data[4];
|
||||
};
|
||||
#ifndef THIN_COMMON_WITHOUT_DOWNLOAD
|
||||
class JCEncrypt
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief构造函数
|
||||
*/
|
||||
JCEncrypt();
|
||||
|
||||
/** @brief析构函数
|
||||
*/
|
||||
~JCEncrypt();
|
||||
|
||||
static bool decrypt(char *buf, int len);
|
||||
|
||||
static std::string getpassCode(std::string url);
|
||||
|
||||
private:
|
||||
static std::string s_sPassCode;//生成秘钥的辅助字符串
|
||||
static std::string s_sPreCode; //加密文件的前面的标志
|
||||
static std::string s_sPassMd5; //秘钥
|
||||
public:
|
||||
static int s_nPreLen; //加密前缀的字数
|
||||
};
|
||||
#endif
|
||||
uint32_t crc32(const unsigned char *buf, uint32_t size);
|
||||
|
||||
#endif
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCCrypto_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
#include "JCFlog.h"
|
||||
#include <stdarg.h>
|
||||
#include "../util/JCCommonMethod.h"
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
namespace laya{
|
||||
JCFileLog::JCFileLog(){
|
||||
m_pFile = NULL;
|
||||
m_bAutoRet = true;
|
||||
}
|
||||
|
||||
JCFileLog::~JCFileLog(){
|
||||
if(m_pFile){
|
||||
fclose(m_pFile);
|
||||
}
|
||||
}
|
||||
|
||||
bool JCFileLog::init(const char* p_pszFile ){
|
||||
m_pFile = fopen(p_pszFile,"w");
|
||||
return m_pFile!=NULL;
|
||||
}
|
||||
|
||||
void JCFileLog::Log(const char* pFormat,...){
|
||||
if(m_pFile==NULL)
|
||||
return;
|
||||
double curtm = tmGetCurms();
|
||||
int* ptm = (int*)&curtm;
|
||||
fprintf( m_pFile, "[%d,%d ]",ptm[1],ptm[0]);
|
||||
va_list args;
|
||||
va_start(args,pFormat);
|
||||
vfprintf(m_pFile,pFormat,args);// (char *)(&pFormat+1));
|
||||
va_end(args);
|
||||
if(m_bAutoRet){
|
||||
fprintf(m_pFile,"\n");
|
||||
}
|
||||
|
||||
fflush(m_pFile);
|
||||
}
|
||||
|
||||
void JCFileLog::Log1(const char* pFormat,va_list pArgs ){
|
||||
if(m_pFile==NULL)
|
||||
return;
|
||||
double curtm = tmGetCurms();
|
||||
int* ptm = (int*)&curtm;
|
||||
fprintf( m_pFile, "[%d,%d ]",ptm[1],ptm[0]);
|
||||
vfprintf(m_pFile,pFormat,pArgs);
|
||||
if(m_bAutoRet){
|
||||
fprintf(m_pFile,"\n");
|
||||
}
|
||||
|
||||
fflush(m_pFile);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
|
||||
/*
|
||||
写到文件中的日志。
|
||||
*/
|
||||
|
||||
#ifndef _LAYA_FILE_LOG_H__
|
||||
#define _LAYA_FILE_LOG_H__
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace laya{
|
||||
class JCFileLog{
|
||||
public:
|
||||
JCFileLog();
|
||||
~JCFileLog();
|
||||
//打开日志文件,会清掉之前的。
|
||||
bool init(const char* p_pszFile );
|
||||
//是否自动加上回车
|
||||
void setAutoRet(bool b){ m_bAutoRet=b;};
|
||||
bool getAutoRet(){return m_bAutoRet;};
|
||||
|
||||
//注意这个函数可能在多个线程调用。
|
||||
void Log(const char* pFormat,...);
|
||||
//同上。只是不用...,pArgs实际是很多参数
|
||||
//void Log1(const char* pFormat,const char* pArgs );
|
||||
void Log1(const char* pFormat, va_list pArgs );
|
||||
protected:
|
||||
FILE* m_pFile;
|
||||
bool m_bAutoRet;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
|
||||
/**
|
||||
@file JCIThreadMgr.h
|
||||
@brief
|
||||
@author guo
|
||||
@version 1.0
|
||||
@date 2016_5_19
|
||||
*/
|
||||
|
||||
#ifndef __JCIThreadMgr_H__
|
||||
#define __JCIThreadMgr_H__
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace laya {
|
||||
class IConchThreadCmdMgr {
|
||||
public:
|
||||
virtual void postToJS(const std::function<void(void)>& f) = 0;
|
||||
virtual void postToDownload(const std::function<void(void)>& f)=0;
|
||||
virtual void postToDecoder(const std::function<void(void)>& f)=0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__JCIThreadMgr_H__
|
||||
@@ -0,0 +1,228 @@
|
||||
#include "JCIniFile.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#pragma warning(disable:4996)
|
||||
#pragma warning(disable:4018)
|
||||
#pragma warning(disable:4101)
|
||||
namespace laya
|
||||
{
|
||||
JCIniFile::__BuffCtrl::__BuffCtrl()
|
||||
{
|
||||
m_pBuff = m_pCur = 0;
|
||||
m_iBuffSize = m_iLeftSize = 0;
|
||||
}
|
||||
JCIniFile::__BuffCtrl::~__BuffCtrl()
|
||||
{
|
||||
if (0 != m_pBuff)
|
||||
{
|
||||
delete[] m_pBuff;
|
||||
m_pBuff = 0;
|
||||
}
|
||||
}
|
||||
void JCIniFile::__BuffCtrl::Reset()
|
||||
{
|
||||
m_pCur = m_pBuff;
|
||||
m_iLeftSize = m_iBuffSize;
|
||||
}
|
||||
void JCIniFile::__BuffCtrl::Bind(char *p_pBuff, int p_iBuffSize)
|
||||
{
|
||||
m_pBuff = p_pBuff;
|
||||
m_iBuffSize = p_iBuffSize;
|
||||
Reset();
|
||||
}
|
||||
bool JCIniFile::__BuffCtrl::GetLine(char *p_pBuff, int p_iBuffSize)
|
||||
{
|
||||
if (0 == m_iLeftSize || 0 == m_pCur)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
char *pBegin = m_pCur;
|
||||
char *pCur = pBegin;
|
||||
int iLeft = m_iLeftSize;
|
||||
for (; iLeft > 0;)
|
||||
{
|
||||
if ('\r' == *pCur || '\n' == *pCur)
|
||||
{
|
||||
if (p_iBuffSize < pCur - pBegin)
|
||||
return false;
|
||||
memcpy(p_pBuff, pBegin, pCur - pBegin);
|
||||
p_pBuff[pCur - pBegin] = 0;
|
||||
for (; iLeft>0;)
|
||||
{
|
||||
if ('\r' != *pCur && '\n' != *pCur)
|
||||
break;
|
||||
else
|
||||
{
|
||||
pCur++;
|
||||
iLeft--;
|
||||
}
|
||||
}
|
||||
if (0 == iLeft)
|
||||
{
|
||||
m_iLeftSize = 0;
|
||||
m_pCur = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pCur = pCur;
|
||||
m_iLeftSize = iLeft;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pCur++;
|
||||
iLeft--;
|
||||
}
|
||||
}
|
||||
|
||||
if (pCur - pBegin > 0)
|
||||
{
|
||||
if (p_iBuffSize < pCur - pBegin)
|
||||
return false;
|
||||
memcpy(p_pBuff, pBegin, pCur - pBegin);
|
||||
p_pBuff[pCur - pBegin] = 0;
|
||||
m_iLeftSize = 0;
|
||||
m_pCur = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
JCIniFile::JCIniFile(char *p_pFileContent, size_t p_iBuffSize)
|
||||
{
|
||||
m_BuffCtrl.Bind(p_pFileContent, p_iBuffSize);
|
||||
__Parse();
|
||||
}
|
||||
|
||||
JCIniFile::~JCIniFile()
|
||||
{
|
||||
if (m_Values.size())
|
||||
{
|
||||
_PairQueueIter iter;
|
||||
for (iter = m_Values.begin(); iter != m_Values.end(); iter++)
|
||||
{
|
||||
delete *iter;
|
||||
}
|
||||
m_Values.clear();
|
||||
}
|
||||
}
|
||||
char *JCIniFile::_TrimLeft(char *p_pszStr)
|
||||
{
|
||||
char *p = p_pszStr;
|
||||
for (;;)
|
||||
{
|
||||
if (!*p)
|
||||
break;
|
||||
if (*p > 0x20)
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
char *JCIniFile::_TrimRight(char *p_pszStr)
|
||||
{
|
||||
char *p = p_pszStr + strlen(p_pszStr);
|
||||
|
||||
for (; p >= p_pszStr;)
|
||||
{
|
||||
if (*p <= 0x20)
|
||||
*p = 0;
|
||||
else
|
||||
break;
|
||||
p--;
|
||||
}
|
||||
return p_pszStr;
|
||||
}
|
||||
void JCIniFile::__Parse()
|
||||
{
|
||||
char szLine[1024];
|
||||
char *ln;
|
||||
int n;
|
||||
char *l, *r;
|
||||
_Pair_t *pPair;
|
||||
|
||||
for (; m_BuffCtrl.GetLine(szLine, 1024);)
|
||||
{
|
||||
ln = _TrimLeft(szLine);
|
||||
if (!*ln)
|
||||
continue;
|
||||
n = strlen(ln);
|
||||
while (n && (ln[n - 1] == '\r' || ln[n - 1] == '\n'))
|
||||
{
|
||||
ln[n - 1] = '\0';
|
||||
n--;
|
||||
}
|
||||
if (!n)
|
||||
continue;
|
||||
|
||||
l = strtok(ln, "=");
|
||||
r = strtok(0, "\0");
|
||||
|
||||
l = _TrimRight(l);
|
||||
if (r)
|
||||
{
|
||||
r = _TrimRight(r);
|
||||
r = _TrimLeft(r);
|
||||
}
|
||||
|
||||
pPair = new _Pair_t;
|
||||
|
||||
pPair->m_pszKey = new char[strlen(l) + 1];
|
||||
strcpy(pPair->m_pszKey, l);
|
||||
if (r && strlen(r))
|
||||
{
|
||||
pPair->m_pszValue = new char[strlen(r) + 1];
|
||||
strcpy(pPair->m_pszValue, r);
|
||||
}
|
||||
m_Values.push_back(pPair);
|
||||
}
|
||||
}
|
||||
bool JCIniFile::IsReady()
|
||||
{
|
||||
return (0 != m_Values.size());
|
||||
}
|
||||
const char *JCIniFile::GetValue(const char *p_pszKey)
|
||||
{
|
||||
if (0 == p_pszKey)
|
||||
return 0;
|
||||
|
||||
const char *pRet = 0;
|
||||
|
||||
if (m_Values.size())
|
||||
{
|
||||
_PairQueueIter iter;
|
||||
for (iter = m_Values.begin(); iter != m_Values.end(); iter++)
|
||||
{
|
||||
if (strcmp(p_pszKey, (*iter)->m_pszKey) == 0)
|
||||
{
|
||||
pRet = (*iter)->m_pszValue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return pRet;
|
||||
}
|
||||
|
||||
JCIniFile* JCIniFile::loadFile(const char* p_sFileName)
|
||||
{
|
||||
if (p_sFileName == NULL)return NULL;
|
||||
FILE* fp = fopen(p_sFileName, "r");
|
||||
if (!fp) return NULL;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int nBuffSize = (int)ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
char *pBuff = new char[nBuffSize+1];
|
||||
int nReadSize = fread((char*)pBuff, 1, nBuffSize, fp);
|
||||
if (nReadSize != nBuffSize)
|
||||
{
|
||||
delete pBuff;
|
||||
return NULL;
|
||||
}
|
||||
fclose(fp);
|
||||
pBuff[nBuffSize] = 0;
|
||||
return new JCIniFile(pBuff, nBuffSize);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
@file JCIniFile.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_6_11
|
||||
*/
|
||||
|
||||
#ifndef __JCIniFile_H__
|
||||
#define __JCIniFile_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <deque>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
class JCIniFile
|
||||
{
|
||||
class __BuffCtrl
|
||||
{
|
||||
public:
|
||||
__BuffCtrl();
|
||||
~__BuffCtrl();
|
||||
void Bind(char *p_pBuff, int p_iBuffSize);
|
||||
void Reset();
|
||||
bool GetLine(char *p_pBuff, int p_iBuffSize);
|
||||
public:
|
||||
char* m_pBuff;
|
||||
int m_iBuffSize;
|
||||
char* m_pCur;
|
||||
int m_iLeftSize;
|
||||
};
|
||||
struct _Pair_t
|
||||
{
|
||||
_Pair_t()
|
||||
{
|
||||
m_pszKey = m_pszValue = 0;
|
||||
}
|
||||
~_Pair_t()
|
||||
{
|
||||
if (0 != m_pszKey)
|
||||
{
|
||||
delete[] m_pszKey;
|
||||
}
|
||||
if (0 != m_pszValue)
|
||||
{
|
||||
delete[] m_pszValue;
|
||||
}
|
||||
}
|
||||
char *m_pszKey;
|
||||
char *m_pszValue;
|
||||
};
|
||||
public:
|
||||
|
||||
typedef std::deque<_Pair_t *> _PairQueue;
|
||||
typedef _PairQueue::iterator _PairQueueIter;
|
||||
char *_TrimLeft(char *p_pszStr);
|
||||
char *_TrimRight(char *p_pszStr);
|
||||
void __Parse();
|
||||
public:
|
||||
JCIniFile(char *p_pFileContent, size_t p_iBuffSize);
|
||||
~JCIniFile();
|
||||
bool IsReady();
|
||||
const char *GetValue(const char *p_pszKey);
|
||||
static JCIniFile* loadFile(const char* p_sFileName);
|
||||
public:
|
||||
__BuffCtrl m_BuffCtrl;
|
||||
_PairQueue m_Values;
|
||||
};
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCIniFile_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
@file JCJson.cpp
|
||||
@brief
|
||||
@author wyw
|
||||
@version 1.0
|
||||
@date 2014_6_17
|
||||
*/
|
||||
|
||||
#include "JCJson.h"
|
||||
#include <ctype.h>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
JCJson::JCJson()
|
||||
{
|
||||
m_pRoot = NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCJson::~JCJson()
|
||||
{
|
||||
cleanUp();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool JCJson::cleanUp()
|
||||
{
|
||||
if( m_pRoot != NULL )
|
||||
{
|
||||
m_pRoot->clearChild();
|
||||
delete m_pRoot;
|
||||
m_pRoot = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JsonNode* JCJson::getRoot()
|
||||
{
|
||||
return m_pRoot;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool JCJson::paserJson( char* p_sBuffer )
|
||||
{
|
||||
return paserJson(p_sBuffer, strlen(p_sBuffer));
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool JCJson::paserJson( char* p_sBuffer, int len )
|
||||
{
|
||||
if( p_sBuffer == NULL )return false;
|
||||
if( m_pRoot == NULL )
|
||||
{
|
||||
m_pRoot = new JsonObject();
|
||||
}
|
||||
int nBufferSize = len;
|
||||
|
||||
//找到第一个 “{” 这样做是为了避免 文件开头有其他文字
|
||||
int i = 0;
|
||||
while( i < nBufferSize )
|
||||
{
|
||||
if( p_sBuffer[i] != '{' )
|
||||
{
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
int nOffset = i + 1;
|
||||
paserJson( p_sBuffer,nBufferSize,nOffset,m_pRoot );
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
int JCJson::paserJson( char* p_sBuffer,int p_nBufferSize,int p_nOffset,JsonNode* p_pNode )
|
||||
{
|
||||
if( p_nOffset >= p_nBufferSize ) return p_nOffset;
|
||||
int i = p_nOffset;
|
||||
|
||||
bool bValueString = false;
|
||||
char* sKey = NULL;
|
||||
char* sValue = NULL;
|
||||
PASER_JSON_STATE nState = PJ_STATE_INIT;
|
||||
|
||||
while( i < p_nBufferSize )
|
||||
{
|
||||
//初始状态
|
||||
if( nState == PJ_STATE_INIT )
|
||||
{
|
||||
//如果找到的是 " 就开始进入匹配KEY的状态
|
||||
if( p_sBuffer[i] == '"' )
|
||||
{
|
||||
nState = PJ_STATE_MATCHING_KEY;
|
||||
sKey = (p_sBuffer + i + 1);
|
||||
}
|
||||
//如果是 { 证明又是一个对象,重新递归读取对象
|
||||
else if( p_sBuffer[i] == '{' )
|
||||
{
|
||||
JsonObject* pObject = new JsonObject();
|
||||
p_pNode->addChild( pObject );
|
||||
i = paserJson( p_sBuffer,p_nBufferSize,++i,pObject );
|
||||
//数据恢复
|
||||
{
|
||||
nState = PJ_STATE_INIT;
|
||||
sKey = NULL;
|
||||
sValue = NULL;
|
||||
}
|
||||
}
|
||||
else if( p_sBuffer[i] == '}' )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
else if( p_sBuffer[i] == ']' )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
//这个有点凑了,,因为在文件中会出现 "mat": [1.3,0,0,1.3,0.294,2.893]
|
||||
//这样的现象,所以要处理
|
||||
else if( isgraph( p_sBuffer[i] ) && ( p_sBuffer[i] != ',' ) )
|
||||
{
|
||||
sKey = (char*)"";
|
||||
sValue = p_sBuffer + i;
|
||||
nState = PJ_STATE_MATCHING_VALUE;
|
||||
}
|
||||
}
|
||||
//如果是匹配key,知道匹配上 " key的值就有了,并进入匹配value阶段
|
||||
else if( nState == PJ_STATE_MATCHING_KEY )
|
||||
{
|
||||
if( p_sBuffer[i] == '"' )
|
||||
{
|
||||
p_sBuffer[i] = 0;
|
||||
}
|
||||
else if( p_sBuffer[i] == ':' )
|
||||
{
|
||||
bValueString = false;
|
||||
sValue = p_sBuffer + i + 1;
|
||||
nState = PJ_STATE_MATCHING_VALUE;
|
||||
}
|
||||
// == ',' 和 下面的 } ] 这两个是为了,怕碰到这种情况 "config_file_path": ["daji0.plist","daji1.plist"]
|
||||
else if( p_sBuffer[i] == ',' )
|
||||
{
|
||||
JsonValue* pJsonValue = new JsonValue();
|
||||
p_sBuffer[i] = 0;
|
||||
pJsonValue->setKeyAndValue( (char*)"",sKey );
|
||||
p_pNode->addChild( pJsonValue );
|
||||
//数据恢复
|
||||
{
|
||||
nState = PJ_STATE_INIT;
|
||||
sKey = NULL;
|
||||
sValue = NULL;
|
||||
}
|
||||
}
|
||||
else if( p_sBuffer[i] == '}' || p_sBuffer[i] == ']' )
|
||||
{
|
||||
JsonValue* pJsonValue = new JsonValue();
|
||||
p_sBuffer[i] = 0;
|
||||
pJsonValue->setKeyAndValue( (char*)"",sKey );
|
||||
p_pNode->addChild( pJsonValue );
|
||||
return i;
|
||||
}
|
||||
}
|
||||
//开始匹配value
|
||||
else if( nState == PJ_STATE_MATCHING_VALUE )
|
||||
{
|
||||
if( bValueString == false )
|
||||
{
|
||||
if( p_sBuffer[i] == '"')
|
||||
{
|
||||
sValue = p_sBuffer + i + 1;
|
||||
bValueString = true;
|
||||
}
|
||||
//如果是 [ 是数组,再次递归
|
||||
else if( p_sBuffer[i] == '[' )
|
||||
{
|
||||
nState = PJ_STATE_MATCHING_ARRAY;
|
||||
JsonArray* pArray = new JsonArray();
|
||||
pArray->setKey( sKey );
|
||||
p_pNode->addChild( pArray );
|
||||
i = paserJson( p_sBuffer,p_nBufferSize,++i,pArray );
|
||||
//数据恢复
|
||||
{
|
||||
nState = PJ_STATE_INIT;
|
||||
sKey = NULL;
|
||||
sValue = NULL;
|
||||
}
|
||||
}
|
||||
//如果是 { 是object,再次递归
|
||||
else if( p_sBuffer[i] == '{' )
|
||||
{
|
||||
nState = PJ_STATE_MATCHING_OBJECT;
|
||||
JsonObject* pObject = new JsonObject();
|
||||
pObject->setKey( sKey );
|
||||
p_pNode->addChild( pObject );
|
||||
i = paserJson( p_sBuffer,p_nBufferSize,++i,pObject );
|
||||
//数据恢复
|
||||
{
|
||||
nState = PJ_STATE_INIT;
|
||||
sKey = NULL;
|
||||
sValue = NULL;
|
||||
}
|
||||
}
|
||||
else if( p_sBuffer[i] == ',' )
|
||||
{
|
||||
JsonValue* pJsonValue = new JsonValue();
|
||||
p_sBuffer[i] = 0;
|
||||
pJsonValue->setKeyAndValue( sKey,sValue );
|
||||
p_pNode->addChild( pJsonValue );
|
||||
//数据恢复
|
||||
{
|
||||
nState = PJ_STATE_INIT;
|
||||
sKey = NULL;
|
||||
sValue = NULL;
|
||||
}
|
||||
}
|
||||
else if( p_sBuffer[i] == '}' || p_sBuffer[i] == ']' )
|
||||
{
|
||||
JsonValue* pJsonValue = new JsonValue();
|
||||
p_sBuffer[i] = 0;
|
||||
pJsonValue->setKeyAndValue( sKey,sValue );
|
||||
p_pNode->addChild( pJsonValue );
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p_sBuffer[i] == '"' )
|
||||
{
|
||||
JsonValue* pJsonValue = new JsonValue();
|
||||
p_sBuffer[i] = 0;
|
||||
pJsonValue->setKeyAndValue( sKey,sValue );
|
||||
p_pNode->addChild( pJsonValue );
|
||||
bValueString = false;
|
||||
//数据恢复
|
||||
{
|
||||
nState = PJ_STATE_INIT;
|
||||
sKey = NULL;
|
||||
sValue = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
@file JCJson.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_6_17
|
||||
*/
|
||||
|
||||
#ifndef __JCJson_H__
|
||||
#define __JCJson_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#pragma warning (disable: 4996)
|
||||
|
||||
namespace laya
|
||||
{
|
||||
enum PASER_JSON_STATE
|
||||
{
|
||||
PJ_STATE_INIT = 0, //初始状态
|
||||
PJ_STATE_MATCHING_KEY, //匹配key的状态
|
||||
PJ_STATE_MATCHING_VALUE, //匹配value状态
|
||||
PJ_STATE_MATCHING_OBJECT, //匹配Object
|
||||
PJ_STATE_MATCHING_ARRAY, //匹配Array
|
||||
};
|
||||
class JsonNode
|
||||
{
|
||||
public:
|
||||
char* m_sKey;
|
||||
int m_nKey;
|
||||
unsigned char m_nType;
|
||||
JsonNode()
|
||||
{
|
||||
m_sKey = NULL;
|
||||
m_nKey = 0;
|
||||
m_nType = -1;
|
||||
}
|
||||
virtual ~JsonNode()
|
||||
{
|
||||
m_sKey = NULL;
|
||||
m_nKey = 0;
|
||||
m_nType = -1;
|
||||
}
|
||||
void setKey( char* p_sKey)
|
||||
{
|
||||
m_sKey = p_sKey;
|
||||
}
|
||||
virtual bool addChild( JsonNode* p_pChild )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool clearChild()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
struct JsonValue : JsonNode
|
||||
{
|
||||
JsonValue()
|
||||
{
|
||||
m_sKey = NULL;
|
||||
m_nKey = 0;
|
||||
m_nType = 0;
|
||||
m_sValue = NULL;
|
||||
}
|
||||
~JsonValue()
|
||||
{
|
||||
}
|
||||
void setKeyAndValue( char* p_sKey,char* p_sValue )
|
||||
{
|
||||
m_sKey = p_sKey;
|
||||
m_sValue = p_sValue;
|
||||
}
|
||||
bool addChild( JsonNode* p_pChild )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
char* m_sValue;
|
||||
};
|
||||
struct JsonObject : JsonNode
|
||||
{
|
||||
JsonObject()
|
||||
{
|
||||
m_sKey = NULL;
|
||||
m_nKey = 0;
|
||||
m_nType = 1;
|
||||
}
|
||||
~JsonObject()
|
||||
{
|
||||
}
|
||||
bool addChild( JsonNode* p_pChild )
|
||||
{
|
||||
m_vVector.push_back( p_pChild );
|
||||
return true;
|
||||
}
|
||||
bool clearChild()
|
||||
{
|
||||
for( int i = 0,nSize = (int)(m_vVector.size()); i < nSize; i++ )
|
||||
{
|
||||
if( m_vVector[i] != NULL )
|
||||
{
|
||||
m_vVector[i]->clearChild();
|
||||
delete m_vVector[i];
|
||||
m_vVector[i] = NULL;
|
||||
}
|
||||
}
|
||||
m_vVector.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
JsonNode* getNode(const char* p_pszName) {
|
||||
for (int i = 0, sz = (int)m_vVector.size(); i < sz; i++) {
|
||||
JsonNode* pN = m_vVector[i];
|
||||
if (strcmp(pN->m_sKey, p_pszName) == 0) {
|
||||
return pN;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
std::vector<JsonNode*> m_vVector;
|
||||
};
|
||||
|
||||
struct JsonArray : JsonNode
|
||||
{
|
||||
JsonArray()
|
||||
{
|
||||
m_sKey = NULL;
|
||||
m_nKey = 0;
|
||||
m_nType = 2;
|
||||
}
|
||||
~JsonArray()
|
||||
{
|
||||
}
|
||||
bool addChild( JsonNode* p_pChild )
|
||||
{
|
||||
m_vVector.push_back( p_pChild );
|
||||
return true;
|
||||
}
|
||||
bool clearChild()
|
||||
{
|
||||
for( int i = 0,nSize = (int)(m_vVector.size()); i < nSize; i++ )
|
||||
{
|
||||
if( m_vVector[i] != NULL )
|
||||
{
|
||||
m_vVector[i]->clearChild();
|
||||
delete m_vVector[i];
|
||||
m_vVector[i] = NULL;
|
||||
}
|
||||
}
|
||||
m_vVector.clear();
|
||||
return true;
|
||||
}
|
||||
std::vector<JsonNode*> m_vVector;
|
||||
};
|
||||
|
||||
class JCJson
|
||||
{
|
||||
public:
|
||||
|
||||
JCJson();
|
||||
|
||||
~JCJson();
|
||||
|
||||
bool cleanUp();
|
||||
|
||||
//注意啦,为了效率,这个buffer没有自己拷贝,外部也先不要删除
|
||||
bool paserJson( char* p_sBuffer );
|
||||
|
||||
bool paserJson( char* p_sBuffer, int len);
|
||||
|
||||
JsonNode* getRoot();
|
||||
|
||||
private:
|
||||
|
||||
int paserJson( char* p_sBuffer,int p_nBufferSize,int p_nOffset,JsonNode* p_pNode );
|
||||
|
||||
private:
|
||||
|
||||
JsonNode* m_pRoot;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //__JCJson_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,382 @@
|
||||
/**
|
||||
@file JCLayaUrl.cpp
|
||||
@brief
|
||||
@author hugao
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#include "JCLayaUrl.h"
|
||||
#include "Log.h"
|
||||
#include "JCCommonMethod.h"
|
||||
|
||||
|
||||
namespace laya{
|
||||
JCUrl::JCUrl(){
|
||||
m_pszUrl = NULL;
|
||||
m_nProto = unk;
|
||||
m_nUrlSize = 0;
|
||||
m_bHasDriver=false;
|
||||
}
|
||||
JCUrl::JCUrl(const char* p_pszUrl) {
|
||||
m_pszUrl = NULL;
|
||||
m_nProto = unk;
|
||||
m_nUrlSize = 0;
|
||||
m_bHasDriver = false;
|
||||
parse(p_pszUrl);
|
||||
}
|
||||
JCUrl::~JCUrl(){
|
||||
if(m_pszUrl){
|
||||
delete [] m_pszUrl;
|
||||
m_pszUrl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void JCUrl::trim(const char*& p_pszData){
|
||||
char cv = *p_pszData;
|
||||
while(cv==' '||cv=='\t'){
|
||||
cv=*(++p_pszData);
|
||||
}
|
||||
}
|
||||
|
||||
//由于js的location是没有 // 所以这个也不要带 //
|
||||
const char* JCUrl::getProtocolString(){
|
||||
switch (m_nProto)
|
||||
{
|
||||
case laya::JCUrl::http:
|
||||
return "http:";
|
||||
break;
|
||||
case laya::JCUrl::https:
|
||||
return "https:";
|
||||
break;
|
||||
case laya::JCUrl::ftp:
|
||||
return "ftp:";
|
||||
break;
|
||||
case laya::JCUrl::file:
|
||||
return "file:";
|
||||
break;
|
||||
default:
|
||||
return "unk:";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO 现在还没有拆分 #
|
||||
std::vector<int> JCUrl::split(const char* p_pszData){
|
||||
const char* pData = p_pszData;
|
||||
char cv = *pData;
|
||||
std::vector<int> ret;
|
||||
while(cv){
|
||||
if(cv=='/'||cv=='\\' ){
|
||||
ret.push_back(pData-p_pszData);
|
||||
}else if(cv=='?'){
|
||||
ret.push_back(pData-p_pszData);
|
||||
break;
|
||||
}
|
||||
cv = *(++pData);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JCUrl::parseScheme(const char*& p_pszData){
|
||||
const char* pcur = p_pszData;
|
||||
if((pcur[0]=='h'||pcur[0]=='H')&&(pcur[1]=='t'||pcur[1]=='T')&&(pcur[2]=='t'||pcur[2]=='T')&&(pcur[3]=='p'||pcur[3]=='P')){
|
||||
if(pcur[4]=='s' || pcur[4]=='S'){
|
||||
m_nProto = https;
|
||||
p_pszData+=5;
|
||||
}else{
|
||||
m_nProto = http;
|
||||
//m_Protocol.st=0; m_Protocol.len=4;
|
||||
p_pszData+=4;
|
||||
}
|
||||
}else if((pcur[0]=='f'||pcur[0]=='F')&&(pcur[1]=='t'||pcur[1]=='T')&&(pcur[2]=='p'||pcur[2]=='P')){
|
||||
m_nProto = ftp;
|
||||
//m_Protocol.st=0; m_Protocol.len=3;
|
||||
p_pszData+=3;
|
||||
}else if((pcur[0]=='f'||pcur[0]=='F')&&(pcur[1]=='i'||pcur[1]=='I')&&(pcur[2]=='l'||pcur[2]=='L')&&(pcur[3]=='e'||pcur[0]=='E')){
|
||||
//m_Protocol.st=0; m_Protocol.len=4;
|
||||
m_nProto = file;
|
||||
p_pszData+=4;
|
||||
}else{
|
||||
throw 11;
|
||||
}
|
||||
if(*(p_pszData++)==':' && *(p_pszData++)=='/' && *(p_pszData++)=='/' ){}
|
||||
else
|
||||
throw 12;
|
||||
}
|
||||
|
||||
void JCUrl::parseUserPassHostPort(const char* p_pszData){
|
||||
const char* pColonPos=NULL;
|
||||
const char* pAtPos=NULL;
|
||||
const char* pCurData = p_pszData;
|
||||
while(true ){
|
||||
if(*pCurData==0){
|
||||
m_Host=pAtPos?(pAtPos):p_pszData;
|
||||
break;
|
||||
}
|
||||
if(*pCurData==':'){
|
||||
pColonPos=pCurData+1;
|
||||
if(pAtPos){//已经有@了,表示这是端口了
|
||||
m_Host = ""; m_Host.append(pAtPos,pCurData-pAtPos);
|
||||
m_Port = pColonPos;
|
||||
break;
|
||||
}
|
||||
}else if(*pCurData=='@'){//有用户信息
|
||||
pAtPos = pCurData+1;
|
||||
if(pColonPos){
|
||||
m_User="";m_User.append(p_pszData,pColonPos-p_pszData-1);
|
||||
m_Pass="";m_Pass.append(pColonPos, pCurData-pColonPos);
|
||||
}else{
|
||||
m_User="";m_User.append(p_pszData, pCurData-p_pszData);
|
||||
}
|
||||
}
|
||||
pCurData++;
|
||||
}
|
||||
}
|
||||
|
||||
void JCUrl::parsePath(const char* pData){
|
||||
m_vPath.clear();
|
||||
int datalen = strlen(pData);
|
||||
std::vector<int> parts = split(pData);
|
||||
if( parts.size()>0){
|
||||
//第一部分
|
||||
std::string cpath="";
|
||||
cpath.append(pData,parts[0]);
|
||||
if(cpath!=".")
|
||||
m_vPath.push_back(cpath);
|
||||
|
||||
bool bHasQuery=false;
|
||||
if(pData[parts[parts.size()-1]]=='?'){//query
|
||||
bHasQuery=true;
|
||||
int nQuerySt =parts[parts.size()-1];
|
||||
m_Query="";m_Query.append(pData+nQuerySt,datalen-nQuerySt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//中间
|
||||
for( int i=0,sz=parts.size()-1; i<sz; i++){
|
||||
cpath="";
|
||||
int l = (parts[i+1]-parts[i])-1;
|
||||
if(l<=0&&i!=0 && i!=sz-1){
|
||||
continue; //空的,通常是 //或者\\或者 /\什么的
|
||||
}
|
||||
cpath.append((char*)(pData+parts[i]+1),l);
|
||||
if(cpath==".."){
|
||||
if(m_vPath.size())
|
||||
m_vPath.pop_back();
|
||||
continue;
|
||||
}
|
||||
if(cpath!=".")
|
||||
m_vPath.push_back(cpath);
|
||||
}
|
||||
//剩余
|
||||
if(!bHasQuery){
|
||||
cpath="";
|
||||
cpath.append((char*)(pData+parts[parts.size()-1]+1),datalen-parts[parts.size()-1]-1);
|
||||
if(cpath==".."){
|
||||
if(m_vPath.size())
|
||||
m_vPath.pop_back();
|
||||
}else if(cpath!=".")
|
||||
m_vPath.push_back(cpath);
|
||||
}
|
||||
}else{
|
||||
m_vPath.push_back(pData);
|
||||
}
|
||||
pathToString(true);
|
||||
}
|
||||
|
||||
void JCUrl::pathToString(bool p_bAddFile){
|
||||
//计算空间
|
||||
m_strPath.clear();
|
||||
int nPathSize = 0;
|
||||
int nPathNum = m_vPath.size();
|
||||
if( !p_bAddFile && nPathNum==1){
|
||||
m_strPath="";
|
||||
return;
|
||||
}
|
||||
for( int i=0; i<nPathNum; i++){
|
||||
nPathSize+=m_vPath[i].length();
|
||||
}
|
||||
if( nPathSize>0){
|
||||
//if( m_vPath[nPathNum-1].length()==0) //最后一个是文件
|
||||
//TODO url可能最后是一个目录么?如果是的话怎么处理。按理说应该必须是一个文件。实际的目录自动加index.html是服务器端做得?
|
||||
m_strPath.append(m_vPath[0].c_str());
|
||||
for(int i=1; i<nPathNum-(p_bAddFile?0:1); i++){
|
||||
m_strPath.append("/",1);
|
||||
m_strPath.append(m_vPath[i].c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JCUrl::parseFile(const char*& p_pszData){
|
||||
}
|
||||
|
||||
void JCUrl::parseQuery(const char*& p_pszData){
|
||||
}
|
||||
|
||||
void JCUrl::parseSegment(const char*& p_pszData){
|
||||
}
|
||||
|
||||
bool JCUrl::parse(const char* p_pszUrl){
|
||||
if(p_pszUrl==NULL)
|
||||
return false;
|
||||
int len = strlen(p_pszUrl);
|
||||
try{
|
||||
m_vPath.clear();
|
||||
m_Host="";
|
||||
m_Port="";
|
||||
m_User="";
|
||||
m_Pass="";
|
||||
m_Query="";
|
||||
m_strProtHost="";
|
||||
m_bHasDriver=false;
|
||||
const char* pData = p_pszUrl;
|
||||
trim(pData);
|
||||
std::string tmpString;
|
||||
//如果是直接写路径的。缺省认为使用的是file
|
||||
if( pData[0]=='/'){
|
||||
tmpString = "file://";
|
||||
tmpString += pData;
|
||||
pData = tmpString.c_str();
|
||||
}
|
||||
else if( pData[1]==':'){
|
||||
tmpString = "file:///";
|
||||
tmpString += pData;
|
||||
pData = tmpString.c_str();
|
||||
}
|
||||
const char* pStart = pData;
|
||||
parseScheme(pData);
|
||||
m_strProtHost.append(pStart,pData-pStart);
|
||||
int datalen = strlen(pData);
|
||||
std::vector<int> parts = split(pData);
|
||||
if (parts.size() > 0) {
|
||||
//host
|
||||
//m_Host.st=0; m_Host.len=0;
|
||||
//m_Query.st=0; m_Query.len=0;
|
||||
if (parts[0] > 0) {//user,pass,host,port
|
||||
std::string uphp;
|
||||
uphp.append(pData, parts[0]);
|
||||
m_strProtHost.append(pData, parts[0]);
|
||||
parseUserPassHostPort(uphp.c_str());
|
||||
}
|
||||
|
||||
bool bHasQuery = false;
|
||||
int lastPos = parts[parts.size() - 1];
|
||||
if (pData[lastPos] == '?') {//query
|
||||
bHasQuery = true;
|
||||
//m_Query.st=nQuerySt;
|
||||
//m_Query.len=datalen-nQuerySt;
|
||||
//m_Path.st = parts[0];//包含 /
|
||||
//m_Path.len = parts[parts.size()-1]-m_Path.st;
|
||||
m_Query = ""; m_Query.append(pData + lastPos, datalen - lastPos);
|
||||
|
||||
}
|
||||
else {
|
||||
//m_Path.st = parts[0];
|
||||
//m_Path.len = datalen-m_Path.st;
|
||||
}
|
||||
|
||||
for (int i = 0, sz = parts.size() - 1; i < sz; i++) {
|
||||
std::string cpath = "";
|
||||
int l = (parts[i + 1] - parts[i]) - 1;
|
||||
if (l <= 0 && i != 0 && i != sz - 1) {
|
||||
continue; //空的,通常是 //或者\\或者 /\什么的
|
||||
}
|
||||
cpath.append((char*)(pData + parts[i] + 1), l);
|
||||
if (cpath == "..") {
|
||||
if (m_vPath.size())
|
||||
m_vPath.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (cpath != ".")
|
||||
m_vPath.push_back(cpath);
|
||||
}
|
||||
|
||||
if (!bHasQuery) {
|
||||
std::string cpath = "";
|
||||
cpath.append((char*)(pData + parts[parts.size() - 1] + 1), datalen - parts[parts.size() - 1] - 1);
|
||||
if (cpath == "..") {
|
||||
if (m_vPath.size())
|
||||
m_vPath.pop_back();
|
||||
}
|
||||
else if (cpath != ".")
|
||||
m_vPath.push_back(cpath);
|
||||
}
|
||||
if (m_vPath.size() > 0 && m_vPath[0].length() > 1 && m_vPath[0][1] == ':') {
|
||||
m_bHasDriver = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_strProtHost = p_pszUrl;
|
||||
parseUserPassHostPort(pData);
|
||||
}
|
||||
//合并path
|
||||
pathToString(false);
|
||||
if(m_strPath.length()>0){
|
||||
if(m_strPath[0]=='/'){
|
||||
m_strPath = m_strProtHost+m_strPath;
|
||||
}else{
|
||||
m_strPath = m_strProtHost+"/"+m_strPath;
|
||||
}
|
||||
}else{
|
||||
if(m_nProto==file)
|
||||
m_strPath = "file:///";
|
||||
else
|
||||
m_strPath = m_strProtHost;
|
||||
}
|
||||
}catch(int e){
|
||||
LOGE("JCUrl::parse error [%d]:%s",e, p_pszUrl );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string JCUrl::resolve(const char* p_pszPath){
|
||||
if(strstr(p_pszPath,"://")){
|
||||
JCUrl pathurl;
|
||||
pathurl.parse(p_pszPath);
|
||||
|
||||
if(pathurl.m_vPath.size()==1&&pathurl.m_Host.length()<=0)
|
||||
return pathurl.m_strPath+pathurl.m_vPath[pathurl.m_vPath.size()-1]+pathurl.m_Query; //file:///a.txt
|
||||
return pathurl.m_strPath+"/"+ (pathurl.m_vPath.size() > 0 ? pathurl.m_vPath[pathurl.m_vPath.size()-1] : "")+pathurl.m_Query; //file:///a/a.txt
|
||||
}
|
||||
JCUrl pathurl;
|
||||
pathurl.parsePath(p_pszPath);
|
||||
if( pathurl.m_vPath.size()>0){
|
||||
pathurl.pathToString(true);
|
||||
if(pathurl.m_vPath[0]=="" ){ //绝对路径
|
||||
if(m_bHasDriver){
|
||||
return m_strProtHost+"/"+m_vPath[0]+pathurl.m_strPath+pathurl.m_Query;
|
||||
}else
|
||||
return m_strProtHost+pathurl.m_strPath+pathurl.m_Query;
|
||||
}else if(pathurl.m_vPath[0].length()>1&&pathurl.m_vPath[0].at(1)==':'){//带盘符的
|
||||
return m_strProtHost+"/"+pathurl.m_strPath+pathurl.m_Query;
|
||||
}else{
|
||||
return m_strPath+"/"+pathurl.m_strPath+pathurl.m_Query;
|
||||
}
|
||||
}
|
||||
return m_strPath;
|
||||
}
|
||||
|
||||
std::string JCUrl::toString(){
|
||||
std::string ret = m_strPath +"/"+ (m_vPath.size()>0?m_vPath[m_vPath.size()-1]:"")+m_Query;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string JCUrl::encode2() {
|
||||
if (m_nProto == file || m_vPath.size()<=0) {
|
||||
return toString();
|
||||
}
|
||||
std::string ret = m_strPath + "/" + UrlEncode(m_vPath[m_vPath.size() - 1].c_str());
|
||||
if (m_Query.length() > 0) {
|
||||
ret += "?";
|
||||
ret += UrlEncode(m_Query.substr(1, m_Query.length() - 1).c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
@file JCLayaUrl.h
|
||||
@brief
|
||||
@author hugao
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#ifndef __JCLayaUrl_H__
|
||||
#define __JCLayaUrl_H__
|
||||
|
||||
/*
|
||||
解析url。
|
||||
可以用第三方库:例如 google url, cpp-netlib等。不过使用太麻烦,这里简单写一个,注意并不完全符合标准。
|
||||
标准为:
|
||||
http://www.ietf.org/rfc/rfc1738.txt
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace laya{
|
||||
class JCUrl{
|
||||
public:
|
||||
//struct part{short st,len;};
|
||||
enum protocol{
|
||||
http, // http://
|
||||
https,
|
||||
ftp, // ftp://
|
||||
file, // file://
|
||||
//barefile,//c:/ 没有file的形式
|
||||
unk,
|
||||
};
|
||||
|
||||
public:
|
||||
JCUrl();
|
||||
JCUrl(const char* p_pszUrl);
|
||||
~JCUrl();
|
||||
|
||||
bool parse(const char* p_pszUrl);
|
||||
|
||||
std::string resolve(const char* p_pszPath);
|
||||
std::string toString();
|
||||
|
||||
void parsePath(const char* p_pszData);
|
||||
void pathToString(bool p_bAddFile);
|
||||
const char* getProtocolString();
|
||||
std::string encode2();
|
||||
protected:
|
||||
void trim(const char*& p_pszData);
|
||||
void parseScheme(const char*& p_pszData);
|
||||
void parseFile(const char*& p_pszData);
|
||||
void parseQuery(const char*& p_pszData);
|
||||
void parseSegment(const char*& p_pszData);
|
||||
void parseUserPassHostPort(const char* p_pszData);
|
||||
//用几个关键符号拆分。/?
|
||||
//从host位置开始。
|
||||
std::vector<int> split(const char* p_pszData);
|
||||
public:
|
||||
char* m_pszUrl;
|
||||
int m_nUrlSize;
|
||||
protocol m_nProto;
|
||||
/*
|
||||
part m_Protocol;
|
||||
part m_User;
|
||||
part m_Host;
|
||||
part m_Port;
|
||||
part m_Path;
|
||||
part m_File;
|
||||
part m_Query;
|
||||
part m_Segmet;//TODO 还没做
|
||||
*/
|
||||
std::string m_User,m_Pass,m_Host,m_Port,m_Query;
|
||||
/*
|
||||
对于有协议的,肯定是从根路径开始。因此m_vPath[0]要么是驱动器,要么是第一层目录,不需要是 /
|
||||
m_vPath[0] 总是驱动器,或者第一层目录
|
||||
m_vPath[最后] 可能是文件也可能是目录,如果最后是 /?xx=xx 则是空字符""
|
||||
*/
|
||||
std::vector<std::string> m_vPath;
|
||||
std::string m_strPath;//保存一个完整的path,用来快速合并。
|
||||
std::string m_strProtHost;
|
||||
bool m_bHasDriver;
|
||||
//Path m_Path;
|
||||
};
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCLayaUrl_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
@file JCMemorySurvey.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_5_13
|
||||
*/
|
||||
|
||||
//包含头文件
|
||||
#include "JCMemorySurvey.h"
|
||||
#include "Log.h"
|
||||
#include "../fileSystem/JCFileSystem.h"
|
||||
|
||||
namespace laya
|
||||
{
|
||||
JCMemorySurvey* JCMemorySurvey::ms_pMemorySurvey = NULL;
|
||||
//------------------------------------------------------------------------------
|
||||
JCMemorySurvey::JCMemorySurvey()
|
||||
{
|
||||
m_bEnable = false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCMemorySurvey::~JCMemorySurvey()
|
||||
{
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::setEnable(bool bEnable)
|
||||
{
|
||||
m_bEnable = bEnable;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCMemorySurvey* JCMemorySurvey::GetInstance()
|
||||
{
|
||||
if( ms_pMemorySurvey == NULL )
|
||||
{
|
||||
ms_pMemorySurvey = new JCMemorySurvey();
|
||||
}
|
||||
return ms_pMemorySurvey;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::DelInstance()
|
||||
{
|
||||
if( ms_pMemorySurvey )
|
||||
{
|
||||
delete ms_pMemorySurvey;
|
||||
ms_pMemorySurvey = NULL;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::newClass( const char* p_sClassName,int p_nMemorySize,void* p_nThis,int p_nID )
|
||||
{
|
||||
if (m_bEnable)
|
||||
{
|
||||
long nThis = (long)p_nThis;
|
||||
MapMemoryInfoIter iter = m_vMapMemoryInfos.find(nThis);
|
||||
if (iter != m_vMapMemoryInfos.end())
|
||||
{
|
||||
LOGI("JCMemorySurvey::newClass error");
|
||||
return;
|
||||
}
|
||||
MemorySurveyInfo* pInfo = new MemorySurveyInfo();
|
||||
pInfo->m_nID = p_nID;
|
||||
pInfo->m_nMemorySize = p_nMemorySize;
|
||||
pInfo->m_sClassName = p_sClassName;
|
||||
pInfo->m_nThis = nThis;
|
||||
m_vMapMemoryInfos[pInfo->m_nThis] = pInfo;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::releaseClass( const char* p_sClassName,void* p_nThis )
|
||||
{
|
||||
if (m_bEnable)
|
||||
{
|
||||
long nThis = (long)p_nThis;
|
||||
MapMemoryInfoIter iter = m_vMapMemoryInfos.find(nThis);
|
||||
if (iter != m_vMapMemoryInfos.end())
|
||||
{
|
||||
MemorySurveyInfo* pInfo = iter->second;
|
||||
if (pInfo != NULL)
|
||||
{
|
||||
delete pInfo;
|
||||
pInfo = NULL;
|
||||
}
|
||||
iter = m_vMapMemoryInfos.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGI("JCMemorySurvey::releaseClass error className=%s,p_nThis=%d", p_sClassName, p_nThis);
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
MemoryStatistics* JCMemorySurvey::getMemoryStatistics( const char* p_sClassName )
|
||||
{
|
||||
for( int i = 0 ; i < (int)(m_vVectorMemoryStatistics.size()); i++ )
|
||||
{
|
||||
if( strcmp( m_vVectorMemoryStatistics[i]->m_sClassName.c_str(),p_sClassName ) == 0 )
|
||||
{
|
||||
return m_vVectorMemoryStatistics[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::clearAllMemoryStatistics()
|
||||
{
|
||||
for( int i = 0 ; i < (int)(m_vVectorMemoryStatistics.size()); i++ )
|
||||
{
|
||||
MemoryStatistics* pStatis = m_vVectorMemoryStatistics[i];
|
||||
if( pStatis != NULL )
|
||||
{
|
||||
delete pStatis;
|
||||
pStatis = NULL;
|
||||
}
|
||||
}
|
||||
m_vVectorMemoryStatistics.clear();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::statisticsMemory()
|
||||
{
|
||||
clearAllMemoryStatistics();
|
||||
for( MapMemoryInfoIter iter = m_vMapMemoryInfos.begin(); iter != m_vMapMemoryInfos.end(); iter++ )
|
||||
{
|
||||
MemorySurveyInfo* pInfo = iter->second;
|
||||
if( pInfo != NULL )
|
||||
{
|
||||
MemoryStatistics* pStatis = getMemoryStatistics( pInfo->m_sClassName.c_str() );
|
||||
if( pStatis != NULL )
|
||||
{
|
||||
pStatis->m_nCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
pStatis = new MemoryStatistics();
|
||||
pStatis->m_nCount = 1;
|
||||
pStatis->m_nMemorySize = pInfo->m_nMemorySize;
|
||||
pStatis->m_sClassName = pInfo->m_sClassName;
|
||||
m_vVectorMemoryStatistics.push_back( pStatis );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::printMemorySurveyInfo( const char* p_sPath )
|
||||
{
|
||||
std::string sBuffer = "";
|
||||
for( MapMemoryInfoIter iter = m_vMapMemoryInfos.begin(); iter != m_vMapMemoryInfos.end(); iter++ )
|
||||
{
|
||||
MemorySurveyInfo* pInfo = iter->second;
|
||||
if( pInfo != NULL )
|
||||
{
|
||||
char sTemp[1024] = {0};
|
||||
sprintf( sTemp,"class=%s,id=%d,this=%ld,size=%d\r\n",pInfo->m_sClassName.c_str(),pInfo->m_nID,pInfo->m_nThis,pInfo->m_nMemorySize );
|
||||
sBuffer += sTemp;
|
||||
}
|
||||
}
|
||||
std::string sPath = p_sPath;
|
||||
sPath += "/memorySurvey.txt";
|
||||
JCBuffer buf((char*)sBuffer.c_str(), strlen(sBuffer.c_str()),false,false);
|
||||
writeFileSync( sPath.c_str(),buf );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::printMemoryStatis( const char* p_sPath)
|
||||
{
|
||||
statisticsMemory();
|
||||
std::string sBuffer = "";
|
||||
int nCount = 0;
|
||||
for( int i = 0 ; i < (int)(m_vVectorMemoryStatistics.size()); i++ )
|
||||
{
|
||||
MemoryStatistics* pInfo = m_vVectorMemoryStatistics[i];
|
||||
if( pInfo != NULL )
|
||||
{
|
||||
char sTemp[1024] = {0};
|
||||
sprintf( sTemp,"count=%d\t,class=%s\t,size=%d,countSize=%d\r\n",pInfo->m_nCount,pInfo->m_sClassName.c_str(),pInfo->m_nMemorySize,pInfo->m_nCount*pInfo->m_nMemorySize );
|
||||
LOGI("printMemoryStatis size=%d,%s",m_vVectorMemoryStatistics.size(),sTemp);
|
||||
sBuffer += sTemp;
|
||||
nCount += pInfo->m_nCount*pInfo->m_nMemorySize;
|
||||
}
|
||||
}
|
||||
char sTemp1[1024] = { 0 };
|
||||
sprintf( sTemp1,"Dynamic Object memory around=%5.2fMB\r\n" ,(float)(nCount/1024.0f/1024.0f) );
|
||||
LOGI("%s",sTemp1);
|
||||
sBuffer += sTemp1;
|
||||
|
||||
std::string sPath = p_sPath;
|
||||
sPath += "/memoryStatis.txt";
|
||||
JCBuffer buf((char*)sBuffer.c_str(), strlen(sBuffer.c_str()),false,false);
|
||||
writeFileSync( sPath.c_str(),buf );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void JCMemorySurvey::printAll(const char* p_sPath)
|
||||
{
|
||||
if (m_bEnable)
|
||||
{
|
||||
//printMemorySurveyInfo(p_sPath);
|
||||
printMemoryStatis(p_sPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOGE("JCMemorySurvey::printAll error enable=false.");
|
||||
LOGE("You can set it by method. 'conch.config.enableMemorySurvey(true);'");
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
@file JCMemorySurvey.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_5_13
|
||||
*/
|
||||
|
||||
#ifndef __JCMemorySurvey_H__
|
||||
#define __JCMemorySurvey_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
struct MemorySurveyInfo
|
||||
{
|
||||
long m_nThis; //作为类的指针数据,这个值作为key
|
||||
int m_nID;
|
||||
std::string m_sClassName;
|
||||
int m_nMemorySize;
|
||||
};
|
||||
struct MemoryStatistics
|
||||
{
|
||||
std::string m_sClassName;
|
||||
int m_nCount;
|
||||
int m_nMemorySize;
|
||||
};
|
||||
/**
|
||||
* @brief 统计对象内存用的
|
||||
*/
|
||||
class JCMemorySurvey
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::map<long,MemorySurveyInfo*> MapMemoryInfo;
|
||||
typedef MapMemoryInfo::iterator MapMemoryInfoIter;
|
||||
|
||||
typedef std::vector<MemoryStatistics*> VectorMemoryStatistics;
|
||||
typedef VectorMemoryStatistics::iterator VectorMemoryStatisticsIter;
|
||||
|
||||
public:
|
||||
|
||||
JCMemorySurvey();
|
||||
|
||||
~JCMemorySurvey();
|
||||
|
||||
static JCMemorySurvey* GetInstance();
|
||||
static void DelInstance();
|
||||
|
||||
public:
|
||||
|
||||
void newClass( const char* p_sClassName,int p_nMemorySize,void* p_nThis,int p_nID = 0 );
|
||||
|
||||
void releaseClass( const char* p_sClassName,void* p_nThis );
|
||||
|
||||
void printAll( const char* p_sPath);
|
||||
|
||||
void setEnable( bool bEnable );
|
||||
|
||||
protected:
|
||||
|
||||
void statisticsMemory();
|
||||
|
||||
void printMemorySurveyInfo( const char* p_sPath );
|
||||
|
||||
void printMemoryStatis(const char* p_sPath);
|
||||
|
||||
private:
|
||||
|
||||
MemoryStatistics* getMemoryStatistics( const char* p_sClassName );
|
||||
|
||||
void clearAllMemoryStatistics();
|
||||
|
||||
public:
|
||||
|
||||
static JCMemorySurvey* ms_pMemorySurvey;
|
||||
|
||||
MapMemoryInfo m_vMapMemoryInfos;
|
||||
|
||||
VectorMemoryStatistics m_vVectorMemoryStatistics;
|
||||
|
||||
bool m_bEnable;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__JCMemorySurvey_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
@file JCSimpleCRC.h
|
||||
@brief
|
||||
@author hugao
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#ifndef __JCSimpleCRC_H__
|
||||
#define __JCSimpleCRC_H__
|
||||
|
||||
|
||||
class JCSimpleCRC
|
||||
{
|
||||
private:
|
||||
long long m_i64Key;
|
||||
public:
|
||||
JCSimpleCRC()
|
||||
{
|
||||
m_i64Key = 0;
|
||||
}
|
||||
void process_bytes( const void *p_pBuffer, size_t p_iSize )
|
||||
{
|
||||
long long *pBuf64=(long long *)p_pBuffer;
|
||||
for(size_t i=0,isz=p_iSize/8; i<isz; i++,pBuf64++)
|
||||
{
|
||||
m_i64Key ^= *pBuf64;
|
||||
}
|
||||
for(size_t i=p_iSize/8*8; i<p_iSize; i++)
|
||||
{
|
||||
m_i64Key ^= ((const unsigned char *)p_pBuffer)[i];
|
||||
}
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
m_i64Key = 0;
|
||||
}
|
||||
unsigned int checksum()
|
||||
{
|
||||
unsigned int lRet = 0;
|
||||
unsigned int *p = (unsigned int *)&m_i64Key;
|
||||
lRet ^= *p;
|
||||
lRet ^= *(p+1);
|
||||
return lRet;
|
||||
}
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCSimpleCRC_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,320 @@
|
||||
/**
|
||||
@file JCJson.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_6_17
|
||||
*/
|
||||
|
||||
#include "JCXml.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
XmlNode::XmlNode( XmlNode* p_pParent )
|
||||
{
|
||||
m_pParentNode = p_pParent;
|
||||
m_sNodeName = NULL;
|
||||
m_sValue = NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
XmlNode::~XmlNode()
|
||||
{
|
||||
m_pParentNode = NULL;
|
||||
m_sNodeName = NULL;
|
||||
m_sValue = NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
int XmlNode::getIntForKey( const char* p_sValue )
|
||||
{
|
||||
for( int i = 0,nSize=(int)(m_vChildNodes.size());i < nSize; i++ )
|
||||
{
|
||||
if ( strcmp( m_vChildNodes[i]->m_sNodeName,"key" ) == 0 &&
|
||||
strcmp( m_vChildNodes[i]->m_sValue,p_sValue ) == 0 )
|
||||
{
|
||||
if( m_vChildNodes[i+1] != NULL )
|
||||
{
|
||||
return atoi( m_vChildNodes[i+1]->m_sValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
char* XmlNode::getStringForKey( const char* p_sValue )
|
||||
{
|
||||
for( int i = 0,nSize=(int)(m_vChildNodes.size());i < nSize; i++ )
|
||||
{
|
||||
if ( strcmp( m_vChildNodes[i]->m_sNodeName,"key" ) == 0 &&
|
||||
strcmp( m_vChildNodes[i]->m_sValue,p_sValue ) == 0 )
|
||||
{
|
||||
if( m_vChildNodes[i+1] != NULL )
|
||||
{
|
||||
return m_vChildNodes[i+1]->m_sValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
float XmlNode::getFloatForKey( const char* p_sValue )
|
||||
{
|
||||
for( int i = 0,nSize=(int)(m_vChildNodes.size());i < nSize; i++ )
|
||||
{
|
||||
if ( strcmp( m_vChildNodes[i]->m_sNodeName,"key" ) == 0 &&
|
||||
strcmp( m_vChildNodes[i]->m_sValue,p_sValue ) == 0 )
|
||||
{
|
||||
if( m_vChildNodes[i+1] != NULL )
|
||||
{
|
||||
return (float)(atof( m_vChildNodes[i+1]->m_sValue ));
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool XmlNode::getBoolForKey( const char* p_sValue )
|
||||
{
|
||||
for( int i = 0,nSize=(int)(m_vChildNodes.size());i < nSize; i++ )
|
||||
{
|
||||
if ( strcmp( m_vChildNodes[i]->m_sNodeName,"key" ) == 0 &&
|
||||
strcmp( m_vChildNodes[i]->m_sValue,p_sValue ) == 0 )
|
||||
{
|
||||
if( m_vChildNodes[i+1] != NULL )
|
||||
{
|
||||
if( strstr( m_vChildNodes[i+1]->m_sValue,"true" ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
XmlNode* XmlNode::getNodeForKey( const char* p_sValue )
|
||||
{
|
||||
for( int i = 0,nSize=(int)(m_vChildNodes.size());i < nSize; i++ )
|
||||
{
|
||||
if ( strcmp( m_vChildNodes[i]->m_sNodeName,"key" ) == 0 &&
|
||||
strcmp( m_vChildNodes[i]->m_sValue,p_sValue ) == 0 )
|
||||
{
|
||||
if( m_vChildNodes[i+1] != NULL )
|
||||
{
|
||||
return m_vChildNodes[i+1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void XmlNode::setName( char* p_sName )
|
||||
{
|
||||
m_sNodeName = p_sName;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void XmlNode::setValue( char* p_sValue )
|
||||
{
|
||||
m_sValue = p_sValue;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void XmlNode::addChild( XmlNode* p_pNode )
|
||||
{
|
||||
m_vChildNodes.push_back( p_pNode );
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool XmlNode::clearChild()
|
||||
{
|
||||
for( int i = 0,nSize = (int)(m_vChildNodes.size()); i < nSize; i++ )
|
||||
{
|
||||
if( m_vChildNodes[i] != NULL )
|
||||
{
|
||||
m_vChildNodes[i]->clearChild();
|
||||
delete m_vChildNodes[i];
|
||||
m_vChildNodes[i] = NULL;
|
||||
}
|
||||
}
|
||||
m_vChildNodes.clear();
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCXml::JCXml()
|
||||
{
|
||||
m_pRoot = NULL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
JCXml::~JCXml()
|
||||
{
|
||||
cleanUp();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool JCXml::cleanUp()
|
||||
{
|
||||
if( m_pRoot != NULL )
|
||||
{
|
||||
m_pRoot->clearChild();
|
||||
delete m_pRoot;
|
||||
m_pRoot = NULL;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
XmlNode* JCXml::getRoot()
|
||||
{
|
||||
return m_pRoot;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
bool JCXml::loadXml( char* p_sBuffer )
|
||||
{
|
||||
if( p_sBuffer == NULL )return false;
|
||||
if( m_pRoot == NULL )
|
||||
{
|
||||
m_pRoot = new XmlNode( NULL );
|
||||
}
|
||||
int nBufferSize = strlen( p_sBuffer );
|
||||
|
||||
int i = 0;
|
||||
while( i < nBufferSize )
|
||||
{
|
||||
if( p_sBuffer[i] == '<' )
|
||||
{
|
||||
if( p_sBuffer[i+1] != '?' && p_sBuffer[i+1] != '!' )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
int nOffset = i;
|
||||
paserXml( p_sBuffer,nBufferSize,nOffset,m_pRoot );
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
int JCXml::paserXml( char* p_sBuffer,int p_nBufferSize,int p_nOffset,XmlNode* p_pNode )
|
||||
{
|
||||
if( p_pNode == NULL ) return p_nOffset;
|
||||
if( p_nOffset >= p_nBufferSize ) return p_nOffset;
|
||||
int i = p_nOffset;
|
||||
|
||||
int nState = 0;
|
||||
char* sName = NULL; //名字
|
||||
char* sMatchingName = NULL; //要匹配的名字
|
||||
char* sValue = NULL; //值
|
||||
|
||||
while( i < p_nBufferSize )
|
||||
{
|
||||
if( nState == 0 )
|
||||
{
|
||||
if( p_sBuffer[i] == '<' )
|
||||
{
|
||||
if( p_sBuffer[i+1] == '/' )
|
||||
{
|
||||
nState = 3;
|
||||
i++;
|
||||
sMatchingName = ( p_sBuffer + i + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
nState = 1;
|
||||
sName = ( p_sBuffer + i + 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( nState == 1 )
|
||||
{
|
||||
if( p_sBuffer[i] == '>' )
|
||||
{
|
||||
nState = 2;
|
||||
p_sBuffer[i] = 0;
|
||||
p_pNode->setName( sName );
|
||||
sValue = (p_sBuffer + i + 1 );
|
||||
}
|
||||
}
|
||||
else if( nState == 2 )
|
||||
{
|
||||
if( p_sBuffer[i] == '<' )
|
||||
{
|
||||
//证明闭合了
|
||||
if( p_sBuffer[i+1] == '/' )
|
||||
{
|
||||
p_sBuffer[i] = 0;
|
||||
i++;
|
||||
sMatchingName = ( p_sBuffer + i + 1 );
|
||||
nState = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
//又找到新的node
|
||||
XmlNode* pNewNode = new XmlNode( p_pNode );
|
||||
p_pNode->addChild( pNewNode );
|
||||
i = paserXml( p_sBuffer,p_nBufferSize,i,pNewNode );
|
||||
//恢复数据
|
||||
{
|
||||
nState = 0;
|
||||
sName = NULL;
|
||||
sMatchingName = NULL;
|
||||
sValue = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( nState == 3 )
|
||||
{
|
||||
if( p_sBuffer[i] == '>' )
|
||||
{
|
||||
p_sBuffer[i] = 0;
|
||||
if( strcmp( p_pNode->m_sNodeName,sMatchingName ) == 0 )
|
||||
{
|
||||
p_pNode->setValue( sValue );
|
||||
//恢复数据
|
||||
{
|
||||
p_pNode = p_pNode->m_pParentNode;
|
||||
nState = 2;
|
||||
sName = NULL;
|
||||
sMatchingName = NULL;
|
||||
sValue = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( p_pNode->m_pParentNode != NULL )
|
||||
{
|
||||
if( strcmp( p_pNode->m_pParentNode->m_sNodeName,sMatchingName ) == 0 )
|
||||
{
|
||||
return ++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
@file JCXml.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2014_6_17
|
||||
*/
|
||||
|
||||
#ifndef __JCXml_H__
|
||||
#define __JCXml_H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <string.h>
|
||||
#pragma warning (disable: 4996)
|
||||
|
||||
namespace laya
|
||||
{
|
||||
|
||||
class XmlNode
|
||||
{
|
||||
public:
|
||||
|
||||
typedef std::vector<XmlNode*> VectorXmlNode;
|
||||
typedef VectorXmlNode::iterator VectorXmlNodeIter;
|
||||
|
||||
public:
|
||||
|
||||
XmlNode( XmlNode* p_pParent );
|
||||
|
||||
~XmlNode();
|
||||
|
||||
int getIntForKey( const char* p_sValue );
|
||||
|
||||
char* getStringForKey( const char* p_sValue );
|
||||
|
||||
float getFloatForKey( const char* p_sValue );
|
||||
|
||||
bool getBoolForKey( const char* p_sValue );
|
||||
|
||||
XmlNode* getNodeForKey( const char* p_sValue );
|
||||
|
||||
public:
|
||||
|
||||
void setName( char* p_sName );
|
||||
|
||||
void setValue( char* p_sValue );
|
||||
|
||||
void addChild( XmlNode* p_pNode );
|
||||
|
||||
bool clearChild();
|
||||
|
||||
public:
|
||||
|
||||
char* m_sNodeName;
|
||||
char* m_sValue;
|
||||
XmlNode* m_pParentNode;
|
||||
VectorXmlNode m_vChildNodes;
|
||||
};
|
||||
|
||||
class JCXml
|
||||
{
|
||||
public:
|
||||
|
||||
JCXml();
|
||||
|
||||
~JCXml();
|
||||
|
||||
bool cleanUp();
|
||||
|
||||
bool loadXml( char* p_sBuffer );
|
||||
|
||||
int paserXml( char* p_sBuffer,int p_nBufferSize,int p_nOffset,XmlNode* p_pNode );
|
||||
|
||||
XmlNode* getRoot();
|
||||
|
||||
private:
|
||||
|
||||
XmlNode* m_pRoot;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif //__JCXml_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
@file JCZipFile.cpp
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#include "JCZipFile.h"
|
||||
#include "Log.h"
|
||||
|
||||
namespace laya
|
||||
{
|
||||
JCZipFile::JCZipFile(){
|
||||
m_pZip = NULL;
|
||||
}
|
||||
JCZipFile::~JCZipFile(){
|
||||
if(m_pZip){
|
||||
zip_close(m_pZip);
|
||||
}
|
||||
}
|
||||
bool JCZipFile::open(const char* p_pZipFile ){
|
||||
int err = 0;
|
||||
m_pZip = zip_open( p_pZipFile, 0, &err);
|
||||
if( err ){
|
||||
LOGI("open zip %s failed erro code %d",p_pZipFile,err);
|
||||
m_pZip = NULL;
|
||||
}
|
||||
return m_pZip!=NULL;
|
||||
}
|
||||
void JCZipFile::InitDir(const char* p_pszDir ){
|
||||
m_sInitDir = p_pszDir;
|
||||
}
|
||||
bool JCZipFile::getSize(const char* p_pszFile, int& p_nSize, int& p_nCompSize ){
|
||||
if( !m_pZip )
|
||||
return false;
|
||||
struct zip_stat st;
|
||||
zip_stat_init(&st);
|
||||
std::string file = p_pszFile;
|
||||
if(m_sInitDir.size() > 0 )
|
||||
{
|
||||
file = m_sInitDir + "/" + p_pszFile;
|
||||
}
|
||||
zip_stat(m_pZip, file.c_str(), 0, &st);
|
||||
p_nSize = (int)(st.size);
|
||||
p_nCompSize = (int)(st.comp_size);
|
||||
return true;
|
||||
}
|
||||
bool JCZipFile::read(const char* p_pszFile, const char* p_pBuff, int p_nBufSize ){
|
||||
if( !m_pZip )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
bool JCZipFile::isFileExist( const char* p_pszFile){
|
||||
int sz=0;
|
||||
int compsz=0;
|
||||
getSize(p_pszFile,sz,compsz);
|
||||
return sz>0;
|
||||
}
|
||||
unsigned int JCZipFile::getFileSize( const char* p_pszFile ){
|
||||
int sz=0;
|
||||
int compsz=0;
|
||||
getSize(p_pszFile,sz,compsz);
|
||||
return sz;
|
||||
}
|
||||
bool JCZipFile::loadFileContent( const char* p_pszFile, char*& p_pBuff, int& p_iBuffSize ){
|
||||
p_iBuffSize = 0;
|
||||
int sz = 0;
|
||||
int compsz = 0;
|
||||
getSize(p_pszFile, sz, compsz);
|
||||
if (sz <= 0)
|
||||
return false;
|
||||
p_iBuffSize = sz;
|
||||
std::string file = p_pszFile;
|
||||
if (m_sInitDir.size() > 0) {
|
||||
file = m_sInitDir + "/" + p_pszFile;
|
||||
}
|
||||
zip_file *f = zip_fopen(m_pZip, file.c_str(), 0);
|
||||
p_pBuff = new char[sz+1];
|
||||
zip_fread(f, p_pBuff, sz);
|
||||
zip_fclose(f);
|
||||
p_pBuff[sz] = 0;
|
||||
return true;
|
||||
}
|
||||
bool JCZipFile::loadFileContent(const char* p_pszFile, ALLOCMEM alloc, void* pUserData, int& p_iBuffSize) {
|
||||
p_iBuffSize = 0;
|
||||
int sz = 0;
|
||||
int compsz = 0;
|
||||
getSize(p_pszFile, sz, compsz);
|
||||
if (sz <= 0)
|
||||
return false;
|
||||
p_iBuffSize = sz;
|
||||
std::string file = p_pszFile;
|
||||
if (m_sInitDir.size() > 0){
|
||||
file = m_sInitDir + "/" + p_pszFile;
|
||||
}
|
||||
zip_file *f = zip_fopen(m_pZip, file.c_str(), 0);
|
||||
unsigned char* pBuf = alloc(sz, pUserData);
|
||||
zip_fread(f, pBuf, sz);
|
||||
zip_fclose(f);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
@file JCZipFile.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
#ifndef __JCZipFile_H__
|
||||
#define __JCZipFile_H__
|
||||
|
||||
#include "../downloadCache/JCFileSource.h"
|
||||
#include <zip.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
class JCZipFile: public JCFileSource
|
||||
{
|
||||
public:
|
||||
|
||||
JCZipFile();
|
||||
|
||||
~JCZipFile();
|
||||
|
||||
bool open(const char* p_pZipFile );
|
||||
|
||||
void InitDir(const char* p_pszDir);
|
||||
|
||||
bool getSize(const char* p_pszFile, int& p_nSize, int& p_nCompSize );
|
||||
|
||||
bool read(const char* p_pszFile, const char* p_pBuff, int p_nBufSize );
|
||||
|
||||
public:
|
||||
virtual bool isFileExistInZipAPKExpansion(const char* sFileName) { return false; };
|
||||
|
||||
virtual bool isFileExist( const char* p_pszFile);
|
||||
|
||||
virtual unsigned int getFileSize( const char* p_pszFile );
|
||||
|
||||
virtual bool loadFileContent(const char* sFileName, ALLOCMEM pAllocFunc, void* pUserData, int& nBuffSize);
|
||||
|
||||
virtual bool loadFileContent(const char* sFileName, char*& pBuffer, int& nBuffSize);
|
||||
|
||||
protected:
|
||||
|
||||
zip* m_pZip;
|
||||
|
||||
std::string m_sInitDir;
|
||||
|
||||
};
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCZipFile_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
@file JCZlib.cpp
|
||||
@brief
|
||||
@author hugao
|
||||
@version 1.0
|
||||
@date 2016_5_13
|
||||
*/
|
||||
|
||||
#include "JCZlib.h"
|
||||
#include <string>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
//------------------------------------------------------------------------------
|
||||
uLong getLayaBoxUncompressSize(unsigned char* p_sBuffer, int buflen, int& p_nOffset)
|
||||
{
|
||||
if (p_sBuffer == NULL) return 0;
|
||||
if (buflen<24) return 0;
|
||||
//我们特有的头 LayaBoxCompress=true
|
||||
char sHead[21];
|
||||
memset(sHead, 0, 21);
|
||||
memcpy(sHead, p_sBuffer, sizeof(char) * 20);
|
||||
|
||||
if (strcmp(sHead, "LayaBoxCompress=true") == 0)
|
||||
{
|
||||
uLong nUncompressSize = *(int*)(p_sBuffer + 20);
|
||||
p_nOffset = 20 + 4;
|
||||
return nUncompressSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned char* zlibByteArrayCompress(unsigned char* p_sBuffer, int buflen, int &realCount)
|
||||
{
|
||||
uLong tlen = buflen;
|
||||
z_stream zs;
|
||||
int err;
|
||||
memset(&zs, 0, sizeof(zs));
|
||||
if (deflateInit(&zs, 9))
|
||||
{
|
||||
printf("deflateInit() failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
uLong blen = deflateBound(&zs, tlen);
|
||||
unsigned char* sUCBuffer = new unsigned char[blen];
|
||||
zs.avail_in = buflen;
|
||||
zs.avail_out = blen;
|
||||
zs.next_in = p_sBuffer;
|
||||
zs.next_out = sUCBuffer;
|
||||
|
||||
while (zs.total_in != buflen&&zs.total_out < blen)
|
||||
{
|
||||
zs.avail_in = zs.avail_out = buflen;
|
||||
err = deflate(&zs, Z_NO_FLUSH);
|
||||
}
|
||||
int status = deflate(&zs, Z_NO_FLUSH);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
zs.avail_out = blen;
|
||||
err = deflate(&zs, Z_FINISH);
|
||||
if (err == Z_STREAM_END)break;
|
||||
if (err != Z_OK)
|
||||
{
|
||||
printf("deflateEnd() failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (deflateEnd(&zs) != Z_OK)
|
||||
{
|
||||
printf("deflateEnd() failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
realCount = zs.total_out;
|
||||
return sUCBuffer;
|
||||
|
||||
|
||||
/*uLong tlen = buflen;
|
||||
uLong blen = compressBound(tlen);
|
||||
unsigned char* sUCBuffer = new unsigned char[blen];
|
||||
if (compress(sUCBuffer, &blen, p_sBuffer, tlen) != Z_OK)
|
||||
{
|
||||
printf("compress failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
realCount = blen;
|
||||
return sUCBuffer;
|
||||
}*/
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned char* zlibByteArrayUnCompress(unsigned char* p_sBuffer, int buflen, int &realCount)
|
||||
{
|
||||
uLong tlen = buflen;
|
||||
z_stream zs;
|
||||
memset(&zs, 0, sizeof(zs));
|
||||
//uLong blen = deflateBound(&zs, tlen);
|
||||
unsigned char* sUCBuffer = new unsigned char[1024];
|
||||
unsigned char* pCurBuff = sUCBuffer;
|
||||
int curOutBuffSz = 1024;
|
||||
unsigned char buf[1024];
|
||||
zs.avail_in = buflen;
|
||||
zs.avail_out = 1024;
|
||||
zs.next_in = p_sBuffer;
|
||||
zs.next_out = buf;
|
||||
if (inflateInit(&zs))
|
||||
{
|
||||
printf("inflateInit() failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
while (zs.avail_in > 0)
|
||||
{
|
||||
int status = inflate(&zs, Z_NO_FLUSH);
|
||||
if (zs.avail_in != 0)
|
||||
{
|
||||
unsigned char* old = sUCBuffer;
|
||||
curOutBuffSz += 1024;
|
||||
sUCBuffer = new unsigned char[curOutBuffSz];
|
||||
memcpy(sUCBuffer, old, zs.total_out - 1024);
|
||||
memcpy(sUCBuffer + zs.total_out - 1024, buf, 1024);
|
||||
pCurBuff = sUCBuffer + zs.total_out;
|
||||
delete[] old;
|
||||
zs.next_out = buf;
|
||||
zs.avail_out = 1024;
|
||||
}
|
||||
else {
|
||||
memcpy(pCurBuff, buf, 1024 - zs.avail_out);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (inflateEnd(&zs) != Z_OK)
|
||||
{
|
||||
printf("deflateEnd() failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
realCount = zs.total_out;
|
||||
return sUCBuffer;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
@file JCZlib.h
|
||||
@brief
|
||||
@author hugao
|
||||
@version 1.0
|
||||
@date 2016_5_13
|
||||
*/
|
||||
|
||||
#ifndef __JCZlib_H__
|
||||
#define __JCZlib_H__
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#define MAX_CHARACTER_SIZE 8
|
||||
|
||||
namespace laya
|
||||
{
|
||||
/** @brief 获得文件解压开后的大小
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @param[in]
|
||||
* @return
|
||||
*/
|
||||
uLong getLayaBoxUncompressSize(unsigned char* p_sBuffer, int buflen, int& p_nOffset);
|
||||
|
||||
|
||||
/** @brief 压缩文件
|
||||
* @param[in] 输入的数据流
|
||||
* @param[in] 数据流大小
|
||||
* @param[out] 返回的大小
|
||||
* @return 返回的数据流
|
||||
*/
|
||||
unsigned char* zlibByteArrayCompress(unsigned char* p_sBuffer, int buflen, int &realCount);
|
||||
|
||||
/** @brief 解压文件
|
||||
* @param[in] 输入的数据流
|
||||
* @param[in] 数据流大小
|
||||
* @param[out] 返回的大小
|
||||
* @return 返回的数据流
|
||||
*/
|
||||
unsigned char* zlibByteArrayUnCompress(unsigned char* p_sBuffer, int buflen, int &realCount);
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__JCZlib_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
@file ListNode.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2016_5_12
|
||||
*/
|
||||
|
||||
#ifndef __ListNode_H__
|
||||
#define __ListNode_H__
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace laya
|
||||
{
|
||||
class ListNode
|
||||
{
|
||||
public:
|
||||
ListNode* _Prev;
|
||||
ListNode* _Next;
|
||||
int id; // for debug
|
||||
ListNode(){
|
||||
_Prev=_Next=this;
|
||||
static int n=0;
|
||||
id=n++;
|
||||
}
|
||||
virtual ~ListNode(){
|
||||
//如果在链表上则删除
|
||||
ListNode* pPrev = _Prev;
|
||||
ListNode* pNext = _Next;
|
||||
pPrev->_Next = _Next;
|
||||
pNext->_Prev = _Prev;
|
||||
_Next = this;
|
||||
_Prev = this;
|
||||
}
|
||||
inline bool notInChain(){
|
||||
return _Prev==this && _Next==this;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief 因为stl的list在删除对象的时候不太方便,需要遍历找到iterator,所以先自己写一个
|
||||
*/
|
||||
class simpList
|
||||
{
|
||||
protected:
|
||||
ListNode* pHead; //pHead只是表示头,不是有效内容
|
||||
int nSize;
|
||||
public:
|
||||
simpList(){
|
||||
pHead = new ListNode();
|
||||
nSize = 0;
|
||||
}
|
||||
~simpList(){
|
||||
delete pHead;
|
||||
pHead = 0;
|
||||
nSize = 0;
|
||||
}
|
||||
int size(){
|
||||
return nSize;
|
||||
}
|
||||
//这个不要了使用了。因为与stl的标准不一致。
|
||||
ListNode* getHead(){
|
||||
return pHead;
|
||||
}
|
||||
//begin是有效值。除非整个list没有内容,那他等于end()
|
||||
ListNode* begin(){
|
||||
return pHead->_Next;
|
||||
}
|
||||
//end是无效值。就是指向pHead
|
||||
ListNode* end(){
|
||||
return pHead;
|
||||
}
|
||||
void push_back(ListNode* pNode ){
|
||||
ListNode* pTail = pHead->_Prev;
|
||||
if( pTail==pNode)
|
||||
return;
|
||||
pTail->_Next = pNode;
|
||||
pNode->_Prev = pTail;
|
||||
pNode->_Next = pHead;
|
||||
pHead->_Prev = pNode;
|
||||
nSize++;
|
||||
}
|
||||
ListNode* pop_back(){
|
||||
ListNode* pTail = pHead->_Prev;
|
||||
ListNode* pPrev = pTail->_Prev;
|
||||
//pnext = phead
|
||||
pPrev->_Next = pHead;
|
||||
pHead->_Prev = pPrev;
|
||||
pTail->_Next= pTail;
|
||||
pTail->_Prev= pTail;
|
||||
nSize--;
|
||||
if(nSize<0)nSize=0;
|
||||
return pTail;
|
||||
}
|
||||
void push_front(ListNode* pNode){
|
||||
if( pNode==pHead->_Next)
|
||||
return;
|
||||
pNode->_Next = pHead->_Next;
|
||||
pHead->_Next->_Prev=pNode;
|
||||
pHead->_Next=pNode;
|
||||
pNode->_Prev = pHead;
|
||||
|
||||
nSize++;
|
||||
}
|
||||
ListNode* pop_front(){
|
||||
ListNode* pDel = pHead->_Next;
|
||||
pDel->_Next->_Prev = pHead;
|
||||
pHead->_Next = pDel->_Next;
|
||||
pDel->_Prev=pDel;
|
||||
pDel->_Next=pDel;
|
||||
nSize--;
|
||||
if(nSize<0)nSize=0;
|
||||
return pDel;
|
||||
}
|
||||
//返回下一个节点
|
||||
ListNode* delNode(ListNode* pNode){
|
||||
if( pNode->notInChain() )
|
||||
return NULL;
|
||||
ListNode* pPrev = pNode->_Prev;
|
||||
ListNode* pNext = pNode->_Next;
|
||||
pPrev->_Next = pNode->_Next;
|
||||
pNext->_Prev = pNode->_Prev;
|
||||
pNode->_Next = pNode;
|
||||
pNode->_Prev = pNode;
|
||||
nSize--;
|
||||
if(nSize<0)nSize=0;
|
||||
return pNext;
|
||||
}
|
||||
void clear(){
|
||||
}
|
||||
};
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__ListNode_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "Log.h"
|
||||
int g_nDebugLevel = 3;
|
||||
void(*gLayaLog)(int level, const char* file, int line, const char* fmt, ...) = 0;
|
||||
void(*gLayaLogNoParam)(int level, const char* file, int line, const char* msg) = 0;
|
||||
void(*gLayaLogBin)(int level, const char* file, int line, void* pData, int len) = 0;
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
@file JSLog.h
|
||||
@brief
|
||||
@author wyw
|
||||
@version 1.0
|
||||
@date 2013_11_12
|
||||
*/
|
||||
|
||||
#ifndef __Log_H__
|
||||
#define __Log_H__
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#pragma warning(disable:4996)
|
||||
#ifdef WIN32
|
||||
#pragma execution_character_set("utf-8")
|
||||
#endif
|
||||
//通用的日志函数。
|
||||
enum LogLevel {
|
||||
Warn,
|
||||
Error,
|
||||
Debug,
|
||||
Info,
|
||||
Runtime,
|
||||
};
|
||||
extern void(*gLayaLog)(int level, const char* file, int line, const char* fmt,...);
|
||||
//如果知道没有参数就不用做%的转换了。
|
||||
extern void(*gLayaLogNoParam)(int level, const char* file, int line, const char* msg);
|
||||
extern void(*gLayaLogBin)(int level, const char* file, int line, void* pData, int len);
|
||||
extern int g_nDebugLevel;
|
||||
void alert(const char* fmt, ...);
|
||||
|
||||
#ifdef WEBASM
|
||||
#define LOG_TAG "LayaBox"
|
||||
#define LOGI(...) {printf(__VA_ARGS__);printf("\n");}
|
||||
#define LOGW(...) {printf(__VA_ARGS__);printf("\n");}
|
||||
#define LOGE(...) {printf(__VA_ARGS__);printf("\n");}
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
void CToObjectCLogI( const char* szFormat,...);
|
||||
void CToObjectCLogW(const char* szFormat, ...);
|
||||
void CToObjectCLogE(const char* szFormat, ...);
|
||||
void CToObjectCLogIExt(const char* str);
|
||||
#define LOGIExt(str) {if(g_nDebugLevel >= 3){CToObjectCLogIExt(str);}}
|
||||
#define LOGI(...) {if(g_nDebugLevel >= 3){CToObjectCLogI(__VA_ARGS__);}}
|
||||
#define LOGW(...) {if(g_nDebugLevel >= 2){CToObjectCLogW(__VA_ARGS__);}if(g_nDebugLevel >= 5){alert(__VA_ARGS__);}}
|
||||
#define LOGE(...) {if(g_nDebugLevel >= 1){CToObjectCLogE(__VA_ARGS__);}if(g_nDebugLevel >= 4){alert(__VA_ARGS__);}}
|
||||
#elif LINUX
|
||||
#define LOGI(...) { if(g_nDebugLevel >= 3){if(gLayaLog){gLayaLog(Info,__FILE__,__LINE__,__VA_ARGS__);}else{ printf(__VA_ARGS__);printf("\n");}}}
|
||||
#define LOGW(...) { if(g_nDebugLevel >= 2){if(gLayaLog){gLayaLog(Warn,__FILE__,__LINE__,__VA_ARGS__);}else{ printf(__VA_ARGS__);printf("\n");}}if(g_nDebugLevel >= 5){alert(__VA_ARGS__);}}
|
||||
#define LOGE(...) { if(g_nDebugLevel >= 1){if(gLayaLog){gLayaLog(Error,__FILE__,__LINE__,__VA_ARGS__);}else{ printf(__VA_ARGS__);printf("\n");}}if(g_nDebugLevel >= 4){alert(__VA_ARGS__);}}
|
||||
#elif ANDROID
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#define LOG_TAG "LayaBox"
|
||||
#define LOGI(...) {if(g_nDebugLevel >= 3){if(gLayaLog){gLayaLog(Info,__FILE__,__LINE__,__VA_ARGS__);}else{__android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__);}}}
|
||||
#define LOGW(...) {if(g_nDebugLevel >= 2){if(gLayaLog){gLayaLog(Warn,__FILE__,__LINE__,__VA_ARGS__);}else{__android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__);}}if(g_nDebugLevel >= 5){alert(__VA_ARGS__);}}
|
||||
#define LOGE(...) {if(g_nDebugLevel >= 1){if(gLayaLog){gLayaLog(Error,__FILE__,__LINE__,__VA_ARGS__);}else{__android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__);}}if(g_nDebugLevel >= 4){alert(__VA_ARGS__);}}
|
||||
#elif WIN32
|
||||
#define LOGI(...) { if(g_nDebugLevel >= 3){if(gLayaLog){gLayaLog(Info,__FILE__,__LINE__,__VA_ARGS__);}else{ printf(__VA_ARGS__);printf("\n");}}}
|
||||
#define LOGW(...) { if(g_nDebugLevel >= 2){if(gLayaLog){gLayaLog(Warn,__FILE__,__LINE__,__VA_ARGS__);}else{ printf(__VA_ARGS__);printf("\n");}}if(g_nDebugLevel >= 5){alert(__VA_ARGS__);}}
|
||||
#define LOGE(...) { if(g_nDebugLevel >= 1){if(gLayaLog){gLayaLog(Error,__FILE__,__LINE__,__VA_ARGS__);}else{ printf(__VA_ARGS__);printf("\n");}}if(g_nDebugLevel >= 4){alert(__VA_ARGS__);}}
|
||||
#endif
|
||||
#endif
|
||||
#endif //__Log_H__
|
||||
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
@file RefObject.h
|
||||
@brief
|
||||
@author James
|
||||
@version 1.0
|
||||
@date 2017_8_8
|
||||
*/
|
||||
|
||||
#ifndef __RefObject_H__
|
||||
#define __RefObject_H__
|
||||
|
||||
namespace laya
|
||||
{
|
||||
class RefObject
|
||||
{
|
||||
public:
|
||||
RefObject()
|
||||
{
|
||||
_ref_ = 0;
|
||||
}
|
||||
virtual ~RefObject()
|
||||
{
|
||||
|
||||
}
|
||||
int addRef()
|
||||
{
|
||||
return _ref_++;
|
||||
}
|
||||
virtual void destroy()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
void release()
|
||||
{
|
||||
if((--_ref_ )<1)
|
||||
destroy();
|
||||
}
|
||||
protected:
|
||||
int _ref_;
|
||||
};
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif //__RefObject_H__
|
||||
|
||||
//-----------------------------END FILE--------------------------------
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,174 @@
|
||||
#ifndef RAPIDXML_ITERATORS_HPP_INCLUDED
|
||||
#define RAPIDXML_ITERATORS_HPP_INCLUDED
|
||||
|
||||
// Copyright (C) 2006, 2009 Marcin Kalicinski
|
||||
// Version 1.13
|
||||
// Revision $DateTime: 2009/05/13 01:46:17 $
|
||||
//! \file rapidxml_iterators.hpp This file contains rapidxml iterators
|
||||
|
||||
#include "rapidxml.hpp"
|
||||
|
||||
namespace rapidxml
|
||||
{
|
||||
|
||||
//! Iterator of child nodes of xml_node
|
||||
template<class Ch>
|
||||
class node_iterator
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef typename xml_node<Ch> value_type;
|
||||
typedef typename xml_node<Ch> &reference;
|
||||
typedef typename xml_node<Ch> *pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
node_iterator()
|
||||
: m_node(0)
|
||||
{
|
||||
}
|
||||
|
||||
node_iterator(xml_node<Ch> *node)
|
||||
: m_node(node->first_node())
|
||||
{
|
||||
}
|
||||
|
||||
reference operator *() const
|
||||
{
|
||||
assert(m_node);
|
||||
return *m_node;
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
assert(m_node);
|
||||
return m_node;
|
||||
}
|
||||
|
||||
node_iterator& operator++()
|
||||
{
|
||||
assert(m_node);
|
||||
m_node = m_node->next_sibling();
|
||||
return *this;
|
||||
}
|
||||
|
||||
node_iterator operator++(int)
|
||||
{
|
||||
node_iterator tmp = *this;
|
||||
++this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
node_iterator& operator--()
|
||||
{
|
||||
assert(m_node && m_node->previous_sibling());
|
||||
m_node = m_node->previous_sibling();
|
||||
return *this;
|
||||
}
|
||||
|
||||
node_iterator operator--(int)
|
||||
{
|
||||
node_iterator tmp = *this;
|
||||
++this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator ==(const node_iterator<Ch> &rhs)
|
||||
{
|
||||
return m_node == rhs.m_node;
|
||||
}
|
||||
|
||||
bool operator !=(const node_iterator<Ch> &rhs)
|
||||
{
|
||||
return m_node != rhs.m_node;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
xml_node<Ch> *m_node;
|
||||
|
||||
};
|
||||
|
||||
//! Iterator of child attributes of xml_node
|
||||
template<class Ch>
|
||||
class attribute_iterator
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
typedef typename xml_attribute<Ch> value_type;
|
||||
typedef typename xml_attribute<Ch> &reference;
|
||||
typedef typename xml_attribute<Ch> *pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
attribute_iterator()
|
||||
: m_attribute(0)
|
||||
{
|
||||
}
|
||||
|
||||
attribute_iterator(xml_node<Ch> *node)
|
||||
: m_attribute(node->first_attribute())
|
||||
{
|
||||
}
|
||||
|
||||
reference operator *() const
|
||||
{
|
||||
assert(m_attribute);
|
||||
return *m_attribute;
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{
|
||||
assert(m_attribute);
|
||||
return m_attribute;
|
||||
}
|
||||
|
||||
attribute_iterator& operator++()
|
||||
{
|
||||
assert(m_attribute);
|
||||
m_attribute = m_attribute->next_attribute();
|
||||
return *this;
|
||||
}
|
||||
|
||||
attribute_iterator operator++(int)
|
||||
{
|
||||
attribute_iterator tmp = *this;
|
||||
++this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
attribute_iterator& operator--()
|
||||
{
|
||||
assert(m_attribute && m_attribute->previous_attribute());
|
||||
m_attribute = m_attribute->previous_attribute();
|
||||
return *this;
|
||||
}
|
||||
|
||||
attribute_iterator operator--(int)
|
||||
{
|
||||
attribute_iterator tmp = *this;
|
||||
++this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator ==(const attribute_iterator<Ch> &rhs)
|
||||
{
|
||||
return m_attribute == rhs.m_attribute;
|
||||
}
|
||||
|
||||
bool operator !=(const attribute_iterator<Ch> &rhs)
|
||||
{
|
||||
return m_attribute != rhs.m_attribute;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
xml_attribute<Ch> *m_attribute;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,421 @@
|
||||
#ifndef RAPIDXML_PRINT_HPP_INCLUDED
|
||||
#define RAPIDXML_PRINT_HPP_INCLUDED
|
||||
|
||||
// Copyright (C) 2006, 2009 Marcin Kalicinski
|
||||
// Version 1.13
|
||||
// Revision $DateTime: 2009/05/13 01:46:17 $
|
||||
//! \file rapidxml_print.hpp This file contains rapidxml printer implementation
|
||||
|
||||
#include "rapidxml.hpp"
|
||||
|
||||
// Only include streams if not disabled
|
||||
#ifndef RAPIDXML_NO_STREAMS
|
||||
#include <ostream>
|
||||
#include <iterator>
|
||||
#endif
|
||||
|
||||
namespace rapidxml
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Printing flags
|
||||
|
||||
const int print_no_indenting = 0x1; //!< Printer flag instructing the printer to suppress indenting of XML. See print() function.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Internal
|
||||
|
||||
//! \cond internal
|
||||
namespace internal
|
||||
{
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Internal character operations
|
||||
|
||||
// Copy characters from given range to given output iterator
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt copy_chars(const Ch *begin, const Ch *end, OutIt out)
|
||||
{
|
||||
while (begin != end)
|
||||
*out++ = *begin++;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Copy characters from given range to given output iterator and expand
|
||||
// characters into references (< > ' " &)
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt copy_and_expand_chars(const Ch *begin, const Ch *end, Ch noexpand, OutIt out)
|
||||
{
|
||||
while (begin != end)
|
||||
{
|
||||
if (*begin == noexpand)
|
||||
{
|
||||
*out++ = *begin; // No expansion, copy character
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (*begin)
|
||||
{
|
||||
case Ch('<'):
|
||||
*out++ = Ch('&'); *out++ = Ch('l'); *out++ = Ch('t'); *out++ = Ch(';');
|
||||
break;
|
||||
case Ch('>'):
|
||||
*out++ = Ch('&'); *out++ = Ch('g'); *out++ = Ch('t'); *out++ = Ch(';');
|
||||
break;
|
||||
case Ch('\''):
|
||||
*out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('p'); *out++ = Ch('o'); *out++ = Ch('s'); *out++ = Ch(';');
|
||||
break;
|
||||
case Ch('"'):
|
||||
*out++ = Ch('&'); *out++ = Ch('q'); *out++ = Ch('u'); *out++ = Ch('o'); *out++ = Ch('t'); *out++ = Ch(';');
|
||||
break;
|
||||
case Ch('&'):
|
||||
*out++ = Ch('&'); *out++ = Ch('a'); *out++ = Ch('m'); *out++ = Ch('p'); *out++ = Ch(';');
|
||||
break;
|
||||
default:
|
||||
*out++ = *begin; // No expansion, copy character
|
||||
}
|
||||
}
|
||||
++begin; // Step to next character
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Fill given output iterator with repetitions of the same character
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt fill_chars(OutIt out, int n, Ch ch)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
*out++ = ch;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Find character
|
||||
template<class Ch, Ch ch>
|
||||
inline bool find_char(const Ch *begin, const Ch *end)
|
||||
{
|
||||
while (begin != end)
|
||||
if (*begin++ == ch)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Internal printing operations
|
||||
|
||||
// Print node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
// Print proper node type
|
||||
switch (node->type())
|
||||
{
|
||||
|
||||
// Document
|
||||
case node_document:
|
||||
out = print_children(out, node, flags, indent);
|
||||
break;
|
||||
|
||||
// Element
|
||||
case node_element:
|
||||
out = print_element_node(out, node, flags, indent);
|
||||
break;
|
||||
|
||||
// Data
|
||||
case node_data:
|
||||
out = print_data_node(out, node, flags, indent);
|
||||
break;
|
||||
|
||||
// CDATA
|
||||
case node_cdata:
|
||||
out = print_cdata_node(out, node, flags, indent);
|
||||
break;
|
||||
|
||||
// Declaration
|
||||
case node_declaration:
|
||||
out = print_declaration_node(out, node, flags, indent);
|
||||
break;
|
||||
|
||||
// Comment
|
||||
case node_comment:
|
||||
out = print_comment_node(out, node, flags, indent);
|
||||
break;
|
||||
|
||||
// Doctype
|
||||
case node_doctype:
|
||||
out = print_doctype_node(out, node, flags, indent);
|
||||
break;
|
||||
|
||||
// Pi
|
||||
case node_pi:
|
||||
out = print_pi_node(out, node, flags, indent);
|
||||
break;
|
||||
|
||||
// Unknown
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
// If indenting not disabled, add line break after node
|
||||
if (!(flags & print_no_indenting))
|
||||
*out = Ch('\n'), ++out;
|
||||
|
||||
// Return modified iterator
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print children of the node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_children(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
for (xml_node<Ch> *child = node->first_node(); child; child = child->next_sibling())
|
||||
out = print_node(out, child, flags, indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print attributes of the node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_attributes(OutIt out, const xml_node<Ch> *node, int flags)
|
||||
{
|
||||
for (xml_attribute<Ch> *attribute = node->first_attribute(); attribute; attribute = attribute->next_attribute())
|
||||
{
|
||||
if (attribute->name() && attribute->value())
|
||||
{
|
||||
// Print attribute name
|
||||
*out = Ch(' '), ++out;
|
||||
out = copy_chars(attribute->name(), attribute->name() + attribute->name_size(), out);
|
||||
*out = Ch('='), ++out;
|
||||
// Print attribute value using appropriate quote type
|
||||
if (find_char<Ch, Ch('"')>(attribute->value(), attribute->value() + attribute->value_size()))
|
||||
{
|
||||
*out = Ch('\''), ++out;
|
||||
out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('"'), out);
|
||||
*out = Ch('\''), ++out;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out = Ch('"'), ++out;
|
||||
out = copy_and_expand_chars(attribute->value(), attribute->value() + attribute->value_size(), Ch('\''), out);
|
||||
*out = Ch('"'), ++out;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print data node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_data_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
assert(node->type() == node_data);
|
||||
if (!(flags & print_no_indenting))
|
||||
out = fill_chars(out, indent, Ch('\t'));
|
||||
out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print data node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_cdata_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
assert(node->type() == node_cdata);
|
||||
if (!(flags & print_no_indenting))
|
||||
out = fill_chars(out, indent, Ch('\t'));
|
||||
*out = Ch('<'); ++out;
|
||||
*out = Ch('!'); ++out;
|
||||
*out = Ch('['); ++out;
|
||||
*out = Ch('C'); ++out;
|
||||
*out = Ch('D'); ++out;
|
||||
*out = Ch('A'); ++out;
|
||||
*out = Ch('T'); ++out;
|
||||
*out = Ch('A'); ++out;
|
||||
*out = Ch('['); ++out;
|
||||
out = copy_chars(node->value(), node->value() + node->value_size(), out);
|
||||
*out = Ch(']'); ++out;
|
||||
*out = Ch(']'); ++out;
|
||||
*out = Ch('>'); ++out;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print element node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_element_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
assert(node->type() == node_element);
|
||||
|
||||
// Print element name and attributes, if any
|
||||
if (!(flags & print_no_indenting))
|
||||
out = fill_chars(out, indent, Ch('\t'));
|
||||
*out = Ch('<'), ++out;
|
||||
out = copy_chars(node->name(), node->name() + node->name_size(), out);
|
||||
out = print_attributes(out, node, flags);
|
||||
|
||||
// If node is childless
|
||||
if (node->value_size() == 0 && !node->first_node())
|
||||
{
|
||||
// Print childless node tag ending
|
||||
*out = Ch('/'), ++out;
|
||||
*out = Ch('>'), ++out;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Print normal node tag ending
|
||||
*out = Ch('>'), ++out;
|
||||
|
||||
// Test if node contains a single data node only (and no other nodes)
|
||||
xml_node<Ch> *child = node->first_node();
|
||||
if (!child)
|
||||
{
|
||||
// If node has no children, only print its value without indenting
|
||||
out = copy_and_expand_chars(node->value(), node->value() + node->value_size(), Ch(0), out);
|
||||
}
|
||||
else if (child->next_sibling() == 0 && child->type() == node_data)
|
||||
{
|
||||
// If node has a sole data child, only print its value without indenting
|
||||
out = copy_and_expand_chars(child->value(), child->value() + child->value_size(), Ch(0), out);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Print all children with full indenting
|
||||
if (!(flags & print_no_indenting))
|
||||
*out = Ch('\n'), ++out;
|
||||
out = print_children(out, node, flags, indent + 1);
|
||||
if (!(flags & print_no_indenting))
|
||||
out = fill_chars(out, indent, Ch('\t'));
|
||||
}
|
||||
|
||||
// Print node end
|
||||
*out = Ch('<'), ++out;
|
||||
*out = Ch('/'), ++out;
|
||||
out = copy_chars(node->name(), node->name() + node->name_size(), out);
|
||||
*out = Ch('>'), ++out;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print declaration node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_declaration_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
// Print declaration start
|
||||
if (!(flags & print_no_indenting))
|
||||
out = fill_chars(out, indent, Ch('\t'));
|
||||
*out = Ch('<'), ++out;
|
||||
*out = Ch('?'), ++out;
|
||||
*out = Ch('x'), ++out;
|
||||
*out = Ch('m'), ++out;
|
||||
*out = Ch('l'), ++out;
|
||||
|
||||
// Print attributes
|
||||
out = print_attributes(out, node, flags);
|
||||
|
||||
// Print declaration end
|
||||
*out = Ch('?'), ++out;
|
||||
*out = Ch('>'), ++out;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print comment node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_comment_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
assert(node->type() == node_comment);
|
||||
if (!(flags & print_no_indenting))
|
||||
out = fill_chars(out, indent, Ch('\t'));
|
||||
*out = Ch('<'), ++out;
|
||||
*out = Ch('!'), ++out;
|
||||
*out = Ch('-'), ++out;
|
||||
*out = Ch('-'), ++out;
|
||||
out = copy_chars(node->value(), node->value() + node->value_size(), out);
|
||||
*out = Ch('-'), ++out;
|
||||
*out = Ch('-'), ++out;
|
||||
*out = Ch('>'), ++out;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print doctype node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_doctype_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
assert(node->type() == node_doctype);
|
||||
if (!(flags & print_no_indenting))
|
||||
out = fill_chars(out, indent, Ch('\t'));
|
||||
*out = Ch('<'), ++out;
|
||||
*out = Ch('!'), ++out;
|
||||
*out = Ch('D'), ++out;
|
||||
*out = Ch('O'), ++out;
|
||||
*out = Ch('C'), ++out;
|
||||
*out = Ch('T'), ++out;
|
||||
*out = Ch('Y'), ++out;
|
||||
*out = Ch('P'), ++out;
|
||||
*out = Ch('E'), ++out;
|
||||
*out = Ch(' '), ++out;
|
||||
out = copy_chars(node->value(), node->value() + node->value_size(), out);
|
||||
*out = Ch('>'), ++out;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Print pi node
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print_pi_node(OutIt out, const xml_node<Ch> *node, int flags, int indent)
|
||||
{
|
||||
assert(node->type() == node_pi);
|
||||
if (!(flags & print_no_indenting))
|
||||
out = fill_chars(out, indent, Ch('\t'));
|
||||
*out = Ch('<'), ++out;
|
||||
*out = Ch('?'), ++out;
|
||||
out = copy_chars(node->name(), node->name() + node->name_size(), out);
|
||||
*out = Ch(' '), ++out;
|
||||
out = copy_chars(node->value(), node->value() + node->value_size(), out);
|
||||
*out = Ch('?'), ++out;
|
||||
*out = Ch('>'), ++out;
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
//! \endcond
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Printing
|
||||
|
||||
//! Prints XML to given output iterator.
|
||||
//! \param out Output iterator to print to.
|
||||
//! \param node Node to be printed. Pass xml_document to print entire document.
|
||||
//! \param flags Flags controlling how XML is printed.
|
||||
//! \return Output iterator pointing to position immediately after last character of printed text.
|
||||
template<class OutIt, class Ch>
|
||||
inline OutIt print(OutIt out, const xml_node<Ch> &node, int flags = 0)
|
||||
{
|
||||
return internal::print_node(out, &node, flags, 0);
|
||||
}
|
||||
|
||||
#ifndef RAPIDXML_NO_STREAMS
|
||||
|
||||
//! Prints XML to given output stream.
|
||||
//! \param out Output stream to print to.
|
||||
//! \param node Node to be printed. Pass xml_document to print entire document.
|
||||
//! \param flags Flags controlling how XML is printed.
|
||||
//! \return Output stream.
|
||||
template<class Ch>
|
||||
inline std::basic_ostream<Ch> &print(std::basic_ostream<Ch> &out, const xml_node<Ch> &node, int flags = 0)
|
||||
{
|
||||
print(std::ostream_iterator<Ch>(out), node, flags);
|
||||
return out;
|
||||
}
|
||||
|
||||
//! Prints formatted XML to given output stream. Uses default printing flags. Use print() function to customize printing process.
|
||||
//! \param out Output stream to print to.
|
||||
//! \param node Node to be printed.
|
||||
//! \return Output stream.
|
||||
template<class Ch>
|
||||
inline std::basic_ostream<Ch> &operator <<(std::basic_ostream<Ch> &out, const xml_node<Ch> &node)
|
||||
{
|
||||
return print(out, node);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,122 @@
|
||||
#ifndef RAPIDXML_UTILS_HPP_INCLUDED
|
||||
#define RAPIDXML_UTILS_HPP_INCLUDED
|
||||
|
||||
// Copyright (C) 2006, 2009 Marcin Kalicinski
|
||||
// Version 1.13
|
||||
// Revision $DateTime: 2009/05/13 01:46:17 $
|
||||
//! \file rapidxml_utils.hpp This file contains high-level rapidxml utilities that can be useful
|
||||
//! in certain simple scenarios. They should probably not be used if maximizing performance is the main objective.
|
||||
|
||||
#include "rapidxml.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace rapidxml
|
||||
{
|
||||
|
||||
//! Represents data loaded from a file
|
||||
template<class Ch = char>
|
||||
class file
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//! Loads file into the memory. Data will be automatically destroyed by the destructor.
|
||||
//! \param filename Filename to load.
|
||||
file(const char *filename)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// Open stream
|
||||
basic_ifstream<Ch> stream(filename, ios::binary);
|
||||
if (!stream)
|
||||
throw runtime_error(string("cannot open file ") + filename);
|
||||
stream.unsetf(ios::skipws);
|
||||
|
||||
// Determine stream size
|
||||
stream.seekg(0, ios::end);
|
||||
size_t size = stream.tellg();
|
||||
stream.seekg(0);
|
||||
|
||||
// Load data and add terminating 0
|
||||
m_data.resize(size + 1);
|
||||
stream.read(&m_data.front(), static_cast<streamsize>(size));
|
||||
m_data[size] = 0;
|
||||
}
|
||||
|
||||
//! Loads file into the memory. Data will be automatically destroyed by the destructor
|
||||
//! \param stream Stream to load from
|
||||
file(std::basic_istream<Ch> &stream)
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
// Load data and add terminating 0
|
||||
stream.unsetf(ios::skipws);
|
||||
m_data.assign(istreambuf_iterator<Ch>(stream), istreambuf_iterator<Ch>());
|
||||
if (stream.fail() || stream.bad())
|
||||
throw runtime_error("error reading stream");
|
||||
m_data.push_back(0);
|
||||
}
|
||||
|
||||
//! Gets file data.
|
||||
//! \return Pointer to data of file.
|
||||
Ch *data()
|
||||
{
|
||||
return &m_data.front();
|
||||
}
|
||||
|
||||
//! Gets file data.
|
||||
//! \return Pointer to data of file.
|
||||
const Ch *data() const
|
||||
{
|
||||
return &m_data.front();
|
||||
}
|
||||
|
||||
//! Gets file data size.
|
||||
//! \return Size of file data, in characters.
|
||||
std::size_t size() const
|
||||
{
|
||||
return m_data.size();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
std::vector<Ch> m_data; // File data
|
||||
|
||||
};
|
||||
|
||||
//! Counts children of node. Time complexity is O(n).
|
||||
//! \return Number of children of node
|
||||
template<class Ch>
|
||||
inline std::size_t count_children(xml_node<Ch> *node)
|
||||
{
|
||||
xml_node<Ch> *child = node->first_node();
|
||||
std::size_t count = 0;
|
||||
while (child)
|
||||
{
|
||||
++count;
|
||||
child = child->next_sibling();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//! Counts attributes of node. Time complexity is O(n).
|
||||
//! \return Number of attributes of node
|
||||
template<class Ch>
|
||||
inline std::size_t count_attributes(xml_node<Ch> *node)
|
||||
{
|
||||
xml_attribute<Ch> *attr = node->first_attribute();
|
||||
std::size_t count = 0;
|
||||
while (attr)
|
||||
{
|
||||
++count;
|
||||
attr = attr->next_attribute();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user