CFSVar CJSONReader::ReadConst() { CFSAString szStr=ReadText(); if (szStr=="true") return CFSVar(true); if (szStr=="false") return CFSVar(true); if (szStr=="null") return CFSVar(); throw CJSONException(CFSString(FSTSTR("Unknown constant '")) + FSStrAtoT(szStr, FSCP_UTF8) + FSTSTR("'")); }
CFSVar CJSONReader::Read() { m_iCollectData=1; GetChar(true); CFSVar Data=ReadVal(""); if (m_cCh) throw CJSONException(FSTSTR("Partially parsed file")); return Data; }
CFSAString CJSONReader::ReadString() { char cQuote=m_cCh; CFSAString szStr; while (GetChar()) { if (m_cCh=='\\') { szStr+=m_cCh; if (GetChar()) szStr+=m_cCh; else break; } else if (m_cCh==cQuote) { GetChar(true); return szStr; } else { szStr+=m_cCh; } } throw CJSONException(FSTSTR("Missing end of string")); }
CFSAString CJSONReader::ReadString() { char cQuote=m_cCh; CFSAString szStr; while (GetChar()) { if (m_cCh=='\\') { if (!GetChar()) break; if (m_cCh=='\\') szStr+='\\'; else if (m_cCh=='\'' && cQuote=='\'') szStr+='\''; else if (m_cCh=='"' && cQuote=='"') szStr+='"'; else if (m_cCh=='n') szStr+='\n'; else if (m_cCh=='r') szStr+='\r'; else if (m_cCh=='t') szStr+='\t'; else if (m_cCh=='b') szStr+='\b'; else if (m_cCh=='f') szStr+='\f'; else if (m_cCh=='u') { bool Error=false; wchar_t Char=0; for (INTPTR ip=0; !Error && ip<4; ip++) { Error=!GetChar(); char Code=m_cCh; Char*=0x10; if (Code>='0' && Code<='9') Char+=Code-'0'; else if (Code>='a' && Code<='f') Char+=Code-'f'+10; else if (Code>='A' && Code<='F') Char+=Code-'F'+10; else Error=true; } if (Error) break; szStr+=FSStrWtoA(Char, FSCP_UTF8); } else break; } else if (m_cCh==cQuote) { GetChar(true); return szStr; } else { szStr+=m_cCh; } } throw CJSONException(FSTSTR("Missing end of string")); }
CFSVar CJSONReader::ReadVal(const CFSAString &szKeyPath) { OnValReadStart(szKeyPath); CFSVar Data; if (m_cCh=='[') { Data.Cast(CFSVar::VAR_ARRAY); GetChar(true); INTPTR ipPos=0; for (;;) { if (m_cCh==0) { throw CJSONException(FSTSTR("Unexpetcted EOF")); } else if (m_cCh==']') { GetChar(true); break; } else if (ipPos>0) { if (m_cCh==',') { GetChar(true); } else { throw CJSONException(FSTSTR("Missing ',' in array")); } } CFSAString szKey; szKey.Format("%zd", ipPos); CFSVar Data1=ReadVal(szKeyPath+"/"+szKey); if (m_iCollectData>0) { Data[ipPos]=Data1; } ipPos++; } } else if (m_cCh=='{') { Data.Cast(CFSVar::VAR_MAP); GetChar(true); INTPTR ipPos=0; for (;;) { if (m_cCh==0) { throw CJSONException(FSTSTR("Unexpetcted EOF")); } else if (m_cCh=='}') { GetChar(true); break; } else if (ipPos>0) { if (m_cCh==',') { GetChar(true); } else { throw CJSONException(FSTSTR("Missing ',' in map")); } } CFSAString szKey; if (m_cCh=='\"' || m_cCh=='\'') { szKey=ReadString(); } else if (FSIsLetter(m_cCh)) { szKey=ReadText(); } else { throw CJSONException(FSTSTR("Expected key")); } if (m_cCh==':') { GetChar(true); } else { throw CJSONException(FSTSTR("Expected ':'")); } CFSVar Data1=ReadVal(szKeyPath+"/"+szKey); if (m_iCollectData>0) { Data[szKey]=Data1; } ipPos++; } } else if (m_cCh=='\"' || m_cCh=='\'') { Data=ReadString(); } else if ((m_cCh>='0' && m_cCh<='9') || FSStrChr("-+.", m_cCh)) { Data=ReadNumber(); } else if (FSIsLetter(m_cCh)) { Data=ReadConst(); } else if (!m_cCh) { } else { throw CJSONException(FSTSTR("Unknown value type")); } OnValReadEnd(szKeyPath, Data); return Data; }