SNAP Library, User Reference  2012-10-15 15:06:59
SNAP, a general purpose network analysis and graph mining library
 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 }