基于C++怎么编写一个Json解析器

前端开发   发布日期:2023年08月10日   浏览次数:533

这篇文章主要介绍了基于C++怎么编写一个Json解析器的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇基于C++怎么编写一个Json解析器文章都会有所收获,下面我们一起来看看吧。

代码

JsonSerialize.h

  1. #pragma once
  2. #ifndef _JSON_SERIALIZE_
  3. #define _JSON_SERIALIZE_
  4. // #include "Util.h"
  5. #include <fstream>
  6. #include <string>
  7. #include <vector>
  8. #include <map>
  9. // NAME_SPACE_START(Json)
  10. enum JsonType {
  11. None,
  12. Number,
  13. String,
  14. Array,
  15. Bool,
  16. Null,
  17. Object
  18. };
  19. class JNull {
  20. public:
  21. JNull() {}
  22. ~JNull() {}
  23. };
  24. template<typename T>
  25. class JBaseObject {
  26. public:
  27. JBaseObject() {}
  28. virtual ~JBaseObject() {}
  29. virtual JBaseObject* clone() = 0;
  30. };
  31. template<typename T>
  32. class JHolderObject :public JBaseObject<T> {
  33. private:
  34. public:
  35. T value;
  36. JHolderObject(const T& val) :value(val) {}
  37. ~JHolderObject() {}
  38. JBaseObject<T>* clone() override;
  39. };
  40. template<typename ValueType>
  41. class JObject {
  42. private:
  43. JBaseObject<ValueType>* _value = nullptr;
  44. public:
  45. JObject() {}
  46. JObject(const ValueType& value);
  47. JObject(const JObject& obj) :_value(obj._value->clone()) {}
  48. ~JObject();
  49. JObject<ValueType>& operator=(const ValueType& value);
  50. ValueType* Cast() {
  51. JHolderObject<ValueType>* temp = dynamic_cast<JHolderObject<ValueType>*>(_value);
  52. return temp ? &temp->value : NULL;
  53. }
  54. ValueType& RefCast() {
  55. return (static_cast<JHolderObject<ValueType>*>(_value))->value;
  56. }
  57. };
  58. template<typename T>
  59. class JsonItemBase {
  60. public:
  61. JsonItemBase() {}
  62. virtual ~JsonItemBase() {}
  63. virtual void f() {}
  64. };
  65. template<typename T>
  66. class JsonItem {
  67. private:
  68. // JObject<T> _value;
  69. T _value;
  70. public:
  71. JsonItem() {}
  72. JsonItem(const JsonItem&);
  73. JsonItem(const JObject<T>& obj);
  74. JsonItem(const T& obj);
  75. ~JsonItem() {};
  76. T& GetItemRefValue() {
  77. return this->_value;
  78. }
  79. T* GetItemLpValue() {
  80. return &this->_value;
  81. }
  82. };
  83. class JsonKey {
  84. public:
  85. JsonType _type{ JsonType::None };
  86. std::wstring _key{ L"" };
  87. JsonKey() {}
  88. JsonKey(const JsonType& type, const std::wstring& key) :_type(type), _key(key) {}
  89. bool operator<(const JsonKey&) const;
  90. };
  91. class JsonValue {
  92. public:
  93. void* _value{ nullptr };
  94. size_t _size{ 0 };
  95. JsonValue() {}
  96. JsonValue(void* value, const int& size) :_value(value), _size(size) {}
  97. };
  98. class JsonSerialize {
  99. using string = std::string;
  100. private:
  101. std::vector<std::pair<JsonKey, JsonValue>> content;
  102. string _filePath;
  103. public:
  104. JsonSerialize() {}
  105. JsonSerialize(const string filePath);
  106. ~JsonSerialize() {};
  107. bool Load(const string filePath = "");
  108. template<typename T>
  109. JsonItem<T>* GetValueByKey(string key);
  110. std::vector<std::pair<JsonKey, JsonValue>>& GetContent();
  111. void printAll(int tab = 0);
  112. private:
  113. };
  114. // NAME_SPACE_END()
  115. #endif //!_JSON_SERIALIZE_

JsonSerialize.cpp

  1. #include "JsonSerialize.h"
  2. // #include "Util.h"
  3. #include <iostream>
  4. #include <sstream>
  5. #include <atomic>
  6. #include <exception>
  7. #include <fstream>
  8. #include <ios>
  9. #include <string>
  10. #include <utility>
  11. #include <vector>
  12. #include <stack>
  13. // NAME_SPACE_START(Json)
  14. template<typename T>
  15. JBaseObject<T>* JHolderObject<T>::clone() {
  16. return new JHolderObject<T>(this->value);
  17. }
  18. // template<typename T>
  19. // T& JHolderObject<T>::GetValue(){
  20. // return value;
  21. // }
  22. template<typename ValueType>
  23. JObject<ValueType>::JObject(const ValueType& value) {
  24. _value = new JHolderObject<ValueType>(value);
  25. }
  26. template<typename ValueType>
  27. JObject<ValueType>::~JObject() {
  28. if (_value) delete _value;
  29. }
  30. template<typename ValueType>
  31. JObject<ValueType>& JObject<ValueType>::operator=(const ValueType& value) {
  32. if (_value) delete _value;
  33. _value = new JHolderObject<ValueType>(value);
  34. return *this;
  35. }
  36. // template<typename ValueType>
  37. // ValueType* JObject<ValueType>::Cast(){
  38. // JHolderObject<ValueType>* temp=dynamic_cast<JHolderObject<ValueType>*>(_value);
  39. // return temp?&temp->GetValue():NULL;
  40. // }
  41. // template<typename ValueType>
  42. // ValueType& JObject<ValueType>::RefCast(){
  43. // return (dynamic_cast<JHolderObject<ValueType>&>(_value)).GetValue();
  44. // }
  45. // template<typename T>
  46. // JsonItem<T>::JsonItem(const JObject<T>& value)
  47. // :JsonItemBase<T>(){
  48. // this->_value=value;
  49. // }
  50. template<typename T>
  51. JsonItem<T>::JsonItem(const T& objList)
  52. {
  53. this->_value = objList;
  54. }
  55. // //获取值
  56. // template<typename T>
  57. // T& JsonItem<T>::GetItemRefValue(){
  58. // return this->_value.RefCast();
  59. // }
  60. // template<typename T>
  61. // T* JsonItem<T>::GetItemLpValue(){
  62. // return this->_value.Cast();
  63. // }
  64. std::ifstream _file;
  65. void OpenFile(const std::string filePath) {
  66. _file.open(filePath, std::ios::in);
  67. if (!_file.is_open()) return;
  68. }
  69. void CloseFile() {
  70. _file.close();
  71. }
  72. bool JsonKey::operator<(const JsonKey& j_key) const {
  73. return false;
  74. }
  75. JsonSerialize::JsonSerialize(const std::string filePath) {
  76. this->_filePath = filePath;
  77. }
  78. bool isFirst = true;
  79. bool isQuote = false;
  80. bool isKey = true;
  81. bool isObj = false;
  82. bool isObjEnd = true;
  83. bool isArrEnd = true;
  84. JsonType curType = JsonType::Null;
  85. size_t objListDeep = 0;
  86. size_t arrDeep = 0;
  87. std::wstring key = L"";
  88. std::wstring value = L"";
  89. std::stack<std::wstring> arrKey;
  90. std::stack<JsonType> cer;
  91. std::vector<std::pair<bool,JsonItem<std::vector<JsonValue>>*>> arrValueList; //false直接放到对象中 true 放到objList中
  92. std::vector<std::pair<bool,JsonItem<JsonSerialize>*>> objList; //false直接放到对象中 true 放到arrValueList中
  93. void freeAll() {
  94. for (std::pair<bool, JsonItem<std::vector<JsonValue>>*> item : arrValueList)
  95. if (item.second) delete item.second;
  96. for (std::pair<bool, JsonItem<JsonSerialize>*> item : objList)
  97. if (item.second) delete item.second;
  98. }
  99. std::string stows(std::wstring& ws)
  100. {
  101. std::string curLocale = setlocale(LC_ALL, NULL); // curLocale = "C";
  102. setlocale(LC_ALL, "chs");
  103. const wchar_t* _Source = ws.c_str();
  104. size_t _Dsize = 2 * ws.size() + 1;
  105. char* _Dest = new char[_Dsize];
  106. memset(_Dest, 0, _Dsize);
  107. wcstombs(_Dest, _Source, _Dsize);
  108. std::string result = _Dest;
  109. delete[]_Dest;
  110. setlocale(LC_ALL, curLocale.c_str());
  111. return result;
  112. }
  113. bool isBool(const std::wstring& str) {
  114. return str == L"true";
  115. }
  116. bool isNumber(const std::wstring& str) {
  117. std::wstring wstr = str;
  118. std::stringstream ss(stows(wstr));
  119. double d;
  120. char c;
  121. if (!(ss >> d)) return false;
  122. if (ss >> c) return false;
  123. return true;
  124. }
  125. bool Analysis(const char* buffer, std::vector<std::pair<JsonKey, JsonValue>>& content, const size_t length) {
  126. size_t charLength = strlen(buffer) < length ? strlen(buffer) : length;
  127. for (size_t i = 0; i < charLength; i++) {
  128. char ch = buffer[i];
  129. std::cout << ch;
  130. if (ch == '{' && !isQuote) {
  131. objListDeep++;
  132. curType = JsonType::Object;
  133. if (objListDeep >= 2) {
  134. bool flag = (cer.empty() || cer.top() == JsonType::Object) ? false : true;
  135. objList.push_back(std::pair<bool, JsonItem<JsonSerialize>*>(flag, new JsonItem<JsonSerialize>()));
  136. isObj = true;
  137. isObjEnd = false;
  138. if (!isArrEnd) cer.push(JsonType::Array);
  139. cer.push(JsonType::Object);
  140. if (isKey) arrKey.push(L"");
  141. }
  142. }
  143. else if (ch == '}' && !isQuote) {
  144. if (objListDeep == 1 && isFirst == true) isFirst = false;
  145. else if (objListDeep == 1 && isFirst == false) return false;
  146. objListDeep--;
  147. isObjEnd = true;
  148. if (objListDeep != 0)
  149. goto addArray;
  150. }
  151. else if (ch == '[' && !isQuote) {
  152. bool flag = (cer.empty() || cer.top() == JsonType::Object) ? false : true;
  153. curType = JsonType::Array;
  154. arrDeep++;
  155. arrValueList.push_back(std::pair<bool, JsonItem<std::vector<JsonValue>>*>(flag,new JsonItem<std::vector<JsonValue>>()));
  156. isArrEnd = false;
  157. if (!isObjEnd) cer.push(JsonType::Object);
  158. cer.push(JsonType::Array);
  159. }
  160. else if (ch == ']' && !isQuote) {
  161. arrDeep--;
  162. if (arrDeep == 0) isArrEnd = true;
  163. goto addArray;
  164. }
  165. else if (ch == ' ' && !isQuote) continue;
  166. else if (ch == '"' && !isQuote) {
  167. isQuote = true;
  168. if (isKey) key += L""";
  169. else value += L""";
  170. }
  171. else if (ch == '"' && isQuote) {
  172. isQuote = false;
  173. if (isKey) key += L""";
  174. else value += L""";
  175. }
  176. else if (ch == ':' && !isQuote) isKey = false;
  177. else if ((ch == ',' || ch == '
  178. ') && !isQuote) {
  179. if ((key == L"" && value == L"" && objList.size() == 0 && arrValueList.size() == 0)
  180. || (key == L"" && value == L"" && !isArrEnd)) continue;
  181. addArray: std::wstring inputKey = key == L"" ? L"" : key.replace(0, 1, L"");
  182. inputKey = inputKey == L"" ? L"" : inputKey.replace(inputKey.find_last_of(L"""), 1, L"");
  183. JsonKey j_key;
  184. JsonValue j_value;
  185. JsonType insertType = JsonType::Null;
  186. j_key._key = inputKey;
  187. if (value == L"true" || value == L"false") { //Bool
  188. JsonItem<bool> *objList=new JsonItem<bool>(isBool(value));
  189. size_t size = sizeof(objList);
  190. j_value._value = objList;
  191. j_value._size = 1;
  192. j_key._type = JsonType::Bool;
  193. }
  194. else if (value.find(L""") == 0 && value.find_last_of(L""") == value.size() - 1) { //String
  195. size_t n = value.size();
  196. std::wstring* temp = new std::wstring(value.begin(), value.end());
  197. JsonItem<std::wstring*> *objList=new JsonItem<std::wstring*>(temp);
  198. j_value._value = objList;
  199. j_value._size = n;
  200. j_key._type = JsonType::String;
  201. }
  202. else if (isNumber(value)) { //Number
  203. double result = 0;
  204. std::stringstream ss(stows(value));
  205. ss >> result;
  206. JsonItem<double> *objList=new JsonItem<double>(result);
  207. size_t size = sizeof(objList);
  208. j_value._value = objList;
  209. //memcpy_s(j_value._value, size, &objList, size);
  210. j_value._size = 1;
  211. j_key._type = JsonType::Number;
  212. }
  213. else if (arrValueList.size() != 0 && objList.size() != 0) {//Array Add or Object Add
  214. if (!isObjEnd) {
  215. arrKey.push(inputKey);
  216. key = L"";
  217. isKey = true;
  218. continue;
  219. }
  220. cer.pop();
  221. void* _val = curType == JsonType::Object ? (void*)objList.back().second : (void*)arrValueList.back().second;
  222. size_t _si = curType == JsonType::Object ?
  223. objList.back().second->GetItemRefValue().GetContent().size() :
  224. arrValueList.back().second->GetItemLpValue()->size();
  225. j_key._key = arrKey.top();
  226. j_value._value = _val;
  227. j_value._size = _si;
  228. j_key._type = JsonType::Object;
  229. if (curType == JsonType::Object) objList.pop_back();
  230. else arrValueList.pop_back();
  231. //接下来确认是放到obj 还是 arrvalue 通过cer栈顶元素判断
  232. JsonType upType = cer.top();
  233. arrKey.pop();
  234. if (upType == JsonType::Object)
  235. objList.back().second->GetItemLpValue()->GetContent().push_back(std::pair<JsonKey, JsonValue>(j_key, j_value));
  236. else
  237. arrValueList.back().second->GetItemLpValue()->push_back(j_value);
  238. continue;
  239. }
  240. else if (objList.size() != 0) {//Object
  241. if (!isObjEnd && isKey) {
  242. arrKey.push(inputKey);
  243. key = L"";
  244. continue;
  245. }
  246. cer.pop();
  247. j_key._key = arrKey.top();
  248. arrKey.pop();
  249. j_value._value = objList.back().second;
  250. j_value._size = objList.back().second->GetItemRefValue().GetContent().size();
  251. j_key._type = JsonType::Object;
  252. objList.pop_back();
  253. if (objList.size() != 0) {
  254. objList.back().second->GetItemLpValue()->GetContent().push_back(std::pair<JsonKey, JsonValue>(j_key, j_value));
  255. continue;
  256. }
  257. }
  258. else if (arrValueList.size() != 0 && objList.size() == 0) {//Array
  259. if (!isArrEnd) {
  260. arrKey.push(inputKey);
  261. key = L"";
  262. isKey = true;
  263. continue;
  264. }
  265. cer.pop();
  266. j_key._key = arrKey.empty()?inputKey:arrKey.top();
  267. if (!arrKey.empty()) arrKey.pop();
  268. j_value._value = arrValueList.back().second;
  269. j_value._size = arrValueList.back().second->GetItemLpValue()->size();
  270. j_key._type = JsonType::Array;
  271. arrValueList.pop_back();
  272. if (arrValueList.size() != 0) {
  273. arrValueList.back().second->GetItemLpValue()->push_back(j_value);
  274. continue;
  275. }
  276. }
  277. else if (value == L"") { //Null
  278. JsonItem<JNull>* objList = new JsonItem<JNull>();
  279. size_t size = sizeof(objList);
  280. j_value._value = objList;
  281. j_value._size = 0;
  282. j_key._type = JsonType::Null;
  283. }
  284. std::pair<JsonKey, JsonValue> pair(j_key, j_value);
  285. if (!isObjEnd) {
  286. objList.back().second->GetItemRefValue().GetContent().push_back(pair);
  287. }
  288. else content.push_back(pair);
  289. key = L"";
  290. value = L"";
  291. isKey = true;
  292. if (objListDeep == 1 && isObj) isObj = false;
  293. }
  294. else {
  295. if (isKey && isQuote) key += std::wstring(1, ch);
  296. else if (isKey && !isQuote) return false;
  297. else if (!isKey) value += std::wstring(1, ch);
  298. }
  299. if (objListDeep < 0 || arrDeep < 0) return false;
  300. }
  301. return true;
  302. }
  303. bool JsonSerialize::Load(const string filePath) {
  304. try {
  305. if (filePath != "") {
  306. this->_filePath = filePath;
  307. }
  308. OpenFile(this->_filePath);
  309. while (!_file.eof()) {
  310. char buffer[0x4000] = "";
  311. size_t length = sizeof(buffer) / sizeof(char);
  312. _file.read(buffer, length);
  313. if (!Analysis(buffer, content, length)) {
  314. CloseFile();
  315. return false;
  316. }
  317. }
  318. CloseFile();
  319. freeAll();
  320. return objListDeep == 0 && arrDeep == 0;
  321. }
  322. catch (std::exception ex) {
  323. throw ex;
  324. }
  325. }
  326. std::vector<std::pair<JsonKey, JsonValue>>& JsonSerialize::GetContent() {
  327. return this->content;
  328. }
  329. template<typename T>
  330. JsonItem<T>* JsonSerialize::GetValueByKey(string key)
  331. {
  332. JsonItem<T>* temp_value = nullptr;
  333. for (auto item : this->content) {
  334. if (item.first._key == key) {
  335. temp_value = (JsonItem<T>*)(item.second._value);
  336. break;
  337. }
  338. }
  339. return temp_value;
  340. }
  341. void coutTab(int count) {
  342. while (count--) {
  343. std::cout << ' ';
  344. }
  345. }
  346. void JsonSerialize::printAll(int tab) {
  347. auto res = this->content;
  348. coutTab(tab);
  349. std::cout << "{" << std::endl;
  350. for (auto it = res.begin(); it != res.end(); it++) {
  351. JsonKey temp_key = it->first;
  352. if (temp_key._type == JsonType::Number) {
  353. JsonItem<double>* temp_value = (JsonItem<double>*)(it->second._value);
  354. coutTab(tab + 1);
  355. std::wcout << temp_key._key << " : " << temp_value->GetItemRefValue() << std::endl;
  356. }
  357. else if (temp_key._type == JsonType::String) {
  358. JsonItem<std::wstring*>* temp_value = (JsonItem<std::wstring*>*)(it->second._value);
  359. coutTab(tab + 1);
  360. std::wcout << temp_key._key << " : " << *temp_value->GetItemRefValue() << "" << std::endl;
  361. }
  362. else if (temp_key._type == JsonType::Null) {
  363. JsonItem<JNull>* temp_value = (JsonItem<JNull>*)(it->second._value);
  364. coutTab(tab + 1);
  365. std::wcout << temp_key._key << " : " << "NULL" << std::endl;
  366. }
  367. else if (temp_key._type == JsonType::Bool) {
  368. JsonItem<bool>* temp_value = (JsonItem<bool>*)(it->second._value);
  369. coutTab(tab + 1);
  370. std::wcout << temp_key._key << " : " << (temp_value->GetItemRefValue() ? "true" : "false") << std::endl;
  371. }
  372. else if (temp_key._type == JsonType::Object) {
  373. JsonItem<JsonSerialize>* temp_value = (JsonItem<JsonSerialize>*)(it->second._value);
  374. temp_value->GetItemRefValue().printAll(tab + 1);
  375. }
  376. else if (temp_key._type == JsonType::Array) {
  377. JsonItem<std::vector<JsonValue>>* temp_value =
  378. (JsonItem<std::vector<JsonValue>>*)(it->second._value);
  379. coutTab(tab + 1);
  380. std::wcout << temp_key._key << ":[" << std::endl;
  381. for (auto item : temp_value->GetItemRefValue()) {

以上就是基于C++怎么编写一个Json解析器的详细内容,更多关于基于C++怎么编写一个Json解析器的资料请关注九品源码其它相关文章!