SNAP Library 2.1, Developer Reference
2013-09-25 10:47:25
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
00001 00002 // Json-Value 00003 TJsonVal::TJsonVal(TSIn& SIn): 00004 JsonValType((TJsonValType)(TInt(SIn).Val)), Bool(SIn), 00005 Num(SIn), Str(SIn), ValV(SIn), KeyValH(SIn) { } 00006 00007 void TJsonVal::Save(TSOut& SOut) const { 00008 TInt((int)JsonValType).Save(SOut); 00009 Bool.Save(SOut); Num.Save(SOut); 00010 Str.Save(SOut); ValV.Save(SOut); 00011 KeyValH.Save(SOut); 00012 } 00013 00014 TStr TJsonVal::SaveStr() { 00015 return GetStrFromVal(this); 00016 } 00017 00018 bool TJsonVal::operator==(const TJsonVal& JsonVal) const { 00019 return JsonValType == JsonVal.JsonValType && 00020 Bool == JsonVal.Bool && 00021 Num == JsonVal.Num && 00022 Str == JsonVal.Str && 00023 ValV == JsonVal.ValV && 00024 KeyValH == JsonVal.KeyValH; 00025 } 00026 00027 bool TJsonVal::operator!=(const TJsonVal& JsonVal) const { 00028 return !(*this == JsonVal); 00029 } 00030 00031 void TJsonVal::AddToObj(const PJsonVal& Val) { 00032 EAssert(Val->IsObj()); 00033 int KeyId = Val->KeyValH.FFirstKeyId(); 00034 while (Val->KeyValH.FNextKeyId(KeyId)) { 00035 AddToObj(Val->KeyValH.GetKey(KeyId), Val->KeyValH[KeyId]); 00036 } 00037 } 00038 00039 PJsonVal TJsonVal::NewArr(const TJsonValV& ValV) { 00040 PJsonVal Val = TJsonVal::NewArr(); 00041 for (int ValN = 0; ValN < ValV.Len(); ValN++) { 00042 Val->AddToArr(ValV[ValN]); 00043 } 00044 return Val; 00045 } 00046 00047 PJsonVal TJsonVal::NewArr(const TIntV& IntV) { 00048 PJsonVal Val = TJsonVal::NewArr(); 00049 for (int IntN = 0; IntN < IntV.Len(); IntN++) { 00050 Val->AddToArr(TJsonVal::NewNum((double)IntV[IntN])); 00051 } 00052 return Val; 00053 } 00054 00055 PJsonVal TJsonVal::NewArr(const TFltV& FltV) { 00056 PJsonVal Val = TJsonVal::NewArr(); 00057 for (int FltN = 0; FltN < FltV.Len(); FltN++) { 00058 Val->AddToArr(TJsonVal::NewNum(FltV[FltN])); 00059 } 00060 return Val; 00061 } 00062 00063 PJsonVal TJsonVal::NewArr(const TStrV& StrV) { 00064 PJsonVal Val = TJsonVal::NewArr(); 00065 for (int StrN = 0; StrN < StrV.Len(); StrN++) { 00066 Val->AddToArr(TJsonVal::NewStr(StrV[StrN])); 00067 } 00068 return Val; 00069 } 00070 00071 PJsonVal TJsonVal::NewArr(const TFltPr& FltPr) { 00072 PJsonVal Val = TJsonVal::NewArr(); 00073 Val->AddToArr(TJsonVal::NewNum(FltPr.Val1)); 00074 Val->AddToArr(TJsonVal::NewNum(FltPr.Val2)); 00075 return Val; 00076 } 00077 00078 PJsonVal TJsonVal::GetObjKey(const TStr& Key) const { 00079 EAssert(IsObj()); 00080 EAssert(IsObjKey(Key)); 00081 return KeyValH.GetDat(Key); 00082 } 00083 00084 PJsonVal TJsonVal::GetObjKey(const char *Key) const { 00085 EAssert(IsObj()); 00086 EAssert(IsObjKey(Key)); 00087 return KeyValH.GetDat(Key); 00088 } 00089 00090 bool TJsonVal::GetObjBool(const TStr& Key, const bool& DefBool) const { 00091 EAssert(IsObj()); 00092 return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetBool() : DefBool; 00093 } 00094 00095 bool TJsonVal::GetObjBool(const char *Key, const bool& DefBool) const { 00096 EAssert(IsObj()); 00097 return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetBool() : DefBool; 00098 } 00099 00100 double TJsonVal::GetObjNum(const TStr& Key, const double& DefNum) const { 00101 EAssert(IsObj()); 00102 return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetNum() : DefNum; 00103 } 00104 00105 double TJsonVal::GetObjNum(const char *Key, const double& DefNum) const { 00106 EAssert(IsObj()); 00107 return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetNum() : DefNum; 00108 } 00109 00110 TStr TJsonVal::GetObjStr(const TStr& Key, const TStr& DefStr) const { 00111 EAssert(IsObj()); 00112 return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetStr() : DefStr; 00113 } 00114 00115 TStr TJsonVal::GetObjStr(const char *Key, const TStr& DefStr) const { 00116 EAssert(IsObj()); 00117 return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetStr() : DefStr; 00118 } 00119 00120 PJsonVal TJsonVal::GetValFromLx(TILx& Lx){ 00121 static TFSet ValExpect=TFSet()|syIdStr|syFlt|syQStr|syLBracket|syLBrace|syRBracket; 00122 PJsonVal Val=TJsonVal::New(); 00123 if ((Lx.Sym==syIdStr)&&(Lx.Str=="null")){ 00124 Val->PutNull(); Lx.GetSym(); 00125 } else if ((Lx.Sym==syIdStr)&&(Lx.Str=="true")){ 00126 Val->PutBool(true); Lx.GetSym(); 00127 } else if ((Lx.Sym==syIdStr)&&(Lx.Str=="false")){ 00128 Val->PutBool(false); Lx.GetSym(); 00129 } else if (Lx.Sym==syFlt){ 00130 Val->PutNum(Lx.Flt); Lx.GetSym(); 00131 } else if (Lx.Sym==syQStr){ 00132 Val->PutStr(Lx.Str); Lx.GetSym(); 00133 } else if (Lx.Sym==syLBracket){ 00134 Val->PutArr(); Lx.GetSym(ValExpect); // added ValExpect to correctyl parse arrays of floats 00135 if (Lx.Sym!=syRBracket){ 00136 forever{ 00137 PJsonVal SubVal=TJsonVal::GetValFromLx(Lx); 00138 Val->AddToArr(SubVal); 00139 if (Lx.Sym==syComma){Lx.GetSym(ValExpect);} 00140 else if (Lx.Sym==syRBracket){break;} 00141 else {TExcept::Throw("JSON Array not properly formed.");} 00142 } 00143 } 00144 Lx.GetSym(); 00145 } else if (Lx.Sym==syLBrace){ 00146 Val->PutObj(); Lx.GetSym(TFSet()|syRBrace|syQStr); 00147 if (Lx.Sym!=syRBrace){ 00148 forever{ 00149 TStr SubKey=Lx.Str; 00150 Lx.GetSym(syColon); 00151 Lx.GetSym(ValExpect); 00152 PJsonVal SubVal=TJsonVal::GetValFromLx(Lx); 00153 Val->AddToObj(SubKey, SubVal); 00154 if (Lx.Sym==syComma){Lx.GetSym(TFSet()|syQStr);} 00155 else if (Lx.Sym==syRBrace){break;} 00156 else {TExcept::Throw("JSON Object not properly formed.");} 00157 } 00158 } 00159 Lx.GetSym(); 00160 } else { 00161 TExcept::Throw("Unexpected JSON symbol."); 00162 } 00163 return Val; 00164 } 00165 00166 PJsonVal TJsonVal::GetValFromSIn(const PSIn& SIn){ 00167 TILx Lx(SIn, TFSet()|iloCmtAlw|iloCsSens|iloExcept|iloSigNum); 00168 PJsonVal Val; 00169 //bool Ok=true; 00170 TStr MsgStr="Ok"; 00171 try { 00172 Lx.GetSym(TFSet()|syLBracket|syLBrace); 00173 Val=GetValFromLx(Lx); 00174 } 00175 catch (PExcept Except){ 00176 //Ok=false; 00177 MsgStr=Except->GetMsgStr(); 00178 Val=TJsonVal::New(); 00179 } 00180 return Val; 00181 } 00182 00183 PJsonVal TJsonVal::GetValFromStr(const TStr& JsonStr){ 00184 PSIn SIn=TStrIn::New(JsonStr); 00185 return GetValFromSIn(SIn); 00186 } 00187 00188 void TJsonVal::AddEscapeChAFromStr(const TStr& Str, TChA& ChA){ 00189 if (TUnicodeDef::IsDef()) { 00190 // parse the UTF8 string 00191 TIntV UStr; TUnicodeDef::GetDef()->DecodeUtf8(Str, UStr); 00192 // escape the string 00193 for (int ChN = 0; ChN < UStr.Len(); ChN++) { 00194 const int UCh = UStr[ChN]; 00195 if (UCh < 0x80) { 00196 // 7-bit ascii 00197 const char Ch = (char)UCh; 00198 switch (Ch) { 00199 case '"' : ChA.AddCh('\\'); ChA.AddCh('"'); break; 00200 case '\\' : ChA.AddCh('\\'); ChA.AddCh('\\'); break; 00201 case '/' : ChA.AddCh('\\'); ChA.AddCh('/'); break; 00202 case '\b' : ChA.AddCh('\\'); ChA.AddCh('b'); break; 00203 case '\f' : ChA.AddCh('\\'); ChA.AddCh('f'); break; 00204 case '\n' : ChA.AddCh('\\'); ChA.AddCh('n'); break; 00205 case '\r' : ChA.AddCh('\\'); ChA.AddCh('r'); break; 00206 case '\t' : ChA.AddCh('\\'); ChA.AddCh('t'); break; 00207 default : 00208 ChA.AddCh(Ch); 00209 } 00210 } else { 00211 // escape 00212 ChA += "\\u"; 00213 ChA += TStr::Fmt("%04x", UCh); 00214 } 00215 } 00216 } else { 00217 // escape the string 00218 for (int ChN = 0; ChN < Str.Len(); ChN++) { 00219 const char Ch = Str[ChN]; 00220 if ((Ch & 0x80) == 0) { 00221 // 7-bit ascii 00222 switch (Ch) { 00223 case '"' : ChA.AddCh('\\'); ChA.AddCh('"'); break; 00224 case '\\' : ChA.AddCh('\\'); ChA.AddCh('\\'); break; 00225 case '/' : ChA.AddCh('\\'); ChA.AddCh('/'); break; 00226 case '\b' : ChA.AddCh('\\'); ChA.AddCh('b'); break; 00227 case '\f' : ChA.AddCh('\\'); ChA.AddCh('f'); break; 00228 case '\n' : ChA.AddCh('\\'); ChA.AddCh('n'); break; 00229 case '\r' : ChA.AddCh('\\'); ChA.AddCh('r'); break; 00230 case '\t' : ChA.AddCh('\\'); ChA.AddCh('t'); break; 00231 default : ChA.AddCh(Ch); 00232 } 00233 } else { 00234 // escape 00235 ChA += "\\u"; 00236 ChA += TStr::Fmt("%02x", (int)Ch); 00237 } 00238 } 00239 } 00240 } 00241 00242 void TJsonVal::AddQChAFromStr(const TStr& Str, TChA& ChA){ 00243 ChA+="\""; 00244 AddEscapeChAFromStr(Str, ChA); 00245 ChA+="\""; 00246 } 00247 00248 void TJsonVal::GetChAFromVal(const PJsonVal& Val, TChA& ChA){ 00249 switch (Val->GetJsonValType()){ 00250 case jvtNull: 00251 ChA+="null"; break; 00252 case jvtBool: 00253 if (Val->GetBool()){ChA+="true";} else {ChA+="false";} break; 00254 case jvtNum: 00255 ChA+=TStr::Fmt("%f", Val->GetNum()); break; 00256 case jvtStr: 00257 AddQChAFromStr(Val->GetStr(), ChA); break; 00258 case jvtArr: 00259 ChA+="["; 00260 for (int ArrValN=0; ArrValN<Val->GetArrVals(); ArrValN++){ 00261 if (ArrValN>0){ChA+=", ";} 00262 GetChAFromVal(Val->GetArrVal(ArrValN), ChA); 00263 } 00264 ChA+="]"; 00265 break; 00266 case jvtObj: 00267 ChA+="{"; 00268 for (int ObjKeyN=0; ObjKeyN<Val->GetObjKeys(); ObjKeyN++){ 00269 if (ObjKeyN>0){ChA+=", ";} 00270 TStr ObjKey; PJsonVal ObjVal; Val->GetObjKeyVal(ObjKeyN, ObjKey, ObjVal); 00271 AddQChAFromStr(ObjKey, ChA); 00272 ChA+=":"; 00273 GetChAFromVal(ObjVal, ChA); 00274 } 00275 ChA+="}"; 00276 break; 00277 default: TExcept::Throw("Error parsing json"); 00278 } 00279 } 00280 00281 TStr TJsonVal::GetStrFromVal(const PJsonVal& Val){ 00282 TChA ChA; 00283 GetChAFromVal(Val, ChA); 00284 return ChA; 00285 }