Guest User

Untitled

a guest
Sep 15th, 2018
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.75 KB | None | 0 0
  1. #pragma once
  2. #include <cstdio>
  3. #include <vector>
  4. #include <memory>
  5. #include <string>
  6. #include <deque>
  7. #include <unordered_map>
  8. #include <set>
  9.  
  10. namespace valve_parser
  11. {
  12. class Document;
  13. class KeyValue;
  14. class Object;
  15.  
  16. enum ENCODING
  17. {
  18. UTF8,
  19. UTF16_LE,
  20. UTF16_BE,
  21. UTF32_LE,
  22. UTF32_BE,
  23. MAX
  24. };
  25.  
  26. enum
  27. {
  28. STRING = '"',
  29. OBJECT_OPEN = '{',
  30. OBJECT_CLOSE = '}',
  31. COMMENT = '/',
  32. };
  33.  
  34.  
  35. class Str
  36. {
  37. public:
  38. char32_t* _start = 0;
  39. char32_t* _end = 0;
  40. public:
  41. std::string toString()
  42. {
  43. if (!_start || !_end)
  44. return "";
  45.  
  46. //convert utf32 to utf16
  47. std::vector<char16_t> utf16;
  48. utf16.reserve(200);
  49.  
  50. for (char32_t* text = _start; text != _end + 1; text++)
  51. {
  52. if ((*text >= 0 && *text <= 0xD7FF) ||
  53. *text >= 0xE000 && *text <= 0xFFFF)
  54. {
  55. utf16.push_back(*text);
  56. }
  57. if (*text >= 0x10000 && *text <= 0x10FFFF)
  58. {
  59. char32_t offset = *text - 0x10000;
  60. char16_t hi = (offset & 0xFFC00) >> 10;
  61. char16_t lo = offset & 0x3FF;
  62. hi += 0xD800;
  63. lo += 0xDC00;
  64. utf16.push_back(hi);
  65. utf16.push_back(lo);
  66. }
  67. }
  68. return std::string(utf16.begin(), utf16.end());
  69. }
  70.  
  71. //warning: no exception handling
  72. int toInt()
  73. {
  74. return std::stoi(toString());
  75. }
  76.  
  77. //checks whether the next read character equals expectedTag, if not 0 is returned
  78. static char32_t* ParseTextExpectedTag(char32_t* p, char32_t expectedTag, bool IGNORE_SPACE_TAB_LF_CR)
  79. {
  80. for (; *p; p++)
  81. {
  82. //skip comment line
  83. if (*p == COMMENT && *(p + 1) && *(p + 1) == COMMENT)
  84. {
  85. for (; *p && *p != '\n'; p++);
  86. }
  87.  
  88. //skip options line
  89. // [§xbox|§360]
  90. if (*p == '[')
  91. {
  92. for (; *p && *p != ']'; p++);
  93. p++;
  94. }
  95.  
  96. if (IGNORE_SPACE_TAB_LF_CR)
  97. {
  98. if (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')
  99. continue;
  100. }
  101.  
  102. if (*p == expectedTag)
  103. return p;
  104. else
  105. return 0;
  106. }
  107.  
  108. return 0;
  109. }
  110.  
  111. static char32_t* EndReached(char32_t* p, char32_t expectedTag)
  112. {
  113. for (; *p; p++)
  114. {
  115. //skip comment line
  116. if (*p == COMMENT && *(p + 1) && *(p + 1) == COMMENT)
  117. {
  118. for (; *p && *p != '\n'; p++);
  119. }
  120.  
  121. //skip options line
  122. // [§xbox|§360]
  123. if (*p == '[')
  124. {
  125. for (; *p && *p != ']'; p++);
  126. p++;
  127. }
  128.  
  129. if (*p == '\n' || *p == '\r' || *p == '\t' || *p == ' ')
  130. continue;
  131.  
  132. if (*p == expectedTag)
  133. return p;
  134. else
  135. return (char32_t*)-1;
  136. }
  137.  
  138. return 0;
  139. }
  140.  
  141. //reads string until it ecnounters endTag
  142. static char32_t* ParseTextEndTag(char32_t* p, char32_t endTag)
  143. {
  144. for (; *p; p++)
  145. {
  146. //skip escape sequence
  147. //there are also hex escapes
  148. //\xAA45, no need to handle them tho
  149. if (*p == '\\')
  150. p += 2;
  151.  
  152. if (*p == endTag)
  153. return p;
  154. }
  155.  
  156. return 0;
  157. }
  158. };
  159.  
  160. class Util
  161. {
  162. public:
  163. static bool StrEqu(Str str1, char* str2)
  164. {
  165. return str1.toString() == std::string(str2);
  166. }
  167.  
  168. static bool StrEquI(Str str1, char* str2)
  169. {
  170. std::string str = str1.toString();
  171. return str.compare(str2) == std::string::npos;
  172. }
  173. };
  174.  
  175. class Node
  176. {
  177. protected:
  178. Document* _doc;
  179. public:
  180. std::vector<std::shared_ptr<Node>> children;
  181. virtual bool Parse();
  182.  
  183. Node(Document* doc)
  184. {
  185. _doc = doc;
  186. }
  187.  
  188. virtual Object* ToObject()
  189. {
  190. return 0;
  191. }
  192.  
  193. virtual KeyValue* ToKeyValue()
  194. {
  195. return 0;
  196. }
  197. };
  198.  
  199. class KeyValue : public Node
  200. {
  201. public:
  202. Str Key;
  203. Str Value;
  204.  
  205. KeyValue(Document* doc) : Node(doc) {}
  206.  
  207. KeyValue* ToKeyValue()
  208. {
  209. return this;
  210. }
  211. };
  212.  
  213. class Object : public Node
  214. {
  215. public:
  216. Str name;
  217. Object(Document* doc);
  218. Object* ToObject();
  219. bool Parse();
  220. std::shared_ptr<Node> GetKeyByName(char* name);
  221. };
  222.  
  223. class Document
  224. {
  225. private:
  226. friend class Object;
  227. friend class Node;
  228.  
  229. struct BOM
  230. {
  231. char* str;
  232. size_t len;
  233. };
  234. BOM BOMS[ENCODING::MAX];
  235.  
  236. char32_t* utf32text = 0;
  237. char32_t* p;
  238. public:
  239. std::shared_ptr<Node> root;
  240.  
  241. Document()
  242. {
  243. BOMS[UTF8] = { "\xEF\xBB\xBF", 3 };
  244. BOMS[UTF16_LE] = { "\xFF\xFE", 2 };
  245. BOMS[UTF16_BE] = { "\xFE\xFF", 2 };
  246. BOMS[UTF32_LE] = { "\xFF\xFE\x00\x00", 4 };
  247. BOMS[UTF32_BE] = { "\x00\x00\xFE\xFF", 4 };
  248. }
  249.  
  250. ~Document()
  251. {
  252. if (utf32text)
  253. delete[] utf32text;
  254. }
  255.  
  256. std::shared_ptr<Node> BreadthFirstSearch(char* name, bool caseInsensitive = false)
  257. {
  258. std::deque<std::shared_ptr<Node>> q;
  259. q.push_back(root);
  260. while (!q.empty())
  261. {
  262. std::shared_ptr<Node> f = q.front();
  263. q.pop_front();
  264.  
  265. if (f->ToKeyValue())
  266. {
  267. if (!caseInsensitive && Util::StrEqu(f->ToKeyValue()->Key, name))
  268. return f;
  269.  
  270. if (caseInsensitive && Util::StrEquI(f->ToKeyValue()->Key, name))
  271. return f;
  272. }
  273. if (f->ToObject())
  274. {
  275. if (!caseInsensitive && Util::StrEqu(f->ToObject()->name, name))
  276. return f;
  277.  
  278. if (caseInsensitive && Util::StrEquI(f->ToObject()->name, name))
  279. return f;
  280. }
  281.  
  282. for (auto& child : f->children)
  283. q.push_back(child);
  284. }
  285.  
  286. return 0;
  287. }
  288.  
  289. std::vector<std::shared_ptr<Node>> BreadthFirstSearchMultiple(char* name, bool caseInsensitive = false)
  290. {
  291. std::vector<std::shared_ptr<Node>> vec;
  292. std::deque<std::shared_ptr<Node>> q;
  293. q.push_back(root);
  294. while (!q.empty())
  295. {
  296. std::shared_ptr<Node> f = q.front();
  297. q.pop_front();
  298.  
  299. if (f->ToKeyValue())
  300. {
  301. if (!caseInsensitive && Util::StrEqu(f->ToKeyValue()->Key, name))
  302. vec.push_back(f);
  303.  
  304. if (caseInsensitive && Util::StrEquI(f->ToKeyValue()->Key, name))
  305. vec.push_back(f);
  306. }
  307. if (f->ToObject())
  308. {
  309. if (!caseInsensitive && Util::StrEqu(f->ToObject()->name, name))
  310. vec.push_back(f);
  311.  
  312. if (caseInsensitive && Util::StrEquI(f->ToObject()->name, name))
  313. vec.push_back(f);
  314. }
  315.  
  316. for (auto& child : f->children)
  317. q.push_back(child);
  318. }
  319.  
  320. return vec;
  321. }
  322.  
  323. //returns true when format is correct
  324. //parse from file
  325. bool Load(char* path, ENCODING encoding)
  326. {
  327. auto f = fopen(path, "rb");
  328. if (!f)
  329. return false;
  330.  
  331. fseek(f, 0, SEEK_END);
  332. auto size = ftell(f);
  333. if (!size)
  334. return false;
  335.  
  336. size_t null_terminator_bytes = 0;
  337. if (encoding == ENCODING::UTF16_BE ||
  338. encoding == ENCODING::UTF16_LE)
  339. null_terminator_bytes = 2;
  340.  
  341. if (encoding == ENCODING::UTF8)
  342. null_terminator_bytes = 1;
  343.  
  344. if (encoding == ENCODING::UTF32_BE ||
  345. encoding == ENCODING::UTF32_LE)
  346. null_terminator_bytes = 4;
  347.  
  348. char* _text = new char[size + null_terminator_bytes];
  349. fseek(f, 0, SEEK_SET);
  350. if (fread(_text, 1, size, f) != size)
  351. return false;
  352.  
  353. for (size_t i = 0; i < null_terminator_bytes; i++)
  354. _text[size + i] = 0;
  355.  
  356. fclose(f);
  357.  
  358. //convert to utf32
  359. //which makes everything easy to handle
  360. //but increases buffer size
  361. cnv_to_utf32(_text, encoding);
  362. delete[] _text;
  363.  
  364. p = trimSpace(utf32text);
  365. if (!p)
  366. return false;
  367.  
  368. return ParseDeep();
  369. }
  370. private:
  371. char* skipBOM(char* p, ENCODING encoding)
  372. {
  373. if (!memcmp(p, BOMS[encoding].str, BOMS[encoding].len))
  374. return p + BOMS[encoding].len;
  375. else
  376. return p;
  377. }
  378.  
  379. void cnv_to_utf32(char* text, ENCODING encoding)
  380. {
  381. if (encoding == ENCODING::UTF16_LE)
  382. {
  383. char* bom = skipBOM(text, ENCODING::UTF16_LE);
  384. cnv_utf16_le(bom);
  385. }
  386.  
  387. if (encoding == ENCODING::UTF16_BE)
  388. {
  389. char* bom = skipBOM(text, ENCODING::UTF16_BE);
  390. cnv_utf16_be(bom);
  391. }
  392.  
  393. if (encoding == ENCODING::UTF8)
  394. {
  395. char* bom = skipBOM(text, ENCODING::UTF8);
  396. cnv_utf8(bom);
  397. }
  398.  
  399. if (encoding == ENCODING::UTF32_LE)
  400. {
  401. char* bom = skipBOM(text, ENCODING::UTF32_LE);
  402. cnv_utf32_le(bom);
  403. }
  404.  
  405. if (encoding == ENCODING::UTF32_BE)
  406. {
  407. char* bom = skipBOM(text, ENCODING::UTF32_BE);
  408. cnv_utf32_be(bom);
  409. }
  410. }
  411.  
  412. size_t cnv_utf16_be_len(char* text)
  413. {
  414. size_t len = 0;
  415. char16_t* u16text = (char16_t*)text;
  416. while (*u16text)
  417. {
  418.  
  419. char16_t c = 0;
  420. char* t = (char*)u16text;
  421. c |= (char16_t)*(t + 1) << 8;
  422. c |= *t;
  423.  
  424. //4 bytes
  425. if (c >= 0xD800 && c <= 0xDFFF)
  426. u16text++;
  427.  
  428. len++;
  429. u16text++;
  430. }
  431.  
  432. return len;
  433. }
  434.  
  435. size_t cnv_utf16_le_len(char* text)
  436. {
  437. size_t len = 0;
  438. char16_t* u16text = (char16_t*)text;
  439. while (*u16text)
  440. {
  441. if (*u16text >= 0xD800 && *u16text <= 0xDFFF)
  442. u16text++;
  443.  
  444. len++;
  445. u16text++;
  446. }
  447.  
  448. return len;
  449. }
  450.  
  451. void cnv_utf16_be(char* text)
  452. {
  453. auto s = cnv_utf16_be_len(text);
  454. utf32text = new char32_t[s + 1];
  455. utf32text[s] = 0;
  456. int i = 0;
  457.  
  458. char16_t* u16text = (char16_t*)text;
  459. char32_t k;
  460.  
  461. while (*u16text)
  462. {
  463.  
  464. char16_t c = 0;
  465. char* t = (char*)u16text;
  466. c |= (char16_t)*(t + 1) << 8;
  467. c |= *t;
  468.  
  469. //4 bytes
  470. if (c >= 0xD800 && c <= 0xDFFF)
  471. {
  472. char16_t hi = c - 0xD800;
  473.  
  474. t = (char*)(u16text + 1);
  475. c |= (char16_t)*(t + 1) << 8;
  476. c |= *t;
  477. char16_t lo = c - 0xDC00;
  478.  
  479. k = (char32_t)(hi & 0x3FF) << 10;
  480. k |= lo & 0x3FF;
  481. k += 0x10000;
  482. u16text++;
  483. }
  484. else //2 bytes
  485. {
  486. k = c;
  487. }
  488. utf32text[i] = k;
  489. i++;
  490. u16text++;
  491. }
  492. }
  493.  
  494. void cnv_utf16_le(char* text)
  495. {
  496. auto s = cnv_utf16_le_len(text);
  497. utf32text = new char32_t[s + 1];
  498. utf32text[s] = 0;
  499. int i = 0;
  500.  
  501. char16_t* u16text = (char16_t*)text;
  502. char32_t k;
  503.  
  504. while (*u16text)
  505. {
  506. //4 bytes
  507. if (*u16text >= 0xD800 && *u16text <= 0xDFFF)
  508. {
  509. char16_t hi = *u16text - 0xD800;
  510. char16_t lo = *(u16text + 1) - 0xDC00;
  511. k = (char32_t)(hi & 0x3FF) << 10;
  512. k |= lo & 0x3FF;
  513. k += 0x10000;
  514. u16text++;
  515. }
  516. else //2 bytes
  517. {
  518. k = *u16text;
  519. }
  520. utf32text[i] = k;
  521. i++;
  522. u16text++;
  523. }
  524. }
  525.  
  526. size_t cnv_utf8_len(char* text)
  527. {
  528. size_t len = 0;
  529. unsigned char c = (unsigned char)*text;
  530.  
  531. while (c)
  532. {
  533. if (c >= 0xc0 && c <= 0xdf)
  534. {
  535. text++;
  536. }
  537. if (c >= 0xe0 && c <= 0xef)
  538. {
  539. text += 2;
  540. }
  541. if (c >= 0xf0 && c <= 0xf7)
  542. {
  543. text += 3;
  544. }
  545.  
  546. len++;
  547. c = *++text;
  548. }
  549.  
  550. return len;
  551. }
  552.  
  553. void cnv_utf8(char* text)
  554. {
  555. auto s = cnv_utf8_len(text);
  556. utf32text = new char32_t[s + 1];
  557. utf32text[s] = 0;
  558. int i = 0;
  559.  
  560. unsigned char c = (unsigned char)*text;
  561.  
  562. while (c)
  563. {
  564. char32_t k = 0;
  565. if (c >= 0 && c <= 0x7f)
  566. {
  567. k = c;
  568. }
  569. if (c >= 0xc0 && c <= 0xdf)
  570. {
  571. k = (char32_t)(c ^ 0xc0) << 6;
  572. c = *++text;
  573. k |= c ^ 0x80;
  574. }
  575. if (c >= 0xe0 && c <= 0xef)
  576. {
  577. k = (char32_t)(c ^ 0xe0) << 12;
  578. c = *++text;
  579. k |= (char32_t)(c ^ 0x80) << 6;
  580. c = *++text;
  581. k |= c ^ 0x80;
  582. }
  583. if (c >= 0xf0 && c <= 0xf7)
  584. {
  585. k = (char32_t)(c ^ 0xf0) << 18;
  586. c = *++text;
  587. k |= (char32_t)(c ^ 0x80) << 12;
  588. c = *++text;
  589. k |= (char32_t)(c ^ 0x80) << 6;
  590. c = *++text;
  591. k |= c ^ 0x80;
  592. }
  593. utf32text[i] = k;
  594. i++;
  595. c = *++text;
  596. }
  597. }
  598.  
  599. size_t cnv_utf32_len(char* text)
  600. {
  601. size_t len = 0;
  602. char32_t* p = (char32_t*)text;
  603.  
  604. while (*p)
  605. {
  606. len++;
  607. p++;
  608. }
  609.  
  610. return len;
  611. }
  612.  
  613. void cnv_utf32_le(char* text)
  614. {
  615. auto s = cnv_utf32_len(text);
  616. utf32text = new char32_t[s + 1];
  617. utf32text[s] = 0;
  618. int i = 0;
  619.  
  620. char32_t* p = (char32_t*)text;
  621.  
  622. while (*p)
  623. {
  624. utf32text[i] = *p;
  625. i++;
  626. p++;
  627. }
  628. }
  629.  
  630. void cnv_utf32_be(char* text)
  631. {
  632. auto s = cnv_utf32_len(text);
  633. utf32text = new char32_t[s + 1];
  634. utf32text[s] = 0;
  635. int i = 0;
  636.  
  637. char32_t* p = (char32_t*)text;
  638. char32_t k;
  639.  
  640. while (*p)
  641. {
  642. char* t = (char*)p;
  643. k = (char32_t)*(t + 3) << 24;
  644. k |= (char32_t)*(t + 2) << 16;
  645. k |= (char32_t)*(t + 1) << 8;
  646. k |= *t;
  647.  
  648. utf32text[i] = k;
  649. i++;
  650. p++;
  651. }
  652. }
  653.  
  654. char32_t* trimSpace(char32_t* p)
  655. {
  656. while (*p)
  657. {
  658. if (*p == ' ')
  659. p++;
  660. else
  661. return p;
  662. }
  663.  
  664. return 0;
  665. }
  666.  
  667. bool identify(std::shared_ptr<Node>& node)
  668. {
  669. auto string_begin = Str::ParseTextExpectedTag(p, STRING, true);
  670. if (!string_begin)
  671. return false;
  672.  
  673. auto string_end = Str::ParseTextEndTag(string_begin + 1, STRING);
  674. if (!string_end)
  675. return false;
  676.  
  677.  
  678. auto object_open = Str::ParseTextExpectedTag(string_end + 1, OBJECT_OPEN, true);
  679. auto val_start = Str::ParseTextExpectedTag(string_end + 1, STRING, true);
  680.  
  681. if (!object_open && !val_start)
  682. return false;
  683.  
  684. if (object_open)
  685. {
  686. std::shared_ptr<Object> obj = std::make_shared<Object>(this);
  687. obj->name._start = string_begin + 1;
  688. obj->name._end = string_end - 1;
  689. node = obj;
  690. p = object_open + 1;
  691. return true;
  692. }
  693.  
  694. if (val_start)
  695. {
  696. auto val_end = Str::ParseTextEndTag(val_start + 1, STRING);
  697. if (!val_end)
  698. return false;
  699.  
  700. std::shared_ptr<KeyValue> keyVal = std::make_shared<KeyValue>(this);
  701. keyVal->Key._start = string_begin + 1;
  702. keyVal->Key._end = string_end - 1;
  703. keyVal->Value._start = val_start + 1;
  704. keyVal->Value._end = val_end - 1;
  705. node = keyVal;
  706. p = val_end + 1;
  707. return true;
  708. }
  709. }
  710.  
  711. bool ParseDeep()
  712. {
  713. root = std::make_shared<Node>(this);
  714. return root->Parse();
  715. }
  716. };
  717. }
  718. struct skinInfo
  719. {
  720. int seed = -1;
  721. int paintkit;
  722. std::string tagName;
  723. };
  724. extern std::unordered_map<std::string, std::set<std::string>> weaponSkins;
  725. extern std::unordered_map<std::string, skinInfo> skinMap;
  726. extern std::unordered_map<std::string, std::string> skinNames;
  727. extern std::vector<std::string> weaponNames;
  728.  
  729. extern int ParseSkins();
  730. extern const char* GetWeaponNameById(int id);
Advertisement
Add Comment
Please, Sign In to add comment