SNAP Library 2.0, User Reference
2013-05-13 16:33:57
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; bool Ok=true; TStr MsgStr="Ok"; 00169 try { 00170 Lx.GetSym(TFSet()|syLBracket|syLBrace); 00171 Val=GetValFromLx(Lx); 00172 } 00173 catch (PExcept Except){ 00174 Ok=false; MsgStr=Except->GetMsgStr(); 00175 Val=TJsonVal::New(); 00176 } 00177 return Val; 00178 } 00179 00180 PJsonVal TJsonVal::GetValFromStr(const TStr& JsonStr){ 00181 PSIn SIn=TStrIn::New(JsonStr); 00182 return GetValFromSIn(SIn); 00183 } 00184 00185 void TJsonVal::AddEscapeChAFromStr(const TStr& Str, TChA& ChA){ 00186 if (TUnicodeDef::IsDef()) { 00187 // parse the UTF8 string 00188 TIntV UStr; TUnicodeDef::GetDef()->DecodeUtf8(Str, UStr); 00189 // escape the string 00190 for (int ChN = 0; ChN < UStr.Len(); ChN++) { 00191 const int UCh = UStr[ChN]; 00192 if (UCh < 0x80) { 00193 // 7-bit ascii 00194 const char Ch = (char)UCh; 00195 switch (Ch) { 00196 case '"' : ChA.AddCh('\\'); ChA.AddCh('"'); break; 00197 case '\\' : ChA.AddCh('\\'); ChA.AddCh('\\'); break; 00198 case '/' : ChA.AddCh('\\'); ChA.AddCh('/'); break; 00199 case '\b' : ChA.AddCh('\\'); ChA.AddCh('b'); break; 00200 case '\f' : ChA.AddCh('\\'); ChA.AddCh('f'); break; 00201 case '\n' : ChA.AddCh('\\'); ChA.AddCh('n'); break; 00202 case '\r' : ChA.AddCh('\\'); ChA.AddCh('r'); break; 00203 case '\t' : ChA.AddCh('\\'); ChA.AddCh('t'); break; 00204 default : 00205 ChA.AddCh(Ch); 00206 } 00207 } else { 00208 // escape 00209 ChA += "\\u"; 00210 ChA += TStr::Fmt("%04x", UCh); 00211 } 00212 } 00213 } else { 00214 // escape the string 00215 for (int ChN = 0; ChN < Str.Len(); ChN++) { 00216 const char Ch = Str[ChN]; 00217 if ((Ch & 0x80) == 0) { 00218 // 7-bit ascii 00219 switch (Ch) { 00220 case '"' : ChA.AddCh('\\'); ChA.AddCh('"'); break; 00221 case '\\' : ChA.AddCh('\\'); ChA.AddCh('\\'); break; 00222 case '/' : ChA.AddCh('\\'); ChA.AddCh('/'); break; 00223 case '\b' : ChA.AddCh('\\'); ChA.AddCh('b'); break; 00224 case '\f' : ChA.AddCh('\\'); ChA.AddCh('f'); break; 00225 case '\n' : ChA.AddCh('\\'); ChA.AddCh('n'); break; 00226 case '\r' : ChA.AddCh('\\'); ChA.AddCh('r'); break; 00227 case '\t' : ChA.AddCh('\\'); ChA.AddCh('t'); break; 00228 default : ChA.AddCh(Ch); 00229 } 00230 } else { 00231 // escape 00232 ChA += "\\u"; 00233 ChA += TStr::Fmt("%02x", (int)Ch); 00234 } 00235 } 00236 } 00237 } 00238 00239 void TJsonVal::AddQChAFromStr(const TStr& Str, TChA& ChA){ 00240 ChA+="\""; 00241 AddEscapeChAFromStr(Str, ChA); 00242 ChA+="\""; 00243 } 00244 00245 void TJsonVal::GetChAFromVal(const PJsonVal& Val, TChA& ChA){ 00246 switch (Val->GetJsonValType()){ 00247 case jvtNull: 00248 ChA+="null"; break; 00249 case jvtBool: 00250 if (Val->GetBool()){ChA+="true";} else {ChA+="false";} break; 00251 case jvtNum: 00252 ChA+=TStr::Fmt("%f", Val->GetNum()); break; 00253 case jvtStr: 00254 AddQChAFromStr(Val->GetStr(), ChA); break; 00255 case jvtArr: 00256 ChA+="["; 00257 for (int ArrValN=0; ArrValN<Val->GetArrVals(); ArrValN++){ 00258 if (ArrValN>0){ChA+=", ";} 00259 GetChAFromVal(Val->GetArrVal(ArrValN), ChA); 00260 } 00261 ChA+="]"; 00262 break; 00263 case jvtObj: 00264 ChA+="{"; 00265 for (int ObjKeyN=0; ObjKeyN<Val->GetObjKeys(); ObjKeyN++){ 00266 if (ObjKeyN>0){ChA+=", ";} 00267 TStr ObjKey; PJsonVal ObjVal; Val->GetObjKeyVal(ObjKeyN, ObjKey, ObjVal); 00268 AddQChAFromStr(ObjKey, ChA); 00269 ChA+=":"; 00270 GetChAFromVal(ObjVal, ChA); 00271 } 00272 ChA+="}"; 00273 break; 00274 default: TExcept::Throw("Error parsing json"); 00275 } 00276 } 00277 00278 TStr TJsonVal::GetStrFromVal(const PJsonVal& Val){ 00279 TChA ChA; 00280 GetChAFromVal(Val, ChA); 00281 return ChA; 00282 }