PListFile.cpp 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. //
  2. // Copyright (c) 2008-2014 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:
  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 "Context.h"
  24. #include "Deserializer.h"
  25. #include "Log.h"
  26. #include "PListFile.h"
  27. #include "XMLFile.h"
  28. #include <stdio.h>
  29. #include "DebugNew.h"
  30. namespace Urho3D
  31. {
  32. static PListValue EMPTY_VALUE;
  33. static PListValueMap EMPTY_VALUEMAP;
  34. static PListValueVector EMPTY_VALUEVECTOR;
  35. PListValue& PListValueMap::operator [](const String& key)
  36. {
  37. return HashMap<String, PListValue>::operator [](key);
  38. }
  39. const PListValue& PListValueMap::operator [](const String& key) const
  40. {
  41. ConstIterator i = Find(key);
  42. if (i == End())
  43. return EMPTY_VALUE;
  44. return i->second_;
  45. }
  46. PListValue::PListValue() : type_(PLVT_NONE)
  47. {
  48. }
  49. PListValue::PListValue(int value) : type_(PLVT_NONE)
  50. {
  51. SetInt(value);
  52. }
  53. PListValue::PListValue(bool value) : type_(PLVT_NONE)
  54. {
  55. SetBool(value);
  56. }
  57. PListValue::PListValue(float value) : type_(PLVT_NONE)
  58. {
  59. SetFloat(value);
  60. }
  61. PListValue::PListValue(const String& value) : type_(PLVT_NONE)
  62. {
  63. SetString(value);
  64. }
  65. PListValue::PListValue(PListValueMap& valueMap) : type_(PLVT_NONE)
  66. {
  67. SetValueMap(valueMap);
  68. }
  69. PListValue::PListValue(PListValueVector& valueVector) : type_(PLVT_NONE)
  70. {
  71. SetValueVector(valueVector);
  72. }
  73. PListValue::PListValue(const PListValue& value) : type_(PLVT_NONE)
  74. {
  75. *this = value;
  76. }
  77. PListValue::~PListValue()
  78. {
  79. Reset();
  80. }
  81. PListValue& PListValue::operator = (const PListValue& rhs)
  82. {
  83. switch (rhs.type_)
  84. {
  85. case PLVT_NONE:
  86. Reset();
  87. break;
  88. case PLVT_INT:
  89. SetInt(rhs.int_);
  90. break;
  91. case PLVT_BOOL:
  92. SetBool(rhs.bool_);
  93. break;
  94. case PLVT_FLOAT:
  95. SetFloat(rhs.float_);
  96. break;
  97. case PLVT_STRING:
  98. SetString(*rhs.string_);
  99. break;
  100. case PLVT_VALUEMAP:
  101. SetValueMap(*rhs.valueMap_);
  102. break;
  103. case PLVT_VALUEVECTOR:
  104. SetValueVector(*rhs.valueVector_);
  105. break;
  106. }
  107. return *this;
  108. }
  109. void PListValue::SetInt(int value)
  110. {
  111. if (type_ != PLVT_INT)
  112. {
  113. Reset();
  114. type_ = PLVT_INT;
  115. }
  116. int_ = value;
  117. }
  118. void PListValue::SetBool(bool value)
  119. {
  120. if (type_ != PLVT_BOOL)
  121. {
  122. Reset();
  123. type_ = PLVT_BOOL;
  124. }
  125. bool_ = value;
  126. }
  127. void PListValue::SetFloat(float value)
  128. {
  129. if (type_ != PLVT_FLOAT)
  130. {
  131. Reset();
  132. type_ = PLVT_FLOAT;
  133. }
  134. float_ = value;
  135. }
  136. void PListValue::SetString(const String& value)
  137. {
  138. if (type_ != PLVT_STRING)
  139. {
  140. Reset();
  141. type_ = PLVT_STRING;
  142. string_ = new String();
  143. }
  144. *string_ = value;
  145. }
  146. void PListValue::SetValueMap(const PListValueMap& valueMap)
  147. {
  148. if (type_ != PLVT_VALUEMAP)
  149. {
  150. Reset();
  151. type_ = PLVT_VALUEMAP;
  152. valueMap_ = new PListValueMap();
  153. }
  154. *valueMap_ = valueMap;
  155. }
  156. void PListValue::SetValueVector(const PListValueVector& valueVector)
  157. {
  158. if (type_ != PLVT_VALUEVECTOR)
  159. {
  160. Reset();
  161. type_ = PLVT_VALUEVECTOR;
  162. valueVector_ = new PListValueVector();
  163. }
  164. *valueVector_ = valueVector;
  165. }
  166. int PListValue::GetInt() const
  167. {
  168. return type_ == PLVT_INT ? int_ : 0;
  169. }
  170. bool PListValue::GetBool() const
  171. {
  172. return type_ == PLVT_BOOL ? bool_ : false;
  173. }
  174. float PListValue::GetFloat() const
  175. {
  176. return type_ == PLVT_FLOAT? float_ : 0.0f;
  177. }
  178. const String& PListValue::GetString() const
  179. {
  180. return type_ == PLVT_STRING ? * string_ : String::EMPTY;
  181. }
  182. IntRect PListValue::GetIntRect() const
  183. {
  184. if (type_ != PLVT_STRING)
  185. return IntRect::ZERO;
  186. int x, y, w, h;
  187. sscanf(string_->CString(), "{{%d,%d},{%d,%d}}", &x, &y, &w, &h);
  188. return IntRect(x, y, x + w, y + h);
  189. }
  190. IntVector2 PListValue::GetIntVector2() const
  191. {
  192. if (type_ != PLVT_STRING)
  193. return IntVector2::ZERO;
  194. int x, y;
  195. sscanf(string_->CString(), "{%d,%d}", &x, &y);
  196. return IntVector2(x, y);
  197. }
  198. const PListValueMap& PListValue::GetValueMap() const
  199. {
  200. return type_ == PLVT_VALUEMAP ? *valueMap_ : EMPTY_VALUEMAP;
  201. }
  202. const PListValueVector& PListValue::GetValueVector() const
  203. {
  204. return type_ == PLVT_VALUEVECTOR? *valueVector_ : EMPTY_VALUEVECTOR;
  205. }
  206. PListValueMap& PListValue::ConvertToValueMap()
  207. {
  208. if (type_ != PLVT_VALUEMAP)
  209. {
  210. Reset();
  211. type_ = PLVT_VALUEMAP;
  212. valueMap_ = new PListValueMap();
  213. }
  214. return *valueMap_;
  215. }
  216. PListValueVector& PListValue::ConvertToValueVector()
  217. {
  218. if (type_ != PLVT_VALUEVECTOR)
  219. {
  220. Reset();
  221. type_ = PLVT_VALUEVECTOR;
  222. valueVector_ = new PListValueVector();
  223. }
  224. return *valueVector_;
  225. }
  226. void PListValue::Reset()
  227. {
  228. if (type_ == PLVT_NONE)
  229. return;
  230. switch (type_)
  231. {
  232. case PLVT_STRING:
  233. delete string_;
  234. break;
  235. case PLVT_VALUEMAP:
  236. delete valueMap_;
  237. break;
  238. case PLVT_VALUEVECTOR:
  239. delete valueVector_;
  240. break;
  241. default:
  242. break;
  243. }
  244. type_ = PLVT_NONE;
  245. }
  246. PListFile::PListFile(Context* context) :
  247. Resource(context)
  248. {
  249. }
  250. PListFile::~PListFile()
  251. {
  252. }
  253. void PListFile::RegisterObject(Context* context)
  254. {
  255. context->RegisterFactory<PListFile>();
  256. }
  257. bool PListFile::BeginLoad(Deserializer& source)
  258. {
  259. if (GetName().Empty())
  260. SetName(source.GetName());
  261. XMLFile xmlFile(context_);
  262. if (!xmlFile.Load(source))
  263. {
  264. LOGERROR("Could not load property list");
  265. return false;
  266. }
  267. XMLElement plistElem = xmlFile.GetRoot("plist");
  268. if (!plistElem)
  269. {
  270. LOGERROR("Invalid property list file");
  271. return false;
  272. }
  273. root_.Clear();
  274. XMLElement dictElem = plistElem.GetChild("dict");
  275. if (!LoadDict(root_, dictElem))
  276. return false;
  277. SetMemoryUse(source.GetSize());
  278. return true;
  279. }
  280. bool PListFile::LoadDict(PListValueMap& dict, const XMLElement& dictElem)
  281. {
  282. if (!dictElem)
  283. return false;
  284. XMLElement keyElem = dictElem.GetChild("key");
  285. XMLElement valueElem = keyElem.GetNext();
  286. while (keyElem && valueElem)
  287. {
  288. String key = keyElem.GetValue();
  289. XMLElement valueElem = keyElem.GetNext();
  290. PListValue value;
  291. if (!LoadValue(value, valueElem))
  292. return false;
  293. dict[key] = value;
  294. keyElem = valueElem.GetNext("key");
  295. valueElem = keyElem.GetNext();
  296. }
  297. return true;
  298. }
  299. bool PListFile::LoadArray(PListValueVector& array, const XMLElement& arrayElem)
  300. {
  301. if (!arrayElem)
  302. return false;
  303. for (XMLElement valueElem = arrayElem.GetChild(); valueElem; valueElem = valueElem.GetNext())
  304. {
  305. PListValue value;
  306. if (!LoadValue(value, valueElem))
  307. return false;
  308. array.Push(value);
  309. }
  310. return true;
  311. }
  312. bool PListFile::LoadValue(PListValue& value, XMLElement valueElem)
  313. {
  314. String valueType = valueElem.GetName();
  315. if (valueType == "string")
  316. value.SetString(valueElem.GetValue());
  317. else if (valueType == "real")
  318. value.SetFloat(ToFloat(valueElem.GetValue()));
  319. else if (valueType == "integer")
  320. value.SetInt(ToInt(valueElem.GetValue()));
  321. else if (valueType == "true")
  322. value.SetBool(true);
  323. else if (valueType == "false")
  324. value.SetBool(false);
  325. else if (valueType == "dict")
  326. {
  327. if (!LoadDict(value.ConvertToValueMap(), valueElem))
  328. return false;
  329. }
  330. else if (valueType == "array")
  331. {
  332. if (!LoadArray(value.ConvertToValueVector(), valueElem))
  333. return false;
  334. }
  335. else
  336. {
  337. LOGERROR("Supported value type");
  338. return false;
  339. }
  340. return true;
  341. }
  342. }