Advertisement
Guest User

Untitled

a guest
Jan 27th, 2020
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.30 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <map>
  4. #include <fstream>
  5. #include <cstring>
  6. #include <cmath>
  7. #include <cassert>
  8.  
  9. // Add ifdef.
  10.  
  11.  
  12.  
  13. #include <type_traits>
  14.  
  15. class JSON
  16. {
  17.  
  18. public:
  19.  
  20. enum class Type : int
  21. {
  22. BOOL = 0,
  23. INT = 1,
  24. FLOAT = 2,
  25. STRING = 3,
  26. ARRAY = 4,
  27. OBJECT = 5,
  28. };
  29.  
  30. void load(std::string_view filename);
  31.  
  32. [[nodiscard]]
  33. bool save(std::string_view filename);
  34.  
  35. template<class T>
  36. void setValue(T newValue);
  37.  
  38. [[nodiscard]]
  39. Type getType() const;
  40. template<class T>
  41. [[nodiscard]]
  42. T getValue() const;
  43.  
  44. [[nodiscard]]
  45. size_t getChildCount() const;
  46. [[nodiscard]]
  47. size_t getArraySize() const;
  48.  
  49. JSON& operator[] (std::string_view nodeName);
  50. JSON& operator[] (size_t index);
  51.  
  52. private:
  53.  
  54. std::map<std::string, JSON> mapJson;
  55. std::vector<JSON> vectorJson;
  56.  
  57. static int tabsCount;
  58. std::string value;
  59. Type type = Type::OBJECT;
  60.  
  61. static void writeTabs(std::ofstream& file, size_t count);
  62. static void skipWhiteSpace(char*&file);
  63.  
  64. void writeBool(std::ofstream& file);
  65. void writeInt(std::ofstream &file);
  66. void writeFloat(std::ofstream &file);
  67. void writeString(std::ofstream &file);
  68. void writeArray(std::ofstream &file);
  69. void writeObject(std::ofstream &file);
  70.  
  71. void write(std::ofstream& file);
  72.  
  73.  
  74. [[nodiscard]]
  75. bool parseBool(char*& file);
  76. [[nodiscard]]
  77. bool parseNumber(char*&file);
  78. [[nodiscard]]
  79. bool parseString(char*& file);
  80. [[nodiscard]]
  81. bool parseArray(char*& file);
  82. [[nodiscard]]
  83. bool parseObject(char*& file);
  84.  
  85. [[nodiscard]]
  86. bool parse(char*& file);
  87. };
  88.  
  89. #define SJR_IMPLEMENTATION
  90. #ifdef SJR_IMPLEMENTATION
  91.  
  92.  
  93. // ==================== ====================
  94. // ====================PUBLIC====================
  95. // ==================== ====================
  96.  
  97.  
  98. void JSON::load(std::string_view filename)
  99. {
  100. std::ifstream file(filename.data());
  101. std::string str;
  102.  
  103. if (!file.is_open())
  104. {
  105. std::cout << "Cannot load a file by path: " << filename << '\n';
  106. return;
  107. }
  108.  
  109. file.seekg(0, std::ios::end);
  110. str.reserve(file.tellg());
  111. file.seekg(0, std::ios::beg);
  112.  
  113. str.assign((std::istreambuf_iterator<char>(file)),{});
  114.  
  115. char* fileData = str.data();
  116.  
  117. if (!parse(fileData))
  118. {
  119. std::cout << "File doesn't correspong to json format file.";
  120. }
  121.  
  122. }
  123.  
  124.  
  125. [[nodiscard]]
  126. bool JSON::save(std::string_view filename)
  127. {
  128. std::ofstream file(filename.data());
  129.  
  130. if(!file.is_open())
  131. {
  132. return false;
  133. }
  134.  
  135. write(file);
  136.  
  137. file.close();
  138. return true;
  139.  
  140. }
  141.  
  142.  
  143. template<class T>
  144. void JSON::setValue(T newValue)
  145. {
  146. if constexpr(std::is_same_v<T, bool>)
  147. {
  148. type = Type::BOOL;
  149. value = std::to_string(newValue);
  150. }
  151.  
  152. if constexpr(std::is_same_v<T, int>)
  153. {
  154. type = Type::INT;
  155. value = std::to_string(newValue);
  156. }
  157.  
  158. if constexpr(std::is_same_v<T, float>)
  159. {
  160. type = Type::FLOAT;
  161. value = std::to_string(newValue);
  162. }
  163.  
  164. if constexpr (std::is_same_v<T, std::string>)
  165. {
  166. type = Type::STRING;
  167. value = newValue;
  168. }
  169. }
  170.  
  171.  
  172. [[nodiscard]]
  173. JSON::Type JSON::getType() const
  174. {
  175. return type;
  176. }
  177.  
  178.  
  179. template<class T>
  180. [[nodiscard]]
  181. T JSON::getValue() const
  182. {
  183. if constexpr(std::is_same_v<T, bool> || std::is_same_v<T, int>)
  184. {
  185. return std::stoi(value);
  186. }
  187.  
  188. if constexpr(std::is_same_v<T, float>)
  189. {
  190. return std::stof(value);
  191. }
  192.  
  193. if constexpr(std::is_same_v<T, std::string>)
  194. {
  195. return value;
  196. }
  197. }
  198.  
  199.  
  200. [[nodiscard]]
  201. size_t JSON::getChildCount() const
  202. {
  203. return mapJson.size();
  204. }
  205.  
  206.  
  207. [[nodiscard]]
  208. size_t JSON::getArraySize() const
  209. {
  210. return vectorJson.size();
  211. }
  212.  
  213.  
  214. [[nodiscard]]
  215. JSON& JSON::operator[] (std::string_view nodeName)
  216. {
  217. auto it = mapJson.find(nodeName.data());
  218.  
  219. if (it != mapJson.end())
  220. {
  221. return it->second;
  222. }
  223. else
  224. {
  225. return mapJson[nodeName.data()];
  226. }
  227. }
  228.  
  229.  
  230. // Indexing starts with 0.
  231. //
  232. [[nodiscard]]
  233. JSON& JSON::operator[] (size_t index)
  234. {
  235. if (type != Type::ARRAY)
  236. {
  237. vectorJson.resize(index);
  238. type = Type::ARRAY;
  239. }
  240.  
  241. if (index >= vectorJson.size())
  242. {
  243. vectorJson.resize(index + 1);
  244. }
  245.  
  246. return vectorJson.at(index);
  247. }
  248.  
  249.  
  250. // ==================== ====================
  251. // ====================PRIVATE====================
  252. // ==================== ====================
  253.  
  254.  
  255. void JSON::writeTabs(std::ofstream& file, size_t count)
  256. {
  257. for (size_t i = 0u; i < count; ++i)
  258. {
  259. file << '\t';
  260. }
  261. }
  262.  
  263.  
  264. void JSON::skipWhiteSpace(char*&file)
  265. {
  266. while (isspace(*file))
  267. {
  268. ++file;
  269. }
  270. }
  271.  
  272.  
  273. void JSON::writeBool(std::ofstream& file)
  274. {
  275. file.setf(std::ios_base::boolalpha);
  276. file << static_cast<bool>(std::stoi(value));
  277. file.unsetf(std::ios::boolalpha);
  278. }
  279.  
  280.  
  281. void JSON::writeInt(std::ofstream &file)
  282. {
  283. file << std::stoi(value);
  284. }
  285.  
  286.  
  287. void JSON::writeFloat(std::ofstream &file)
  288. {
  289. file << std::stof(value);
  290. }
  291.  
  292.  
  293. void JSON::writeString(std::ofstream &file)
  294. {
  295. file << "\"" << value << "\"";
  296. }
  297.  
  298.  
  299. void JSON::writeArray(std::ofstream &file)
  300. {
  301. file << '[';
  302.  
  303. for (auto it = vectorJson.begin(); it != vectorJson.end(); ++it)
  304. {
  305. it->write(file);
  306.  
  307. if (it != (--vectorJson.end()))
  308. {
  309. file << ',' << ' ';
  310. }
  311. }
  312.  
  313. file << ']';
  314. }
  315.  
  316.  
  317. void JSON::writeObject(std::ofstream &file)
  318. {
  319. if (!value.empty())
  320. {
  321. file << "\"" << value << "\"";
  322. file << ": ";
  323. }
  324.  
  325. file << '{' << ' ';
  326.  
  327. ++tabsCount;
  328. if (tabsCount == 1)
  329. {
  330. file << '\n' << '\t';
  331. }
  332. for (auto it = mapJson.begin(); it != mapJson.end(); ++it)
  333. {
  334. {
  335. file << "\"" << it->first << "\"";
  336. file << ": ";
  337. }
  338.  
  339. it->second.write(file);
  340.  
  341. if (it != (--mapJson.end()))
  342. {
  343. file << ", ";
  344. if(it->second.type == Type::ARRAY)
  345. {
  346. file << '\n';
  347. JSON::writeTabs(file, tabsCount);
  348. continue;
  349. }
  350.  
  351. if(tabsCount == 1)
  352. {
  353. file << '\n';
  354. JSON::writeTabs(file, tabsCount);
  355. }
  356.  
  357. }
  358. }
  359. --tabsCount;
  360. if(tabsCount == 0)
  361. {
  362. file << '\n';
  363. }
  364. file << '}';
  365. }
  366.  
  367.  
  368. void JSON::write(std::ofstream& file)
  369. {
  370. switch(type)
  371. {
  372. case Type::BOOL :
  373. writeBool(file);
  374. break;
  375.  
  376. case Type::INT:
  377. writeInt(file);
  378. break;
  379.  
  380. case Type::FLOAT :
  381. writeFloat(file);
  382. break;
  383.  
  384. case Type::STRING:
  385. writeString(file);
  386. break;
  387.  
  388. case Type::ARRAY:
  389. writeArray(file);
  390. break;
  391.  
  392. case Type::OBJECT:
  393. writeObject(file);
  394. break;
  395. }
  396.  
  397.  
  398. }
  399.  
  400.  
  401. int JSON::tabsCount = 0;
  402.  
  403.  
  404. [[nodiscard]]
  405. bool JSON::parseBool(char*& file)
  406. {
  407. bool resultTrue = memcmp(file, "true", 4) == 0;
  408. bool resultFalse = memcmp(file, "false", 5) == 0;
  409.  
  410. if (resultTrue || resultFalse)
  411. {
  412. value = std::to_string(resultTrue);
  413. file += resultTrue ? 4 : 5;
  414. type = Type::BOOL;
  415. return true;
  416. }
  417.  
  418. return false;
  419. }
  420.  
  421.  
  422. [[nodiscard]]
  423. bool JSON::parseNumber(char*& file)
  424. {
  425. bool signNegative = *file == '-';
  426. bool signPositive = *file == '+';
  427.  
  428. bool sign = signNegative | signPositive;
  429.  
  430. int valueInt{0};
  431. float valueFloat{0.0f};
  432.  
  433. if (sign || isdigit(*file))
  434. {
  435. if (sign)
  436. {
  437. ++file;
  438. }
  439.  
  440. while (isdigit(*file))
  441. {
  442. valueInt *= 10;
  443. valueInt += *file - '0';
  444. ++file;
  445. }
  446.  
  447. if (*file == '.')
  448. {
  449. ++file;
  450.  
  451. type = Type::FLOAT;
  452. valueFloat = static_cast<float>(valueInt);
  453.  
  454. while(isdigit(*file))
  455. {
  456. valueFloat *= 10;
  457. valueFloat += static_cast<float>(*file - '0');
  458. valueFloat /= 10;
  459.  
  460. ++file;
  461. }
  462.  
  463. value = std::to_string(valueFloat * (signNegative ? -1. : 1.));
  464.  
  465. return true;
  466. }
  467.  
  468. if (*file == 'e' || *file == 'E')
  469. {
  470. ++file;
  471.  
  472. type = Type::FLOAT;
  473. valueFloat = static_cast<float>(valueInt);
  474. valueInt = 0;
  475.  
  476. while (isdigit(*file))
  477. {
  478. valueInt *= 10;
  479. valueInt += *file - '0';
  480. }
  481.  
  482. valueFloat *= static_cast<float>(pow(10, valueInt));
  483.  
  484. value = std::to_string(valueFloat * (signNegative ? -1. : 1.));
  485. return true;
  486. }
  487.  
  488. type = Type::INT;
  489. value = std::to_string(valueInt * (signNegative ? -1 : 1));
  490. return true;
  491. }
  492.  
  493. return false;
  494. }
  495.  
  496.  
  497. [[nodiscard]]
  498. bool JSON::parseString(char*& file)
  499. {
  500. if (*file == '"')
  501. {
  502. ++file;
  503.  
  504. type = Type::STRING;
  505.  
  506. while (*file != '"')
  507. {
  508. JSON::skipWhiteSpace(file);
  509.  
  510. if (*file == '"')
  511. {
  512. return true;
  513. }
  514.  
  515. value += *file;
  516.  
  517. ++file;
  518. }
  519.  
  520. ++file;
  521.  
  522. return true;
  523. }
  524.  
  525. return false;
  526. }
  527.  
  528.  
  529. [[nodiscard]]
  530. bool JSON::parseArray(char*& file)
  531. {
  532. if (*file == '[')
  533. {
  534. ++file;
  535.  
  536. type = Type::ARRAY;
  537.  
  538. while (*file != ']')
  539. {
  540. JSON::skipWhiteSpace(file);
  541.  
  542. if (*file == ']')
  543. {
  544. ++file;
  545.  
  546. return true;
  547. }
  548.  
  549. JSON newJSON;
  550.  
  551. if (!newJSON.parse(file))
  552. {
  553. return false;
  554. }
  555.  
  556. vectorJson.push_back(newJSON);
  557.  
  558. JSON::skipWhiteSpace(file);
  559.  
  560. if (*file == ']')
  561. {
  562. ++file;
  563. type = Type::ARRAY;
  564. return true;
  565. }
  566.  
  567. if (*file != ',')
  568. {
  569. return false;
  570. }
  571.  
  572. ++file;
  573. }
  574.  
  575. ++file;
  576. return true;
  577. }
  578.  
  579. return false;
  580. }
  581.  
  582.  
  583. [[nodiscard]]
  584. bool JSON::parseObject(char*& file)
  585. {
  586. if (*file == '{')
  587. {
  588. ++file;
  589. type = Type::OBJECT;
  590.  
  591. while (*file != '}')
  592. {
  593. JSON::skipWhiteSpace(file);
  594.  
  595. if (*file == '}')
  596. {
  597. ++file;
  598. return true;
  599. }
  600.  
  601.  
  602. if (*file == '"')
  603. {
  604. ++file;
  605. std::string nodeName{};
  606.  
  607. while (*file != '"')
  608. {
  609. JSON::skipWhiteSpace(file);
  610.  
  611. if (*file == '"')
  612. {
  613. break;
  614. }
  615.  
  616. nodeName += *file;
  617.  
  618. ++file;
  619. }
  620.  
  621. if (*file != '"')
  622. {
  623. return true;
  624. }
  625. ++file;
  626. JSON::skipWhiteSpace(file);
  627.  
  628.  
  629. if (*file != ':')
  630. {
  631. return true;
  632. }
  633.  
  634. ++file;
  635. JSON::skipWhiteSpace(file);
  636.  
  637. JSON newNode;
  638. if (!newNode.parse(file)) {
  639. return true;
  640. }
  641. type = Type::OBJECT;
  642. mapJson[nodeName] = newNode;
  643. }
  644.  
  645.  
  646. JSON::skipWhiteSpace(file);
  647.  
  648. if(*file == '}')
  649. {
  650. ++file;
  651. return true;
  652. }
  653.  
  654. if(*file != ',')
  655. {
  656. return false;
  657. }
  658.  
  659. ++file;
  660.  
  661. }
  662.  
  663. ++file;
  664. return true;
  665. }
  666.  
  667. return false;
  668. }
  669.  
  670.  
  671. //
  672. //
  673. [[nodiscard]]
  674. bool JSON::parse(char*& file)
  675. {
  676. skipWhiteSpace(file);
  677.  
  678. if (parseString(file))
  679. {
  680. return true;
  681. }
  682.  
  683. if (parseBool(file))
  684. {
  685. return true;
  686. }
  687.  
  688. if (parseNumber(file))
  689. {
  690. return true;
  691. }
  692.  
  693. if (parseArray(file))
  694. {
  695. return true;
  696. }
  697.  
  698. if (parseObject(file))
  699. {
  700. return true;
  701. }
  702.  
  703. return false;
  704. }
  705.  
  706.  
  707. #endif
  708.  
  709. int main()
  710. {
  711. JSON temp;
  712.  
  713. temp.load("Smoke.par");
  714.  
  715. std::cout << temp["Billboard"].getValue<std::string>() << '\n';
  716.  
  717. //temp["z"][0]["ar"].setValue<bool>(true);
  718.  
  719. temp.save("Wagh.txt");
  720.  
  721. return 0;
  722. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement