#include "stdafx.h"
#include "gxx_base.h"
#include "stdlib.h"
#include <algorithm>
bool isBlankChar(const char ch){
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n';
}
void appendTabByDepth(std::string& strResult, int depth)
{
if (depth == 0) return;
char * p = new char[ depth + 1 ];
for (int i = 0; i < depth; i++) {
p[ i ] = '\t';
}
p[ depth ] = 0;
strResult.append(p);
delete []p;
}
int isUtf8Char(unsigned const char* p) {
if (*p >> 4 == 0x0E) {
// 验证是否为3字节utf8
p++;
if (*p == 0)
return 0;
if (*p >> 6 != 0x02) {
return 0;
}
p++;
if (*p == 0)
return 0;
if (*p >> 6 != 0x02)
return 0;
return 3;
}
if (*p >> 4 == 0x0C) {
// 验证是否为2字节utf8
p++;
if (*p == 0)
return 0;
if (*p >> 6 != 0x02) {
return 0;
}
return 2;
}
return 0;
}
void appendStringDoesEscape(std::string& strResult, const char* pString, bool isUtf8=false)
{
int nC = (int)strlen(pString);
char* p = new char[nC*2+1];
if (p) {
memset(p,0,nC*2+1);
int i = 0;
while(*pString) {
if (isUtf8) {
int nCCC = isUtf8Char((unsigned char*)pString);
if (nCCC > 0) {
while (nCCC> 0) {
p[i++] = *pString;
pString++;
nCCC--;
}
continue;
}
}
if (((unsigned char)*pString) & 0x80) {
p[i++] = *pString++;
p[i++] = *pString++;
continue;
}
if (*pString == '\"' || *pString == '{' || *pString == '}' || *pString == '[' || *pString == ']' || *pString == '\\' /*|| *pString ==':'*/){
p[i++] = '\\';
}
p[i++] = *pString;
pString++;
}
strResult.append(p);
delete p;
}
}
//用于调试GXX_INNER_CYCLE
//void GXX_INNER_CYCLE(const char* &_point, bool isUtf8=false) {
// //const char* pOrg = _point;
// while(*_point)
// {
// const char* _p = _point;
// while(*_p && *_p =='\\')
// _p += 2;//continue;
// while(((unsigned char)*_p) & 0x80)
// {
// if (isUtf8) {
// int nC=0;
// nC = isUtf8Char((unsigned char*)_p);
// if (nC > 0) {
// _p += nC; continue;
// }
// _p += 1;
// }
// else {
// _p += 2;
// }
// }
// if (_p != _point)
// {
// _point += (_p - _point); //continue;
// }
// else
// {
// break;
// }
// }
// //if (pOrg != _point) continue;
//}
#define GXX_INNER_CYCLE(_point,isUtf8) {\
const char* pOrg = _point;\
while(*_point) \
{\
const char* _p = _point;\
while(*_p && *_p =='\\')\
_p += 2;\
while(((unsigned char)*_p) & 0x80)\
{ \
if (isUtf8) {\
int nC=0;\
nC = isUtf8Char((unsigned char*)_p);\
if (nC > 0) {\
_p += nC; continue;\
}\
_p += 1;\
}\
else {\
_p += 2;\
}\
}\
if (_p != _point)\
{\
_point += (_p - _point); \
}\
else\
{\
break;\
}\
}\
if (pOrg != _point) continue;\
}
/*#define GXX_INNER_CYCLE(_point,isUtf8) {if (*_point == '\\')\
{_point += 2;continue;}\
const char* _p = _point;\
while(((unsigned char)*_p) & 0x80)\
{ \
if (isUtf8){\
int nC=isUtf8Char((unsigned char*)_p);\
if (nC > 0) {\
_p += nC; continue;\
}\
_p += 1;\
}\
_p += 2;\
}\
if (_p != _point)\
{ _point += (_p - _point); continue;}\
}
*/
GxxObject::GxxObject()
:retainCount(0)
{
}
GxxObject::~GxxObject()
{
}
void GxxObject::retain()
{
retainCount += 1;
}
void GxxObject::release()
{
retainCount -= 1;
if (retainCount == 0)
{
objectReleased();
delete this;
}
}
void GxxObject::_print( const char* x )
{
GXX_PRINT(x);
}
void GxxObject::_println( const char* x )
{
GXX_PRINT(x); GXX_PRINT("\n");
}
//-------------------------------------------------------------------------
bool GxxDictionary::init()
{
keyValues = GxxValueMap::create();
return true;
}
void GxxDictionary::objectReleased()
{
}
bool GxxDictionary::initWithJsonText(const char* jsonText, bool isUtf8)
{
if (jsonText == 0 || *jsonText == 0){
return true;
}
const char* p = jsonText;
int nStack = 0;
const char* pFirst = 0;
const char* pLast = 0;
const char* pFirstValue = 0;
const char* pEndValue = 0;
int nQutCount = 0; // 引号个数
int nCCC = 0;
// 先找到{起点 和 }终点
while(*p)
{
GXX_INNER_CYCLE(p, isUtf8); // 跳过连续非ANSII字符,转义符
if (*p == '{' && nQutCount%2 == 0){
nCCC++;nStack++;
if (!pFirst) pFirst = p;
}
else if(*p == '}' && nQutCount%2 == 0){
--nStack;
if (nStack < 0){
throw GxxException("{} does not match.");// {}括弧不匹配
return false;
}
if (nStack == 0){
pLast = p;
break;
}
}
else if(*p == '\"'){
nQutCount++;
}
p++;
}
if (!pFirst || !pLast){
throw GxxException("{} does not match.");// {}括弧不匹配
return false;
}
if (pLast - pFirst < 2){
return true; // 空白信息
}
// 已经找到花括弧的位置, 读取key引号的位置
while(pFirst)
{
// 1: 找到key的首引号和尾引号的位置
int nQuoMark = 0;
const char* pFirstQuo = 0;
const char* pLastQuo = 0;
const char* pColon = 0; // 冒号的位置
p = pFirst + 1;
while (p != pLast)
{
GXX_INNER_CYCLE(p, isUtf8);
if (*p == '\"'){
++nQuoMark;
if (nQuoMark == 1){
pFirstQuo = p;
}
else
{
pLastQuo = p;
}
}
else if(*p == ':' && nQuoMark >= 2)
{
pColon = p;
break;
}
p++;
}
if (!pFirstQuo || !pLastQuo || !pColon)
{
return false;
}
GxxKey key;
key.resize((unsigned int)(pLastQuo - pFirstQuo -1));
for (int i = 1,j = 0; i <= pLastQuo - pFirstQuo -1; i++){
if (pFirstQuo[i] == '\\'){
key[j++] = pFirstQuo[++i];
} else {
key[j++] = pFirstQuo[i];
}
}
// 2: 得到value
p = pColon + 1;
pFirstValue = 0;
while(p != pLast)
{
if (!isBlankChar(*p))
{
pFirstValue = p;
break;
}
p++;
}
if (pFirstValue == 0) {
// value 是空的
GxxValuePtr ptrV = GxxValue::create("");
keyValues->PutValue(key, ptrV);
break;
}
pEndValue = 0;
switch(*pFirstValue)
{
case '\"':
{
p = pFirstValue + 1;
nQutCount = 1;
while(p != pLast)
{
GXX_INNER_CYCLE(p, isUtf8);
if (*p == '\"')
{
nQutCount++;
pEndValue = p;
}
if (*p == ',' && nQutCount % 2 == 0)
{
p--;break;
}
p++;
}
if (!pEndValue)
{
throw GxxException("invalid json text.");
return false;
}
int nLen = int(pEndValue - pFirstValue - 1);
GxxStringPtr strTmpPtr = GxxString::create(nLen);
char* pTmp = (char*)strTmpPtr->getString();
for (int i = 1,j = 0; i <= nLen; i++){
if (pFirstValue[i] == '\\'){
char ch = pFirstValue[++i];
if (ch == 'n') pTmp[j++] = '\n';
else if (ch == 'r') pTmp[j++] = '\r';
else if (ch == 't') pTmp[j++] = '\t';
else pTmp[j++] = ch;
} else {
pTmp[j++] = pFirstValue[i];
}
}
GxxValuePtr ptrV = GxxValue::create(strTmpPtr);
keyValues->PutValue(key, ptrV);
}
break;
case '{':
{
p = pFirstValue;
nStack = 0;
nQutCount = 0;
while(p != pLast)
{
GXX_INNER_CYCLE(p, isUtf8);
if (*p == '{' && nQutCount % 2 == 0) ++nStack;
else if(*p == '}' && nQutCount % 2 == 0)
{
--nStack;
if (nStack == 0)
{
pEndValue = p;
break;
}
}
else if(*p == '\"')
nQutCount++;
p++;
}
if (!pEndValue)
{
throw GxxException("invalid json text.");
return false;
}
std::string strDic;
strDic.append(pFirstValue, pEndValue - pFirstValue + 1);
GxxDictionaryPtr dictionary = GxxDictionary::create();
dictionary->initWithJsonText(strDic.c_str(), isUtf8);
keyValues->PutValue(key, GxxValue::c