Advertisement
Guest User

C++ JSON Parser

a guest
Mar 22nd, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 34.41 KB | None | 0 0
  1. // Win32 incompatibilities
  2. #if defined(WIN32) && !defined(__GNUC__)
  3.         #define wcsncasecmp _wcsnicmp
  4.         static inline bool isnan(double x) { return x != x; }
  5.         static inline bool isinf(double x) { return !isnan(x) && isnan(x - x); }
  6. #endif
  7.  
  8. #include <vector>
  9. #include <string>
  10. #include <map>
  11.  
  12. // Linux compile fix - from quaker66
  13. #ifdef __GNUC__
  14.         #include <cstring>
  15.         #include <cstdlib>
  16. #endif
  17.  
  18. // Mac compile fixes - from quaker66, Lion fix by dabrahams
  19. #if defined(__APPLE__) && __DARWIN_C_LEVEL < 200809L || (defined(WIN32) && defined(__GNUC__)) || defined(ANDROID)
  20.         #include <wctype.h>
  21.         #include <wchar.h>
  22.  
  23.         static inline int wcsncasecmp(const wchar_t *s1, const wchar_t *s2, size_t n)
  24.         {
  25.                 int lc1  = 0;
  26.                 int lc2  = 0;
  27.  
  28.                 while (n--)
  29.                 {
  30.                         lc1 = towlower (*s1);
  31.                         lc2 = towlower (*s2);
  32.  
  33.                         if (lc1 != lc2)
  34.                                 return (lc1 - lc2);
  35.  
  36.                         if (!lc1)
  37.                                 return 0;
  38.  
  39.                         ++s1;
  40.                         ++s2;
  41.                 }
  42.  
  43.                 return 0;
  44.         }
  45. #endif
  46.  
  47. // Simple function to check a string 's' has at least 'n' characters
  48. static inline bool simplejson_wcsnlen(const wchar_t *s, size_t n) {
  49.         if (s == 0)
  50.                 return false;
  51.  
  52.         const wchar_t *save = s;
  53.         while (n-- > 0)
  54.         {
  55.                 if (*(save++) == 0) return false;
  56.         }
  57.  
  58.         return true;
  59. }
  60.  
  61. // Custom types
  62. class JSONValue;
  63. typedef std::vector<JSONValue*> JSONArray;
  64. typedef std::map<std::wstring, JSONValue*> JSONObject;
  65.  
  66. #include <vector>
  67. #include <string>
  68.  
  69. class JSON;
  70.  
  71. enum JSONType { JSONType_Null, JSONType_String, JSONType_Bool, JSONType_Number, JSONType_Array, JSONType_Object };
  72.  
  73. class JSONValue
  74. {
  75.         friend class JSON;
  76.  
  77.         public:
  78.                 JSONValue(/*NULL*/);
  79.                 JSONValue(const wchar_t *m_char_value);
  80.                 JSONValue(const std::wstring &m_string_value);
  81.                 JSONValue(bool m_bool_value);
  82.                 JSONValue(double m_number_value);
  83.                 JSONValue(const JSONArray &m_array_value);
  84.                 JSONValue(const JSONObject &m_object_value);
  85.                 ~JSONValue();
  86.  
  87.                 bool IsNull() const;
  88.                 bool IsString() const;
  89.                 bool IsBool() const;
  90.                 bool IsNumber() const;
  91.                 bool IsArray() const;
  92.                 bool IsObject() const;
  93.  
  94.                 const std::wstring &AsString() const;
  95.                 bool AsBool() const;
  96.                 double AsNumber() const;
  97.                 const JSONArray &AsArray() const;
  98.                 const JSONObject &AsObject() const;
  99.  
  100.                 std::size_t CountChildren() const;
  101.                 bool HasChild(std::size_t index) const;
  102.                 JSONValue *Child(std::size_t index);
  103.                 bool HasChild(const wchar_t* name) const;
  104.                 JSONValue *Child(const wchar_t* name);
  105.  
  106.                 std::wstring Stringify() const;
  107.  
  108.         protected:
  109.                 static JSONValue *Parse(const wchar_t **data);
  110.  
  111.         private:
  112.                 static std::wstring StringifyString(const std::wstring &str);
  113.  
  114.                 JSONType type;
  115.                 std::wstring string_value;
  116.                 bool bool_value;
  117.                 double number_value;
  118.                 JSONArray array_value;
  119.                 JSONObject object_value;
  120. };
  121.  
  122. class JSON
  123. {
  124.         friend class JSONValue;
  125.  
  126.         public:
  127.                 static JSONValue* Parse(const char *data);
  128.                 static JSONValue* Parse(const wchar_t *data);
  129.                 static std::wstring Stringify(const JSONValue *value);
  130.         protected:
  131.                 static bool SkipWhitespace(const wchar_t **data);
  132.                 static bool ExtractString(const wchar_t **data, std::wstring &str);
  133.                 static double ParseInt(const wchar_t **data);
  134.                 static double ParseDecimal(const wchar_t **data);
  135.         private:
  136.                 JSON();
  137. };
  138.  
  139. #include <stdio.h>
  140. #include <string.h>
  141. #include <stdlib.h>
  142. #include <vector>
  143. #include <string>
  144. #include <sstream>
  145. #include <iostream>
  146. #include <math.h>
  147.  
  148. // Macros to free an array/object
  149. #define FREE_ARRAY(x) { JSONArray::iterator iter; for (iter = x.begin(); iter != x.end(); iter++) { delete *iter; } }
  150. #define FREE_OBJECT(x) { JSONObject::iterator iter; for (iter = x.begin(); iter != x.end(); iter++) { delete (*iter).second; } }
  151.  
  152. /**
  153.  * Parses a JSON encoded value to a JSONValue object
  154.  *
  155.  * @access protected
  156.  *
  157.  * @param wchar_t** data Pointer to a wchar_t* that contains the data
  158.  *
  159.  * @return JSONValue* Returns a pointer to a JSONValue object on success, NULL on error
  160.  */
  161. JSONValue *JSONValue::Parse(const wchar_t **data)
  162. {
  163.         // Is it a string?
  164.         if (**data == '"')
  165.         {
  166.                 std::wstring str;
  167.                 if (!JSON::ExtractString(&(++(*data)), str))
  168.                         return NULL;
  169.                 else
  170.                         return new JSONValue(str);
  171.         }
  172.  
  173.         // Is it a boolean?
  174.         else if ((simplejson_wcsnlen(*data, 4) && wcsncasecmp(*data, L"true", 4) == 0) || (simplejson_wcsnlen(*data, 5) && wcsncasecmp(*data, L"false", 5) == 0))
  175.         {
  176.                 bool value = wcsncasecmp(*data, L"true", 4) == 0;
  177.                 (*data) += value ? 4 : 5;
  178.                 return new JSONValue(value);
  179.         }
  180.  
  181.         // Is it a null?
  182.         else if (simplejson_wcsnlen(*data, 4) && wcsncasecmp(*data, L"null", 4) == 0)
  183.         {
  184.                 (*data) += 4;
  185.                 return new JSONValue();
  186.         }
  187.  
  188.         // Is it a number?
  189.         else if (**data == L'-' || (**data >= L'0' && **data <= L'9'))
  190.         {
  191.                 // Negative?
  192.                 bool neg = **data == L'-';
  193.                 if (neg) (*data)++;
  194.  
  195.                 double number = 0.0;
  196.  
  197.                 // Parse the whole part of the number - only if it wasn't 0
  198.                 if (**data == L'0')
  199.                         (*data)++;
  200.                 else if (**data >= L'1' && **data <= L'9')
  201.                         number = JSON::ParseInt(data);
  202.                 else
  203.                         return NULL;
  204.  
  205.                 // Could be a decimal now...
  206.                 if (**data == '.')
  207.                 {
  208.                         (*data)++;
  209.  
  210.                         // Not get any digits?
  211.                         if (!(**data >= L'0' && **data <= L'9'))
  212.                                 return NULL;
  213.  
  214.                         // Find the decimal and sort the decimal place out
  215.                         // Use ParseDecimal as ParseInt won't work with decimals less than 0.1
  216.                         // thanks to Javier Abadia for the report & fix
  217.                         double decimal = JSON::ParseDecimal(data);
  218.  
  219.                         // Save the number
  220.                         number += decimal;
  221.                 }
  222.  
  223.                 // Could be an exponent now...
  224.                 if (**data == L'E' || **data == L'e')
  225.                 {
  226.                         (*data)++;
  227.  
  228.                         // Check signage of expo
  229.                         bool neg_expo = false;
  230.                         if (**data == L'-' || **data == L'+')
  231.                         {
  232.                                 neg_expo = **data == L'-';
  233.                                 (*data)++;
  234.                         }
  235.  
  236.                         // Not get any digits?
  237.                         if (!(**data >= L'0' && **data <= L'9'))
  238.                                 return NULL;
  239.  
  240.                         // Sort the expo out
  241.                         double expo = JSON::ParseInt(data);
  242.                         for (double i = 0.0; i < expo; i++)
  243.                                 number = neg_expo ? (number / 10.0) : (number * 10.0);
  244.                 }
  245.  
  246.                 // Was it neg?
  247.                 if (neg) number *= -1;
  248.  
  249.                 return new JSONValue(number);
  250.         }
  251.  
  252.         // An object?
  253.         else if (**data == L'{')
  254.         {
  255.                 JSONObject object;
  256.  
  257.                 (*data)++;
  258.  
  259.                 while (**data != 0)
  260.                 {
  261.                         // Whitespace at the start?
  262.                         if (!JSON::SkipWhitespace(data))
  263.                         {
  264.                                 FREE_OBJECT(object);
  265.                                 return NULL;
  266.                         }
  267.  
  268.                         // Special case - empty object
  269.                         if (object.size() == 0 && **data == L'}')
  270.                         {
  271.                                 (*data)++;
  272.                                 return new JSONValue(object);
  273.                         }
  274.  
  275.                         // We want a string now...
  276.                         std::wstring name;
  277.                         if (!JSON::ExtractString(&(++(*data)), name))
  278.                         {
  279.                                 FREE_OBJECT(object);
  280.                                 return NULL;
  281.                         }
  282.  
  283.                         // More whitespace?
  284.                         if (!JSON::SkipWhitespace(data))
  285.                         {
  286.                                 FREE_OBJECT(object);
  287.                                 return NULL;
  288.                         }
  289.  
  290.                         // Need a : now
  291.                         if (*((*data)++) != L':')
  292.                         {
  293.                                 FREE_OBJECT(object);
  294.                                 return NULL;
  295.                         }
  296.  
  297.                         // More whitespace?
  298.                         if (!JSON::SkipWhitespace(data))
  299.                         {
  300.                                 FREE_OBJECT(object);
  301.                                 return NULL;
  302.                         }
  303.  
  304.                         // The value is here                        
  305.                         JSONValue *value = Parse(data);
  306.                         if (value == NULL)
  307.                         {
  308.                                 FREE_OBJECT(object);
  309.                                 return NULL;
  310.                         }
  311.  
  312.                         // Add the name:value
  313.                         if (object.find(name) != object.end())
  314.                                 delete object[name];
  315.                         object[name] = value;
  316.  
  317.                         // More whitespace?
  318.                         if (!JSON::SkipWhitespace(data))
  319.                         {
  320.                                 FREE_OBJECT(object);
  321.                                 return NULL;
  322.                         }
  323.  
  324.                         // End of object?
  325.                         if (**data == L'}')
  326.                         {
  327.                                 (*data)++;
  328.                                 return new JSONValue(object);
  329.                         }
  330.  
  331.                         // Want a , now
  332.                         if (**data != L',')
  333.                         {
  334.                                 FREE_OBJECT(object);
  335.                                 return NULL;
  336.                         }
  337.  
  338.                         (*data)++;
  339.                 }
  340.  
  341.                 // Only here if we ran out of data
  342.                 FREE_OBJECT(object);
  343.                 return NULL;
  344.         }
  345.  
  346.         // An array?
  347.         else if (**data == L'[')
  348.         {
  349.                 JSONArray array;
  350.  
  351.                 (*data)++;
  352.  
  353.                 while (**data != 0)
  354.                 {
  355.                         // Whitespace at the start?
  356.                         if (!JSON::SkipWhitespace(data))
  357.                         {
  358.                                 FREE_ARRAY(array);
  359.                                 return NULL;
  360.                         }
  361.  
  362.                         // Special case - empty array
  363.                         if (array.size() == 0 && **data == L']')
  364.                         {
  365.                                 (*data)++;
  366.                                 return new JSONValue(array);
  367.                         }
  368.  
  369.                         // Get the value
  370.                         JSONValue *value = Parse(data);
  371.                         if (value == NULL)
  372.                         {
  373.                                 FREE_ARRAY(array);
  374.                                 return NULL;
  375.                         }
  376.  
  377.                         // Add the value
  378.                         array.push_back(value);
  379.  
  380.                         // More whitespace?
  381.                         if (!JSON::SkipWhitespace(data))
  382.                         {
  383.                                 FREE_ARRAY(array);
  384.                                 return NULL;
  385.                         }
  386.  
  387.                         // End of array?
  388.                         if (**data == L']')
  389.                         {
  390.                                 (*data)++;
  391.                                 return new JSONValue(array);
  392.                         }
  393.  
  394.                         // Want a , now
  395.                         if (**data != L',')
  396.                         {
  397.                                 FREE_ARRAY(array);
  398.                                 return NULL;
  399.                         }
  400.  
  401.                         (*data)++;
  402.                 }
  403.  
  404.                 // Only here if we ran out of data
  405.                 FREE_ARRAY(array);
  406.                 return NULL;
  407.         }
  408.  
  409.         // Ran out of possibilites, it's bad!
  410.         else
  411.         {
  412.                 return NULL;
  413.         }
  414. }
  415.  
  416. /**
  417.  * Basic constructor for creating a JSON Value of type NULL
  418.  *
  419.  * @access public
  420.  */
  421. JSONValue::JSONValue(/*NULL*/)
  422. {
  423.         type = JSONType_Null;
  424. }
  425.  
  426. /**
  427.  * Basic constructor for creating a JSON Value of type String
  428.  *
  429.  * @access public
  430.  *
  431.  * @param wchar_t* m_char_value The string to use as the value
  432.  */
  433. JSONValue::JSONValue(const wchar_t *m_char_value)
  434. {
  435.         type = JSONType_String;
  436.         string_value = std::wstring(m_char_value);
  437. }
  438.  
  439. /**
  440.  * Basic constructor for creating a JSON Value of type String
  441.  *
  442.  * @access public
  443.  *
  444.  * @param std::wstring m_string_value The string to use as the value
  445.  */
  446. JSONValue::JSONValue(const std::wstring &m_string_value)
  447. {
  448.         type = JSONType_String;
  449.         string_value = m_string_value;
  450. }
  451.  
  452. /**
  453.  * Basic constructor for creating a JSON Value of type Bool
  454.  *
  455.  * @access public
  456.  *
  457.  * @param bool m_bool_value The bool to use as the value
  458.  */
  459. JSONValue::JSONValue(bool m_bool_value)
  460. {
  461.         type = JSONType_Bool;
  462.         bool_value = m_bool_value;
  463. }
  464.  
  465. /**
  466.  * Basic constructor for creating a JSON Value of type Number
  467.  *
  468.  * @access public
  469.  *
  470.  * @param double m_number_value The number to use as the value
  471.  */
  472. JSONValue::JSONValue(double m_number_value)
  473. {
  474.         type = JSONType_Number;
  475.         number_value = m_number_value;
  476. }
  477.  
  478. /**
  479.  * Basic constructor for creating a JSON Value of type Array
  480.  *
  481.  * @access public
  482.  *
  483.  * @param JSONArray m_array_value The JSONArray to use as the value
  484.  */
  485. JSONValue::JSONValue(const JSONArray &m_array_value)
  486. {
  487.         type = JSONType_Array;
  488.         array_value = m_array_value;
  489. }
  490.  
  491. /**
  492.  * Basic constructor for creating a JSON Value of type Object
  493.  *
  494.  * @access public
  495.  *
  496.  * @param JSONObject m_object_value The JSONObject to use as the value
  497.  */
  498. JSONValue::JSONValue(const JSONObject &m_object_value)
  499. {
  500.         type = JSONType_Object;
  501.         object_value = m_object_value;
  502. }
  503.  
  504. /**
  505.  * The destructor for the JSON Value object
  506.  * Handles deleting the objects in the array or the object value
  507.  *
  508.  * @access public
  509.  */
  510. JSONValue::~JSONValue()
  511. {
  512.         if (type == JSONType_Array)
  513.         {
  514.                 JSONArray::iterator iter;
  515.                 for (iter = array_value.begin(); iter != array_value.end(); iter++)
  516.                         delete *iter;
  517.         }
  518.         else if (type == JSONType_Object)
  519.         {
  520.                 JSONObject::iterator iter;
  521.                 for (iter = object_value.begin(); iter != object_value.end(); iter++)
  522.                 {
  523.                         delete (*iter).second;
  524.                 }
  525.         }
  526. }
  527.  
  528. /**
  529.  * Checks if the value is a NULL
  530.  *
  531.  * @access public
  532.  *
  533.  * @return bool Returns true if it is a NULL value, false otherwise
  534.  */
  535. bool JSONValue::IsNull() const
  536. {
  537.         return type == JSONType_Null;
  538. }
  539.  
  540. /**
  541.  * Checks if the value is a String
  542.  *
  543.  * @access public
  544.  *
  545.  * @return bool Returns true if it is a String value, false otherwise
  546.  */
  547. bool JSONValue::IsString() const
  548. {
  549.         return type == JSONType_String;
  550. }
  551.  
  552. /**
  553.  * Checks if the value is a Bool
  554.  *
  555.  * @access public
  556.  *
  557.  * @return bool Returns true if it is a Bool value, false otherwise
  558.  */
  559. bool JSONValue::IsBool() const
  560. {
  561.         return type == JSONType_Bool;
  562. }
  563.  
  564. /**
  565.  * Checks if the value is a Number
  566.  *
  567.  * @access public
  568.  *
  569.  * @return bool Returns true if it is a Number value, false otherwise
  570.  */
  571. bool JSONValue::IsNumber() const
  572. {
  573.         return type == JSONType_Number;
  574. }
  575.  
  576. /**
  577.  * Checks if the value is an Array
  578.  *
  579.  * @access public
  580.  *
  581.  * @return bool Returns true if it is an Array value, false otherwise
  582.  */
  583. bool JSONValue::IsArray() const
  584. {
  585.         return type == JSONType_Array;
  586. }
  587.  
  588. /**
  589.  * Checks if the value is an Object
  590.  *
  591.  * @access public
  592.  *
  593.  * @return bool Returns true if it is an Object value, false otherwise
  594.  */
  595. bool JSONValue::IsObject() const
  596. {
  597.         return type == JSONType_Object;
  598. }
  599.  
  600. /**
  601.  * Retrieves the String value of this JSONValue
  602.  * Use IsString() before using this method.
  603.  *
  604.  * @access public
  605.  *
  606.  * @return std::wstring Returns the string value
  607.  */
  608. const std::wstring &JSONValue::AsString() const
  609. {
  610.         return string_value;
  611. }
  612.  
  613. /**
  614.  * Retrieves the Bool value of this JSONValue
  615.  * Use IsBool() before using this method.
  616.  *
  617.  * @access public
  618.  *
  619.  * @return bool Returns the bool value
  620.  */
  621. bool JSONValue::AsBool() const
  622. {
  623.         return bool_value;
  624. }
  625.  
  626. /**
  627.  * Retrieves the Number value of this JSONValue
  628.  * Use IsNumber() before using this method.
  629.  *
  630.  * @access public
  631.  *
  632.  * @return double Returns the number value
  633.  */
  634. double JSONValue::AsNumber() const
  635. {
  636.         return number_value;
  637. }
  638.  
  639. /**
  640.  * Retrieves the Array value of this JSONValue
  641.  * Use IsArray() before using this method.
  642.  *
  643.  * @access public
  644.  *
  645.  * @return JSONArray Returns the array value
  646.  */
  647. const JSONArray &JSONValue::AsArray() const
  648. {
  649.         return array_value;
  650. }
  651.  
  652. /**
  653.  * Retrieves the Object value of this JSONValue
  654.  * Use IsObject() before using this method.
  655.  *
  656.  * @access public
  657.  *
  658.  * @return JSONObject Returns the object value
  659.  */
  660. const JSONObject &JSONValue::AsObject() const
  661. {
  662.         return object_value;
  663. }
  664.  
  665. /**
  666.  * Retrieves the number of children of this JSONValue.
  667.  * This number will be 0 or the actual number of children
  668.  * if IsArray() or IsObject().
  669.  *
  670.  * @access public
  671.  *
  672.  * @return The number of children.
  673.  */
  674. std::size_t JSONValue::CountChildren() const
  675. {
  676.         switch (type)
  677.         {
  678.                 case JSONType_Array:
  679.                         return array_value.size();
  680.                 case JSONType_Object:
  681.                         return object_value.size();
  682.                 default:
  683.                         return 0;
  684.         }
  685. }
  686.  
  687. /**
  688.  * Checks if this JSONValue has a child at the given index.
  689.  * Use IsArray() before using this method.
  690.  *
  691.  * @access public
  692.  *
  693.  * @return bool Returns true if the array has a value at the given index.
  694.  */
  695. bool JSONValue::HasChild(std::size_t index) const
  696. {
  697.         if (type == JSONType_Array)
  698.         {
  699.                 return index < array_value.size();
  700.         }
  701.         else
  702.         {
  703.                 return false;
  704.         }
  705. }
  706.  
  707. /**
  708.  * Retrieves the child of this JSONValue at the given index.
  709.  * Use IsArray() before using this method.
  710.  *
  711.  * @access public
  712.  *
  713.  * @return JSONValue* Returns JSONValue at the given index or NULL
  714.  *                    if it doesn't exist.
  715.  */
  716. JSONValue *JSONValue::Child(std::size_t index)
  717. {
  718.         if (index < array_value.size())
  719.         {
  720.                 return array_value[index];
  721.         }
  722.         else
  723.         {
  724.                 return NULL;
  725.         }
  726. }
  727.  
  728. /**
  729.  * Checks if this JSONValue has a child at the given key.
  730.  * Use IsObject() before using this method.
  731.  *
  732.  * @access public
  733.  *
  734.  * @return bool Returns true if the object has a value at the given key.
  735.  */
  736. bool JSONValue::HasChild(const wchar_t* name) const
  737. {
  738.         if (type == JSONType_Object)
  739.         {
  740.                 return object_value.find(name) != object_value.end();
  741.         }
  742.         else
  743.         {
  744.                 return false;
  745.         }
  746. }
  747.  
  748. /**
  749.  * Retrieves the child of this JSONValue at the given key.
  750.  * Use IsObject() before using this method.
  751.  *
  752.  * @access public
  753.  *
  754.  * @return JSONValue* Returns JSONValue for the given key in the object
  755.  *                    or NULL if it doesn't exist.
  756.  */
  757. JSONValue* JSONValue::Child(const wchar_t* name)
  758. {
  759.         JSONObject::const_iterator it = object_value.find(name);
  760.         if (it != object_value.end())
  761.         {
  762.                 return it->second;
  763.         }
  764.         else
  765.         {
  766.                 return NULL;
  767.         }
  768. }
  769.  
  770. /**
  771.  * Creates a JSON encoded string for the value with all necessary characters escaped
  772.  *
  773.  * @access public
  774.  *
  775.  * @return std::wstring Returns the JSON string
  776.  */
  777. std::wstring JSONValue::Stringify() const
  778. {
  779.         std::wstring ret_string;
  780.  
  781.         switch (type)
  782.         {
  783.                 case JSONType_Null:
  784.                         ret_string = L"null";
  785.                         break;
  786.  
  787.                 case JSONType_String:
  788.                         ret_string = StringifyString(string_value);
  789.                         break;
  790.  
  791.                 case JSONType_Bool:
  792.                         ret_string = bool_value ? L"true" : L"false";
  793.                         break;
  794.  
  795.                 case JSONType_Number:
  796.                 {
  797.                         if (isinf(number_value) || isnan(number_value))
  798.                                 ret_string = L"null";
  799.                         else
  800.                         {
  801.                                 std::wstringstream ss;
  802.                                 ss.precision(15);
  803.                                 ss << number_value;
  804.                                 ret_string = ss.str();
  805.                         }
  806.                         break;
  807.                 }
  808.  
  809.                 case JSONType_Array:
  810.                 {
  811.                         ret_string = L"[";
  812.                         JSONArray::const_iterator iter = array_value.begin();
  813.                         while (iter != array_value.end())
  814.                         {
  815.                                 ret_string += (*iter)->Stringify();
  816.  
  817.                                 // Not at the end - add a separator
  818.                                 if (++iter != array_value.end())
  819.                                         ret_string += L",";
  820.                         }
  821.                         ret_string += L"]";
  822.                         break;
  823.                 }
  824.  
  825.                 case JSONType_Object:
  826.                 {
  827.                         ret_string = L"{";
  828.                         JSONObject::const_iterator iter = object_value.begin();
  829.                         while (iter != object_value.end())
  830.                         {
  831.                                 ret_string += StringifyString((*iter).first);
  832.                                 ret_string += L":";
  833.                                 ret_string += (*iter).second->Stringify();
  834.  
  835.                                 // Not at the end - add a separator
  836.                                 if (++iter != object_value.end())
  837.                                         ret_string += L",";
  838.                         }
  839.                         ret_string += L"}";
  840.                         break;
  841.                 }
  842.         }
  843.  
  844.         return ret_string;
  845. }
  846.  
  847. /**
  848.  * Creates a JSON encoded string with all required fields escaped
  849.  * Works from http://w...content-available-to-author-only...l.org/publications/files/ECMA-ST/ECMA-262.pdf
  850.  * Section 15.12.3.
  851.  *
  852.  * @access private
  853.  *
  854.  * @param std::wstring str The string that needs to have the characters escaped
  855.  *
  856.  * @return std::wstring Returns the JSON string
  857.  */
  858. std::wstring JSONValue::StringifyString(const std::wstring &str)
  859. {
  860.         std::wstring str_out = L"\"";
  861.  
  862.         std::wstring::const_iterator iter = str.begin();
  863.         while (iter != str.end())
  864.         {
  865.                 wchar_t chr = *iter;
  866.  
  867.                 if (chr == L'"' || chr == L'\\' || chr == L'/')
  868.                 {
  869.                         str_out += L'\\';
  870.                         str_out += chr;
  871.                 }
  872.                 else if (chr == L'\b')
  873.                 {
  874.                         str_out += L"\\b";
  875.                 }
  876.                 else if (chr == L'\f')
  877.                 {
  878.                         str_out += L"\\f";
  879.                 }
  880.                 else if (chr == L'\n')
  881.                 {
  882.                         str_out += L"\\n";
  883.                 }
  884.                 else if (chr == L'\r')
  885.                 {
  886.                         str_out += L"\\r";
  887.                 }
  888.                 else if (chr == L'\t')
  889.                 {
  890.                         str_out += L"\\t";
  891.                 }
  892.                 else if (chr < L' ')
  893.                 {
  894.                         str_out += L"\\u";
  895.                         for (int i = 0; i < 4; i++)
  896.                         {
  897.                                 int value = (chr >> 12) & 0xf;
  898.                                 if (value >= 0 && value <= 9)
  899.                                         str_out += (wchar_t)('0' + value);
  900.                                 else if (value >= 10 && value <= 15)
  901.                                         str_out += (wchar_t)('A' + (value - 10));
  902.                                 chr <<= 4;
  903.                         }
  904.                 }
  905.                 else
  906.                 {
  907.                         str_out += chr;
  908.                 }
  909.  
  910.                 iter++;
  911.         }
  912.  
  913.         str_out += L"\"";
  914.         return str_out;
  915. }
  916.  
  917. /**
  918.  * Blocks off the public constructor
  919.  *
  920.  * @access private
  921.  *
  922.  */
  923. JSON::JSON()
  924. {
  925. }
  926.  
  927. /**
  928.  * Parses a complete JSON encoded string
  929.  * This is just a wrapper around the UNICODE Parse().
  930.  *
  931.  * @access public
  932.  *
  933.  * @param char* data The JSON text
  934.  *
  935.  * @return JSONValue* Returns a JSON Value representing the root, or NULL on error
  936.  */
  937. JSONValue *JSON::Parse(const char *data)
  938. {
  939.         size_t length = strlen(data) + 1;
  940.         wchar_t *w_data = (wchar_t*)malloc(length * sizeof(wchar_t));
  941.  
  942.         #if defined(WIN32) && !defined(__GNUC__)
  943.                 size_t ret_value = 0;
  944.                 if (mbstowcs_s(&ret_value, w_data, length, data, length) != 0)
  945.                 {
  946.                         free(w_data);
  947.                         return NULL;
  948.                 }
  949.         #elif defined(ANDROID)
  950.                 // mbstowcs seems to misbehave on android
  951.                 for(size_t i = 0; i<length; i++)
  952.                         w_data[i] = (wchar_t)data[i];
  953.         #else
  954.                 if (mbstowcs(w_data, data, length) == (size_t)-1)
  955.                 {
  956.                         free(w_data);
  957.                         return NULL;
  958.                 }
  959.         #endif
  960.  
  961.         JSONValue *value = JSON::Parse(w_data);
  962.         free(w_data);
  963.         return value;
  964. }
  965.  
  966. /**
  967.  * Parses a complete JSON encoded string (UNICODE input version)
  968.  *
  969.  * @access public
  970.  *
  971.  * @param wchar_t* data The JSON text
  972.  *
  973.  * @return JSONValue* Returns a JSON Value representing the root, or NULL on error
  974.  */
  975. JSONValue *JSON::Parse(const wchar_t *data)
  976. {
  977.         // Skip any preceding whitespace, end of data = no JSON = fail
  978.         if (!SkipWhitespace(&data))
  979.                 return NULL;
  980.  
  981.         // We need the start of a value here now...
  982.         JSONValue *value = JSONValue::Parse(&data);
  983.         if (value == NULL)
  984.                 return NULL;
  985.  
  986.         // Can be white space now and should be at the end of the string then...
  987.         if (SkipWhitespace(&data))
  988.         {
  989.                 delete value;
  990.                 return NULL;
  991.         }
  992.  
  993.         // We're now at the end of the string
  994.         return value;
  995. }
  996.  
  997. /**
  998.  * Turns the passed in JSONValue into a JSON encode string
  999.  *
  1000.  * @access public
  1001.  *
  1002.  * @param JSONValue* value The root value
  1003.  *
  1004.  * @return std::wstring Returns a JSON encoded string representation of the given value
  1005.  */
  1006. std::wstring JSON::Stringify(const JSONValue *value)
  1007. {
  1008.         if (value != NULL)
  1009.                 return value->Stringify();
  1010.         else
  1011.                 return L"";
  1012. }
  1013.  
  1014. /**
  1015.  * Skips over any whitespace characters (space, tab, \r or \n) defined by the JSON spec
  1016.  *
  1017.  * @access protected
  1018.  *
  1019.  * @param wchar_t** data Pointer to a wchar_t* that contains the JSON text
  1020.  *
  1021.  * @return bool Returns true if there is more data, or false if the end of the text was reached
  1022.  */
  1023. bool JSON::SkipWhitespace(const wchar_t **data)
  1024. {
  1025.         while (**data != 0 && (**data == L' ' || **data == L'\t' || **data == L'\r' || **data == L'\n'))
  1026.                 (*data)++;
  1027.  
  1028.         return **data != 0;
  1029. }
  1030.  
  1031. /**
  1032.  * Extracts a JSON String as defined by the spec - "<some chars>"
  1033.  * Any escaped characters are swapped out for their unescaped values
  1034.  *
  1035.  * @access protected
  1036.  *
  1037.  * @param wchar_t** data Pointer to a wchar_t* that contains the JSON text
  1038.  * @param std::wstring& str Reference to a std::wstring to receive the extracted string
  1039.  *
  1040.  * @return bool Returns true on success, false on failure
  1041.  */
  1042. bool JSON::ExtractString(const wchar_t **data, std::wstring &str)
  1043. {
  1044.         str = L"";
  1045.  
  1046.         while (**data != 0)
  1047.         {
  1048.                 // Save the char so we can change it if need be
  1049.                 wchar_t next_char = **data;
  1050.  
  1051.                 // Escaping something?
  1052.                 if (next_char == L'\\')
  1053.                 {
  1054.                         // Move over the escape char
  1055.                         (*data)++;
  1056.  
  1057.                         // Deal with the escaped char
  1058.                         switch (**data)
  1059.                         {
  1060.                                 case L'"': next_char = L'"'; break;
  1061.                                 case L'\\': next_char = L'\\'; break;
  1062.                                 case L'/': next_char = L'/'; break;
  1063.                                 case L'b': next_char = L'\b'; break;
  1064.                                 case L'f': next_char = L'\f'; break;
  1065.                                 case L'n': next_char = L'\n'; break;
  1066.                                 case L'r': next_char = L'\r'; break;
  1067.                                 case L't': next_char = L'\t'; break;
  1068.                                 case L'u':
  1069.                                 {
  1070.                                         // We need 5 chars (4 hex + the 'u') or its not valid
  1071.                                         if (!simplejson_wcsnlen(*data, 5))
  1072.                                                 return false;
  1073.  
  1074.                                         // Deal with the chars
  1075.                                         next_char = 0;
  1076.                                         for (int i = 0; i < 4; i++)
  1077.                                         {
  1078.                                                 // Do it first to move off the 'u' and leave us on the
  1079.                                                 // final hex digit as we move on by one later on
  1080.                                                 (*data)++;
  1081.  
  1082.                                                 next_char <<= 4;
  1083.  
  1084.                                                 // Parse the hex digit
  1085.                                                 if (**data >= '0' && **data <= '9')
  1086.                                                         next_char |= (**data - '0');
  1087.                                                 else if (**data >= 'A' && **data <= 'F')
  1088.                                                         next_char |= (10 + (**data - 'A'));
  1089.                                                 else if (**data >= 'a' && **data <= 'f')
  1090.                                                         next_char |= (10 + (**data - 'a'));
  1091.                                                 else
  1092.                                                 {
  1093.                                                         // Invalid hex digit = invalid JSON
  1094.                                                         return false;
  1095.                                                 }
  1096.                                         }
  1097.                                         break;
  1098.                                 }
  1099.  
  1100.                                 // By the spec, only the above cases are allowed
  1101.                                 default:
  1102.                                         return false;
  1103.                         }
  1104.                 }
  1105.  
  1106.                 // End of the string?
  1107.                 else if (next_char == L'"')
  1108.                 {
  1109.                         (*data)++;
  1110.                         str.reserve(); // Remove unused capacity
  1111.                         return true;
  1112.                 }
  1113.  
  1114.                 // Disallowed char?
  1115.                 else if (next_char < L' ' && next_char != L'\t')
  1116.                 {
  1117.                         // SPEC Violation: Allow tabs due to real world cases
  1118.                         return false;
  1119.                 }
  1120.  
  1121.                 // Add the next char
  1122.                 str += next_char;
  1123.  
  1124.                 // Move on
  1125.                 (*data)++;
  1126.         }
  1127.  
  1128.         // If we're here, the string ended incorrectly
  1129.         return false;
  1130. }
  1131.  
  1132. /**
  1133.  * Parses some text as though it is an integer
  1134.  *
  1135.  * @access protected
  1136.  *
  1137.  * @param wchar_t** data Pointer to a wchar_t* that contains the JSON text
  1138.  *
  1139.  * @return double Returns the double value of the number found
  1140.  */
  1141. double JSON::ParseInt(const wchar_t **data)
  1142. {
  1143.         double integer = 0;
  1144.         while (**data != 0 && **data >= '0' && **data <= '9')
  1145.                 integer = integer * 10 + (*(*data)++ - '0');
  1146.  
  1147.         return integer;
  1148. }
  1149.  
  1150. /**
  1151.  * Parses some text as though it is a decimal
  1152.  *
  1153.  * @access protected
  1154.  *
  1155.  * @param wchar_t** data Pointer to a wchar_t* that contains the JSON text
  1156.  *
  1157.  * @return double Returns the double value of the decimal found
  1158.  */
  1159. double JSON::ParseDecimal(const wchar_t **data)
  1160. {
  1161.         double decimal = 0.0;
  1162.   double factor = 0.1;
  1163.         while (**data != 0 && **data >= '0' && **data <= '9')
  1164.   {
  1165.     int digit = (*(*data)++ - '0');
  1166.                 decimal = decimal + digit * factor;
  1167.     factor *= 0.1;
  1168.   }
  1169.         return decimal;
  1170. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement