SNAP Library , Developer Reference  2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
json.cpp
Go to the documentation of this file.
00001 
00002 // Json-Value
00003 PJsonVal TJsonVal::NewArr(const TJsonValV& ValV) {
00004         PJsonVal Val = TJsonVal::NewArr();
00005         for (int ValN = 0; ValN < ValV.Len(); ValN++) {
00006                 Val->AddToArr(ValV[ValN]);
00007         }
00008         return Val;
00009 }
00010 
00011 PJsonVal TJsonVal::NewArr(const TStrV& StrV) {
00012         PJsonVal Val = TJsonVal::NewArr();
00013         for (int StrN = 0; StrN < StrV.Len(); StrN++) {
00014                 Val->AddToArr(TJsonVal::NewStr(StrV[StrN]));
00015         }
00016         return Val;
00017 }
00018 
00019 PJsonVal TJsonVal::GetObjKey(const TStr& Key) const {
00020   EAssert(IsObj());
00021   EAssert(IsObjKey(Key)); 
00022   return KeyValH.GetDat(Key);
00023 }
00024 
00025 PJsonVal TJsonVal::GetObjKey(const char *Key) const {
00026   EAssert(IsObj());
00027   EAssert(IsObjKey(Key));
00028   return KeyValH.GetDat(Key);
00029 }
00030 
00031 bool TJsonVal::GetObjBool(const TStr& Key, const bool& DefBool) const { 
00032   EAssert(IsObj());
00033   return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetBool() : DefBool;
00034 }
00035 
00036 bool TJsonVal::GetObjBool(const char *Key, const bool& DefBool) const { 
00037   EAssert(IsObj());
00038   return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetBool() : DefBool;
00039 }
00040 
00041 double TJsonVal::GetObjNum(const TStr& Key, const double& DefNum) const { 
00042   EAssert(IsObj());
00043   return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetNum() : DefNum;
00044 } 
00045 
00046 double TJsonVal::GetObjNum(const char *Key, const double& DefNum) const { 
00047   EAssert(IsObj());
00048   return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetNum() : DefNum;
00049 }
00050 
00051 TStr TJsonVal::GetObjStr(const TStr& Key, const TStr& DefStr) const { 
00052   EAssert(IsObj());
00053   return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetStr() : DefStr;
00054 }
00055 
00056 TStr TJsonVal::GetObjStr(const char *Key, const TStr& DefStr) const { 
00057   EAssert(IsObj());
00058   return (IsObjKey(Key)) ? KeyValH.GetDat(Key)->GetStr() : DefStr;
00059 }
00060   
00061 PJsonVal TJsonVal::GetValFromLx(TILx& Lx){
00062   static TFSet ValExpect=TFSet()|syIdStr|syFlt|syQStr|syLBracket|syLBrace;
00063   PJsonVal Val=TJsonVal::New();
00064   if ((Lx.Sym==syIdStr)&&(Lx.Str=="null")){
00065     Val->PutNull(); Lx.GetSym();
00066   } else if ((Lx.Sym==syIdStr)&&(Lx.Str=="true")){
00067     Val->PutBool(true); Lx.GetSym();
00068   } else if ((Lx.Sym==syIdStr)&&(Lx.Str=="false")){
00069     Val->PutBool(false); Lx.GetSym();
00070   } else if (Lx.Sym==syFlt){
00071     Val->PutNum(Lx.Flt); Lx.GetSym();
00072   } else if (Lx.Sym==syQStr){
00073     Val->PutStr(Lx.Str); Lx.GetSym();
00074   } else if (Lx.Sym==syLBracket){
00075     Val->PutArr(); Lx.GetSym(ValExpect); // added ValExpect to correctyl parse arrays of floats
00076     if (Lx.Sym!=syRBracket){
00077       forever{
00078         PJsonVal SubVal=TJsonVal::GetValFromLx(Lx);
00079         Val->AddToArr(SubVal);
00080         if (Lx.Sym==syComma){Lx.GetSym(ValExpect);} 
00081         else if (Lx.Sym==syRBracket){break;} 
00082         else {TExcept::Throw("JSON Array not properly formed.");}
00083       }
00084     }
00085     Lx.GetSym();
00086   } else if (Lx.Sym==syLBrace){
00087     Val->PutObj(); Lx.GetSym(TFSet()|syRBrace|syQStr);
00088     if (Lx.Sym!=syRBrace){
00089       forever{
00090         TStr SubKey=Lx.Str; 
00091         Lx.GetSym(syColon); 
00092         Lx.GetSym(ValExpect);
00093         PJsonVal SubVal=TJsonVal::GetValFromLx(Lx);
00094         Val->AddToObj(SubKey, SubVal);
00095         if (Lx.Sym==syComma){Lx.GetSym(TFSet()|syQStr);} 
00096         else if (Lx.Sym==syRBrace){break;} 
00097         else {TExcept::Throw("JSON Object not properly formed.");}
00098       }
00099     }
00100     Lx.GetSym();
00101   } else {
00102     TExcept::Throw("Unexpected JSON symbol.");
00103   }
00104   return Val;
00105 }
00106 
00107 PJsonVal TJsonVal::GetValFromStr(const TStr& JsonStr){
00108   PSIn SIn=TStrIn::New(JsonStr);
00109   TILx Lx(SIn, TFSet()|iloCmtAlw|iloCsSens|iloExcept|iloSigNum);
00110   PJsonVal Val; bool Ok=true; TStr MsgStr="Ok";
00111   try {
00112     Lx.GetSym(TFSet()|syLBracket|syLBrace);
00113     Val=GetValFromLx(Lx);
00114   }
00115   catch (PExcept Except){
00116     Ok=false; MsgStr=Except->GetMsgStr();
00117     Val=TJsonVal::New();
00118   }
00119   return Val;
00120 }
00121 
00122 void TJsonVal::AddEscapeChAFromStr(const TStr& Str, TChA& ChA){
00123         if (TUnicodeDef::IsDef()) {
00124                 // parse the UTF8 string (old: TUStr InUStr(InStr);)
00125                 TIntV UStr; TUnicodeDef::GetDef()->DecodeUtf8(Str, UStr);
00126                 // escape the string
00127                 for (int ChN = 0; ChN < UStr.Len(); ChN++) {
00128                         const int UCh = UStr[ChN];
00129                         if (UCh < 0x80) {
00130                                 // 7-bit ascii
00131                                 const char Ch = (char)UCh;
00132                                 switch (Ch) {
00133                                         case '"' : ChA.AddCh('\\'); ChA.AddCh('"'); break;
00134                                         case '\\' : ChA.AddCh('\\'); ChA.AddCh('\\'); break;
00135                                         case '/' : ChA.AddCh('\\'); ChA.AddCh('/'); break;
00136                                         case '\b' : ChA.AddCh('\\'); ChA.AddCh('b'); break;
00137                                         case '\f' : ChA.AddCh('\\'); ChA.AddCh('f'); break;
00138                                         case '\n' : ChA.AddCh('\\'); ChA.AddCh('n'); break;
00139                                         case '\r' : ChA.AddCh('\\'); ChA.AddCh('r'); break;
00140                                         case '\t' : ChA.AddCh('\\'); ChA.AddCh('t'); break;
00141                                         default :
00142                                                 ChA.AddCh(Ch);
00143                                 }
00144                         } else {
00145                                 // escape
00146                                 ChA += "\\u";
00147                                 ChA += TStr::Fmt("%04x", UCh);
00148                         }
00149                 }
00150         } else {
00151                 // escape the string
00152                 for (int ChN = 0; ChN < Str.Len(); ChN++) {
00153                         const char Ch = Str[ChN];
00154                         if ((Ch & 0x80) == 0) {
00155                                 // 7-bit ascii
00156                                 switch (Ch) {
00157                                         case '"' : ChA.AddCh('\\'); ChA.AddCh('"'); break;
00158                                         case '\\' : ChA.AddCh('\\'); ChA.AddCh('\\'); break;
00159                                         case '/' : ChA.AddCh('\\'); ChA.AddCh('/'); break;
00160                                         case '\b' : ChA.AddCh('\\'); ChA.AddCh('b'); break;
00161                                         case '\f' : ChA.AddCh('\\'); ChA.AddCh('f'); break;
00162                                         case '\n' : ChA.AddCh('\\'); ChA.AddCh('n'); break;
00163                                         case '\r' : ChA.AddCh('\\'); ChA.AddCh('r'); break;
00164                                         case '\t' : ChA.AddCh('\\'); ChA.AddCh('t'); break;
00165                                         default : ChA.AddCh(Ch);
00166                                 }
00167                         } else {
00168                                 // escape
00169                                 ChA += "\\u";
00170                                 ChA += TStr::Fmt("%02x", (int)Ch);
00171                         }
00172                 }
00173         }
00174 }
00175 
00176 void TJsonVal::AddQChAFromStr(const TStr& Str, TChA& ChA){
00177   ChA+="\"";
00178   AddEscapeChAFromStr(Str, ChA);
00179   ChA+="\"";
00180 }
00181 
00182 void TJsonVal::GetChAFromVal(const PJsonVal& Val, TChA& ChA){
00183   switch (Val->GetJsonValType()){
00184     case jvtNull: 
00185       ChA+="null"; break;
00186     case jvtBool:
00187       if (Val->GetBool()){ChA+="true";} else {ChA+="false";} break;
00188     case jvtNum: 
00189       ChA+=TStr::Fmt("%g", Val->GetNum()); break;
00190     case jvtStr:
00191       AddQChAFromStr(Val->GetStr(), ChA); break;
00192     case jvtArr:
00193       ChA+="[";
00194       for (int ArrValN=0; ArrValN<Val->GetArrVals(); ArrValN++){
00195         if (ArrValN>0){ChA+=", ";}
00196         GetChAFromVal(Val->GetArrVal(ArrValN), ChA);
00197       }
00198       ChA+="]"; 
00199       break;
00200     case jvtObj:
00201       ChA+="{";
00202       for (int ObjKeyN=0; ObjKeyN<Val->GetObjKeys(); ObjKeyN++){
00203         if (ObjKeyN>0){ChA+=", ";}
00204         TStr ObjKey; PJsonVal ObjVal; Val->GetObjKeyVal(ObjKeyN, ObjKey, ObjVal);
00205         AddQChAFromStr(ObjKey, ChA);
00206         ChA+=":";
00207         GetChAFromVal(ObjVal, ChA);
00208       }
00209       ChA+="}"; 
00210       break;
00211         default: TExcept::Throw("Error parsing json");
00212   }
00213 }
00214 
00215 TStr TJsonVal::GetStrFromVal(const PJsonVal& Val){
00216   TChA ChA;
00217   GetChAFromVal(Val, ChA);
00218   return ChA;
00219 }