ffead.server.doc
JSONUtil.cpp
1 /*
2  Copyright 2009-2012, Sumeet Chhetri
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 */
16 /*
17  * JSONUtil.cpp
18  *
19  * Created on: 06-Aug-2012
20  * Author: sumeetc
21  */
22 
23 #include "JSONUtil.h"
24 
25 JSONUtil::JSONUtil() {
26  // TODO Auto-generated constructor stub
27 
28 }
29 
30 JSONUtil::~JSONUtil() {
31  // TODO Auto-generated destructor stub
32 }
33 
34 void JSONUtil::array(string& json, JSONElement* element)
35 {
36  while(json.find("[")!=string::npos && json.find("]")!=string::npos)
37  {
38  element->setType(JSONElement::JSON_ARRAY);
39  StringUtil::replaceFirst(json, "[", "");
40  StringUtil::replaceLast(json, "]", "");
41  readJSON(json,true,element);
42  }
43 }
44 
45 void JSONUtil::object(string& json, JSONElement* element)
46 {
47  while(json.find("{")!=string::npos && json.find("}")!=string::npos)
48  {
49  element->setType(JSONElement::JSON_OBJECT);
50  StringUtil::replaceFirst(json, "{", "");
51  StringUtil::replaceLast(json, "}", "");
52  readJSON(json,false,element);
53  }
54 }
55 
56 void JSONUtil::arrayOrObject(string& json, JSONElement* element)
57 {
58  while((json.find("{")!=string::npos && json.find("}")!=string::npos)
59  || (json.find("[")!=string::npos && json.find("]")!=string::npos))
60  {
61  int arrst = json.find("[");
62  int objst = json.find("{");
63  if(json.find("{")!=string::npos && json.find("}")!=string::npos && (objst<arrst || arrst==(int)string::npos))
64  {
65  element->setType(JSONElement::JSON_OBJECT);
66  StringUtil::replaceFirst(json, "{", "");
67  StringUtil::replaceLast(json, "}", "");
68  readJSON(json,false,element);
69  }
70  else if(json.find("[")!=string::npos && json.find("]")!=string::npos)
71  {
72  element->setType(JSONElement::JSON_ARRAY);
73  StringUtil::replaceFirst(json, "[", "");
74  StringUtil::replaceLast(json, "]", "");
75  readJSON(json,true,element);
76  }
77  }
78 }
79 
80 void JSONUtil::readJSON(string& json,bool isarray,JSONElement *par)
81 {
82  if(json=="")
83  return;
84  string name, value;
85  if(!isarray)
86  {
87  size_t stn = json.find("\"");
88  while(stn!=string::npos && stn>0 && json.at(stn-1)=='\\')
89  {
90  stn = json.find("\"", stn+1);
91  if(stn==0)
92  {
93  stn = string::npos;
94  }
95  }
96  if(stn==string::npos)
97  throw ("invalid json - no start '\"' found for name parameter");
98  size_t enn = json.find("\"", stn+1);
99  while(enn!=string::npos && enn>0 && json.at(enn-1)=='\\')
100  {
101  enn = json.find("\"", enn+1);
102  if(enn==0)
103  {
104  enn = string::npos;
105  }
106  }
107  if(enn==string::npos)
108  throw ("invalid json - no end '\"' found for name parameter");
109  if(stn!=enn-1)
110  name = json.substr(stn+1, (enn-stn-1));
111  //StringUtil::trim(name);
112  json = json.substr(enn+1);
113  StringUtil::trim(json);
114  size_t vst = json.find(":");
115  if(vst==string::npos)
116  throw ("invalid json - no ':' found");
117  else if(vst!=0)
118  throw ("invalid json - invalid json - invalid string before ':' found");
119  json = json.substr(vst+1);
120  }
121  JSONElement* element = new JSONElement();
122  element->setName(name);
123 
124  StringUtil::trim(json);
125  size_t env = json.find(",");
126  size_t obs = json.find("{");
127  size_t ars = json.find("[");
128  if(obs==0)
129  {
130  size_t sss = json.find("{", obs+1);
131  size_t eee = json.find("}", obs);
132  size_t obe = eee;
133  if(sss<eee)
134  {
135  while(sss<eee)
136  {
137  sss = json.find("{", sss+1);
138  if(sss!=string::npos)
139  {
140  eee = json.find("}", sss);
141  }
142  if(eee!=string::npos)
143  obe = eee;
144  }
145  if(eee!=string::npos && json.find("}", eee+1)!=string::npos)
146  obe = json.find("}", eee+1);
147  }
148  value = json.substr(obs, obe-obs+1);
149  json = json.substr(obe+1);
150  element->setType(JSONElement::JSON_OBJECT);
151  }
152  else if(ars==0)
153  {
154  size_t sss = json.find("[", ars+1);
155  size_t eee = json.find("]", ars);
156  size_t are = eee;
157  if(sss<eee)
158  {
159  while(sss<eee)
160  {
161  sss = json.find("[", sss+1);
162  if(sss!=string::npos)
163  {
164  eee = json.find("]", sss);
165  }
166  if(eee!=string::npos)
167  are = eee;
168  }
169  if(eee!=string::npos && json.find("]", eee+1)!=string::npos)
170  are = json.find("]", eee+1);
171  }
172  value = json.substr(ars, are-ars+1);
173  json = json.substr(are+1);
174  element->setType(JSONElement::JSON_ARRAY);
175  }
176  else if(env==string::npos)
177  {
178  value = json;
179  json = "";
180  element->setType(JSONElement::JSON_STRING);
181  }
182  else
183  {
184  if(obs!=string::npos && env==0 && (obs<ars || ars==string::npos))
185  {
186  size_t sss = json.find("{", obs+1);
187  size_t eee = json.find("}", obs);
188  size_t obe = eee;
189  if(sss<eee)
190  {
191  while(sss<eee)
192  {
193  sss = json.find("{", sss+1);
194  if(sss!=string::npos)
195  {
196  eee = json.find("}", sss);
197  }
198  if(eee!=string::npos)
199  obe = eee;
200  }
201  if(eee!=string::npos && json.find("}", eee+1)!=string::npos)
202  obe = json.find("}", eee+1);
203  }
204  value = json.substr(obs, obe-obs+1);
205  json = json.substr(obe+1);
206  element->setType(JSONElement::JSON_OBJECT);
207  }
208  else if(ars!=string::npos && env==0 && (ars<obs || obs==string::npos))
209  {
210  size_t sss = json.find("[", ars+1);
211  size_t eee = json.find("]", ars);
212  size_t are = eee;
213  if(sss<eee)
214  {
215  while(sss<eee)
216  {
217  sss = json.find("[", sss+1);
218  if(sss!=string::npos)
219  {
220  eee = json.find("]", sss);
221  }
222  if(eee!=string::npos)
223  are = eee;
224  }
225  if(eee!=string::npos && json.find("]", eee+1)!=string::npos)
226  are = json.find("]", eee+1);
227  }
228  value = json.substr(ars, are-ars+1);
229  json = json.substr(are+1);
230  element->setType(JSONElement::JSON_ARRAY);
231  }
232  else if(obs!=string::npos && obs<env && (obs<ars || ars==string::npos))
233  {
234  size_t sss = json.find("{", obs+1);
235  size_t eee = json.find("}", obs);
236  size_t obe = eee;
237  if(sss<eee)
238  {
239  while(sss<eee)
240  {
241  sss = json.find("{", sss+1);
242  if(sss!=string::npos)
243  {
244  eee = json.find("}", sss);
245  }
246  if(eee!=string::npos)
247  obe = eee;
248  }
249  if(eee!=string::npos && json.find("}", eee+1)!=string::npos)
250  obe = json.find("}", eee+1);
251  }
252  value = json.substr(obs, obe-obs+1);
253  json = json.substr(obe+1);
254  element->setType(JSONElement::JSON_OBJECT);
255  }
256  else if(ars!=string::npos && ars<env && (ars<obs || obs==string::npos))
257  {
258  size_t sss = json.find("[", ars+1);
259  size_t eee = json.find("]", ars);
260  size_t are = eee;
261  if(sss<eee)
262  {
263  while(sss<eee)
264  {
265  sss = json.find("[", sss+1);
266  if(sss!=string::npos)
267  {
268  eee = json.find("]", sss);
269  }
270  if(eee!=string::npos)
271  are = eee;
272  }
273  if(eee!=string::npos && json.find("]", eee+1)!=string::npos)
274  are = json.find("]", eee+1);
275  }
276  value = json.substr(ars, are-ars+1);
277  json = json.substr(are+1);
278  element->setType(JSONElement::JSON_ARRAY);
279  }
280  else
281  {
282  value = json.substr(0, env);
283  json = json.substr(env+1);
284  element->setType(JSONElement::JSON_STRING);
285  }
286  }
287  if(value=="")
288  {
289  string ex = "invalid json - no value object found for name "+ name;
290  throw (ex.c_str());
291  }
292  if(element->getType()!=JSONElement::JSON_OBJECT && element->getType()!=JSONElement::JSON_ARRAY)
293  {
294  validateSetValue(element, value);
295  }
296  par->addChild(element);
297  if(element->getType()==JSONElement::JSON_OBJECT)
298  object(value, element);
299  else if(element->getType()==JSONElement::JSON_ARRAY)
300  array(value, element);
301  readJSON(json,isarray,par);
302 }
303 
304 void JSONUtil::validateSetValue(JSONElement* element, string value)
305 {
306  StringUtil::trim(value);
307  size_t stn = value.find("\"");
308  if(stn!=string::npos)
309  {
310  while(stn!=string::npos && stn>0 && value.at(stn-1)=='\\')
311  {
312  stn = value.find("\"", stn+1);
313  if(stn==0)
314  {
315  stn = string::npos;
316  }
317  }
318  size_t enn = value.find("\"", stn+1);
319  while(enn!=string::npos && enn>0 && value.at(enn-1)=='\\')
320  {
321  enn = value.find("\"", enn+1);
322  if(enn==0)
323  {
324  enn = string::npos;
325  }
326  }
327  if(enn==string::npos)
328  {
329  string ex = "invalid json - invalid string object '"+value+"' found for name "+ element->getName();
330  throw (ex.c_str());
331  }
332  else if(enn!=value.length()-1)
333  {
334  string ex = "invalid json - invalid literal found after string object '"+value+"' for name "+ element->getName();
335  throw (ex.c_str());
336  }
337  if(stn!=enn-1)
338  {
339  value = value.substr(stn+1, (enn-stn-1));
340  }
341  else
342  {
343  value = "";
344  }
345  element->setType(JSONElement::JSON_STRING);
346  }
347  else if(StringUtil::toLowerCopy(value)=="true" || StringUtil::toLowerCopy(value)=="false")
348  {
349  value = StringUtil::toLowerCopy(value);
350  element->setType(JSONElement::JSON_BOOL);
351  }
352  else if(value.find(".")!=string::npos)
353  {
354  try
355  {
356  CastUtil::lexical_cast<double>(value);
357  } catch (const char* ex) {
358  string exp = "invalid json - invalid double value "+value+" found for name "+ element->getName();
359  throw (exp.c_str());
360  }
361  element->setType(JSONElement::JSON_FLOAT);
362  }
363  else
364  {
365  try
366  {
367  CastUtil::lexical_cast<int>(value);
368  } catch (const char* ex) {
369  try
370  {
371  CastUtil::lexical_cast<long>(value);
372  } catch (const char* ex) {
373  try
374  {
375  CastUtil::lexical_cast<long long>(value);
376  } catch (const char* ex) {
377  string exp = "invalid json - invalid numeric value "+value+" found for name "+ element->getName();
378  throw (exp.c_str());
379  }
380  }
381  }
382  element->setType(JSONElement::JSON_NUMBER);
383  }
384  element->setValue(value);
385 }
386 
387 JSONElement JSONUtil::getDocument(const string& jsonTxt)
388 {
389  string json(jsonTxt);
390  JSONElement root;
391  root.setType(JSONElement::JSON_OBJECT);
392  root.setName("_JSON_ROOT");
393  int arrst = json.find("[");
394  int objst = json.find("{");
395  if(json.find("{")!=string::npos && json.find("}")!=string::npos && (objst<arrst || arrst==(int)string::npos))
396  {
397  root.setType(JSONElement::JSON_OBJECT);
398  StringUtil::replaceFirst(json, "{", "");
399  StringUtil::replaceLast(json, "}", "");
400  readJSON(json,false,&root);
401  }
402  else if(json.find("[")!=string::npos && json.find("]")!=string::npos)
403  {
404  root.setType(JSONElement::JSON_ARRAY);
405  StringUtil::replaceFirst(json, "[", "");
406  StringUtil::replaceLast(json, "]", "");
407  readJSON(json,true,&root);
408  }
409  return root;
410 }
411 
412 string JSONUtil::getDocumentStr(JSONElement doc)
413 {
414  string jsonText;
415  if(doc.getType()==JSONElement::JSON_OBJECT)
416  jsonText += "{";
417  else
418  jsonText += "[";
419  if(doc.hasChildren())
420  {
421  for (int var = 0; var < (int)doc.getChildren().size(); ++var) {
422  JSONElement* child = doc.getChildren().at(var);
423  if(doc.getType()==JSONElement::JSON_OBJECT)
424  jsonText += "\"" + child->getName() + "\":";
425  if(child->getType()==JSONElement::JSON_OBJECT || child->getType()==JSONElement::JSON_ARRAY)
426  {
427  jsonText += getDocumentStr(*child);
428  }
429  else
430  {
431  if(child->getType()==JSONElement::JSON_STRING)
432  jsonText += "\"" + child->getValue() + "\"";
433  else
434  jsonText += child->getValue();
435  }
436  if(var!=(int)doc.getChildren().size()-1)
437  {
438  jsonText += ", ";
439  }
440  }
441  }
442  if(doc.getType()==JSONElement::JSON_OBJECT)
443  jsonText += "}";
444  else
445  jsonText += "]";
446  return jsonText;
447 }