JSONValue.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. //
  2. // Copyright (c) 2008-2015 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:addmember
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "../Precompiled.h"
  23. #include "../Core/Context.h"
  24. #include "../IO/Log.h"
  25. #include "../Resource/JSONValue.h"
  26. #include "../DebugNew.h"
  27. namespace Urho3D
  28. {
  29. const JSONValue JSONValue::EMPTY;
  30. const JSONArray JSONValue::emptyArray;
  31. const JSONObject JSONValue::emptyObject;
  32. JSONValue& JSONValue::operator =(bool rhs)
  33. {
  34. SetType(JSON_BOOL);
  35. boolValue_ = rhs;
  36. return *this;
  37. }
  38. JSONValue& JSONValue::operator =(int rhs)
  39. {
  40. SetType(JSON_NUMBER, JSONNT_INT);
  41. numberValue_ = rhs;
  42. return *this;
  43. }
  44. JSONValue& JSONValue::operator =(unsigned rhs)
  45. {
  46. SetType(JSON_NUMBER, JSONNT_UINT);
  47. numberValue_ = rhs;
  48. return *this;
  49. }
  50. JSONValue& JSONValue::operator =(float rhs)
  51. {
  52. SetType(JSON_NUMBER, JSONNT_FLOAT_DOUBLE);
  53. numberValue_ = rhs;
  54. return *this;
  55. }
  56. JSONValue& JSONValue::operator =(double rhs)
  57. {
  58. SetType(JSON_NUMBER, JSONNT_FLOAT_DOUBLE);
  59. numberValue_ = rhs;
  60. return *this;
  61. }
  62. JSONValue& JSONValue::operator =(const String& rhs)
  63. {
  64. SetType(JSON_STRING);
  65. *stringValue_ = rhs;
  66. return *this;
  67. }
  68. JSONValue& JSONValue::operator =(const char* rhs)
  69. {
  70. SetType(JSON_STRING);
  71. *stringValue_ = rhs;
  72. return *this;
  73. }
  74. JSONValue& JSONValue::operator =(const JSONArray& rhs)
  75. {
  76. SetType(JSON_ARRAY);
  77. *arrayValue_ = rhs;
  78. return *this;
  79. }
  80. JSONValue& JSONValue::operator =(const JSONObject& rhs)
  81. {
  82. SetType(JSON_OBJECT);
  83. *objectValue_ = rhs;
  84. return *this;
  85. }
  86. JSONValue& JSONValue::operator =(const JSONValue& rhs)
  87. {
  88. if (this == &rhs)
  89. return *this;
  90. SetType(rhs.GetValueType(), rhs.GetNumberType());
  91. switch (GetValueType())
  92. {
  93. case JSON_BOOL:
  94. boolValue_ = rhs.boolValue_;
  95. break;
  96. case JSON_NUMBER:
  97. numberValue_ = rhs.numberValue_;
  98. break;
  99. case JSON_STRING:
  100. *stringValue_ = *rhs.stringValue_;
  101. break;
  102. case JSON_ARRAY:
  103. *arrayValue_ = *rhs.arrayValue_;
  104. break;
  105. case JSON_OBJECT:
  106. *objectValue_ = *rhs.objectValue_;
  107. default:
  108. break;
  109. }
  110. return *this;
  111. }
  112. JSONValueType JSONValue::GetValueType() const
  113. {
  114. return (JSONValueType)(type_ >> 16);
  115. }
  116. JSONNumberType JSONValue::GetNumberType() const
  117. {
  118. return (JSONNumberType)(type_ & 0xffff);
  119. }
  120. JSONValue& JSONValue::operator [](unsigned index)
  121. {
  122. // Convert to array type
  123. SetType(JSON_ARRAY);
  124. return (*arrayValue_)[index];
  125. }
  126. const JSONValue& JSONValue::operator [](unsigned index) const
  127. {
  128. if (GetValueType() != JSON_ARRAY)
  129. return EMPTY;
  130. return (*arrayValue_)[index];
  131. }
  132. void JSONValue::Push(const JSONValue& value)
  133. {
  134. // Convert to array type
  135. SetType(JSON_ARRAY);
  136. arrayValue_->Push(value);
  137. }
  138. void JSONValue::Pop()
  139. {
  140. if (GetValueType() != JSON_ARRAY)
  141. return;
  142. arrayValue_->Pop();
  143. }
  144. void JSONValue::Insert(unsigned pos, const JSONValue& value)
  145. {
  146. if (GetValueType() != JSON_ARRAY)
  147. return;
  148. arrayValue_->Insert(pos, value);
  149. }
  150. void JSONValue::Erase(unsigned pos, unsigned length)
  151. {
  152. if (GetValueType() != JSON_ARRAY)
  153. return;
  154. arrayValue_->Erase(pos, length);
  155. }
  156. void JSONValue::Resize(unsigned newSize)
  157. {
  158. // Convert to array type
  159. SetType(JSON_ARRAY);
  160. arrayValue_->Resize(newSize);
  161. }
  162. unsigned JSONValue::Size() const
  163. {
  164. if (GetValueType() == JSON_ARRAY)
  165. return arrayValue_->Size();
  166. return 0;
  167. }
  168. JSONValue& JSONValue::operator [](const String& key)
  169. {
  170. // Convert to object type
  171. SetType(JSON_OBJECT);
  172. return (*objectValue_)[key];
  173. }
  174. const JSONValue& JSONValue::operator [](const String& key) const
  175. {
  176. if (GetValueType() != JSON_OBJECT)
  177. return EMPTY;
  178. return (*objectValue_)[key];
  179. }
  180. void JSONValue::Set(const String& key, const JSONValue& value)
  181. {
  182. // Convert to object type
  183. SetType(JSON_OBJECT);
  184. (*objectValue_)[key] = value;
  185. }
  186. const JSONValue& JSONValue::Get(const String& key) const
  187. {
  188. if (GetValueType() != JSON_OBJECT)
  189. return EMPTY;
  190. JSONObject::ConstIterator i = objectValue_->Find(key);
  191. if (i == objectValue_->End())
  192. return EMPTY;
  193. return i->second_;
  194. }
  195. bool JSONValue::Erase(const String& key)
  196. {
  197. if (GetValueType() != JSON_OBJECT)
  198. return false;
  199. return objectValue_->Erase(key);
  200. }
  201. bool JSONValue::Contains(const String& key) const
  202. {
  203. if (GetValueType() != JSON_OBJECT)
  204. return false;
  205. return objectValue_->Contains(key);
  206. }
  207. JSONObjectIterator JSONValue::Begin()
  208. {
  209. // Convert to object type.
  210. SetType(JSON_OBJECT);
  211. return objectValue_->Begin();
  212. }
  213. ConstJSONObjectIterator JSONValue::Begin() const
  214. {
  215. if (GetValueType() != JSON_OBJECT)
  216. return emptyObject.Begin();
  217. return objectValue_->Begin();
  218. }
  219. JSONObjectIterator JSONValue::End()
  220. {
  221. // Convert to object type.
  222. SetType(JSON_OBJECT);
  223. return objectValue_->Begin();
  224. }
  225. ConstJSONObjectIterator JSONValue::End() const
  226. {
  227. if (GetValueType() != JSON_OBJECT)
  228. return emptyObject.End();
  229. return objectValue_->End();
  230. }
  231. void JSONValue::Clear()
  232. {
  233. if (GetValueType() == JSON_ARRAY)
  234. arrayValue_->Clear();
  235. else if (GetValueType() == JSON_OBJECT)
  236. objectValue_->Clear();
  237. }
  238. void JSONValue::SetType(JSONValueType valueType, JSONNumberType numberType)
  239. {
  240. int type = (valueType << 16) | numberType;
  241. if (type == type_)
  242. return;
  243. switch (GetValueType())
  244. {
  245. case JSON_STRING:
  246. delete stringValue_;
  247. break;
  248. case JSON_ARRAY:
  249. delete arrayValue_;
  250. break;
  251. case JSON_OBJECT:
  252. delete objectValue_;
  253. break;
  254. default:
  255. break;
  256. }
  257. type_ = type;
  258. switch (GetValueType())
  259. {
  260. case JSON_STRING:
  261. stringValue_ = new String();
  262. break;
  263. case JSON_ARRAY:
  264. arrayValue_ = new JSONArray();
  265. break;
  266. case JSON_OBJECT:
  267. objectValue_ = new JSONObject();
  268. break;
  269. default:
  270. break;
  271. }
  272. }
  273. void JSONValue::SetVariant(const Variant& variant, Context* context)
  274. {
  275. if (!IsNull())
  276. {
  277. URHO3D_LOGWARNING("JsonValue is not null");
  278. }
  279. (*this)["type"] = variant.GetTypeName();
  280. (*this)["value"].SetVariantValue(variant, context);
  281. }
  282. Variant JSONValue::GetVariant() const
  283. {
  284. VariantType type = Variant::GetTypeFromName((*this)["type"].GetString());
  285. return (*this)["value"].GetVariantValue(type);
  286. }
  287. void JSONValue::SetVariantValue(const Variant& variant, Context* context)
  288. {
  289. if (!IsNull())
  290. {
  291. URHO3D_LOGWARNING("JsonValue is not null");
  292. }
  293. switch (variant.GetType())
  294. {
  295. case VAR_BOOL:
  296. *this = variant.GetBool();
  297. return;
  298. case VAR_INT:
  299. *this = variant.GetInt();
  300. return;
  301. case VAR_FLOAT:
  302. *this = variant.GetFloat();
  303. return;
  304. case VAR_DOUBLE:
  305. *this = variant.GetDouble();
  306. return;
  307. case VAR_STRING:
  308. *this = variant.GetString();
  309. return;
  310. case VAR_VARIANTVECTOR:
  311. SetVariantVector(variant.GetVariantVector(), context);
  312. return;
  313. case VAR_VARIANTMAP:
  314. SetVariantMap(variant.GetVariantMap(), context);
  315. return;
  316. case VAR_RESOURCEREF:
  317. {
  318. if (!context)
  319. {
  320. URHO3D_LOGERROR("Context must not null for ResourceRef");
  321. return;
  322. }
  323. const ResourceRef& ref = variant.GetResourceRef();
  324. *this = String(context->GetTypeName(ref.type_)) + ";" + ref.name_;
  325. }
  326. return;
  327. case VAR_RESOURCEREFLIST:
  328. {
  329. if (!context)
  330. {
  331. URHO3D_LOGERROR("Context must not null for ResourceRefList");
  332. return;
  333. }
  334. const ResourceRefList& refList = variant.GetResourceRefList();
  335. String str(context->GetTypeName(refList.type_));
  336. for (unsigned i = 0; i < refList.names_.Size(); ++i)
  337. {
  338. str += ";";
  339. str += refList.names_[i];
  340. }
  341. *this = str;
  342. }
  343. return;
  344. case VAR_STRINGVECTOR:
  345. {
  346. const StringVector& vector = variant.GetStringVector();
  347. Resize(vector.Size());
  348. for (unsigned i = 0; i < vector.Size(); ++i)
  349. (*this)[i] = vector[i];
  350. }
  351. return;
  352. default:
  353. *this = variant.ToString();
  354. }
  355. }
  356. Variant JSONValue::GetVariantValue(VariantType type) const
  357. {
  358. Variant variant;
  359. switch (type)
  360. {
  361. case VAR_BOOL:
  362. variant = GetBool();
  363. break;
  364. case VAR_INT:
  365. variant = GetInt();
  366. break;
  367. case VAR_FLOAT:
  368. variant = GetFloat();
  369. break;
  370. case VAR_DOUBLE:
  371. variant = GetDouble();
  372. break;
  373. case VAR_STRING:
  374. variant = GetString();
  375. break;
  376. case VAR_VARIANTVECTOR:
  377. variant = GetVariantVector();
  378. break;
  379. case VAR_VARIANTMAP:
  380. variant = GetVariantMap();
  381. break;
  382. case VAR_RESOURCEREF:
  383. {
  384. ResourceRef ref;
  385. Vector<String> values = GetString().Split(';');
  386. if (values.Size() == 2)
  387. {
  388. ref.type_ = values[0];
  389. ref.name_ = values[1];
  390. }
  391. variant = ref;
  392. }
  393. break;
  394. case VAR_RESOURCEREFLIST:
  395. {
  396. ResourceRefList refList;
  397. Vector<String> values = GetString().Split(';');
  398. if (values.Size() >= 1)
  399. {
  400. refList.type_ = values[0];
  401. refList.names_.Resize(values.Size() - 1);
  402. for (unsigned i = 1; i < values.Size(); ++i)
  403. refList.names_[i - 1] = values[i];
  404. }
  405. variant = refList;
  406. }
  407. break;
  408. case VAR_STRINGVECTOR:
  409. {
  410. StringVector vector;
  411. for (unsigned i = 0; i < Size(); ++i)
  412. vector.Push((*this)[i].GetString());
  413. variant = vector;
  414. }
  415. break;
  416. default:
  417. variant.FromString(type, GetString());
  418. }
  419. return variant;
  420. }
  421. void JSONValue::SetVariantMap(const VariantMap& variantMap, Context* context)
  422. {
  423. SetType(JSON_OBJECT);
  424. for (VariantMap::ConstIterator i = variantMap.Begin(); i != variantMap.End(); ++i)
  425. (*this)[i->first_.ToString()].SetVariant(i->second_);
  426. }
  427. VariantMap JSONValue::GetVariantMap() const
  428. {
  429. VariantMap variantMap;
  430. if (!IsObject())
  431. {
  432. URHO3D_LOGERROR("JSONValue is not a object");
  433. return variantMap;
  434. }
  435. for (ConstJSONObjectIterator i = Begin(); i != End(); ++i)
  436. {
  437. StringHash key(ToUInt(i->first_));
  438. Variant variant = i->second_.GetVariant();
  439. variantMap[key] = variant;
  440. }
  441. return variantMap;
  442. }
  443. void JSONValue::SetVariantVector(const VariantVector& variantVector, Context* context)
  444. {
  445. SetType(JSON_ARRAY);
  446. for (unsigned i = 0; i < variantVector.Size(); ++i)
  447. (*this)[i].SetVariant(variantVector[i]);
  448. }
  449. VariantVector JSONValue::GetVariantVector() const
  450. {
  451. VariantVector variantVector;
  452. if (!IsArray())
  453. {
  454. URHO3D_LOGERROR("JSONValue is not a array");
  455. return variantVector;
  456. }
  457. for (unsigned i = 0; i < Size(); ++i)
  458. {
  459. Variant variant = (*this)[i].GetVariant();
  460. variantVector.Push(variant);
  461. }
  462. return variantVector;
  463. }
  464. }