Merge pull request #4676 from jmarshallnz/dont_set_scraper_on_tvshow_on_nfo
[vuplus_xbmc] / xbmc / utils / JSONVariantWriter.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include <locale>
22
23 #include "JSONVariantWriter.h"
24
25 using namespace std;
26
27 string CJSONVariantWriter::Write(const CVariant &value, bool compact)
28 {
29   string output;
30
31 #if YAJL_MAJOR == 2
32   yajl_gen g = yajl_gen_alloc(NULL);
33   yajl_gen_config(g, yajl_gen_beautify, compact ? 0 : 1);
34   yajl_gen_config(g, yajl_gen_indent_string, "\t");
35 #else
36   yajl_gen_config conf = { compact ? 0 : 1, "\t" };
37   yajl_gen g = yajl_gen_alloc(&conf, NULL);
38 #endif
39
40   // Set locale to classic ("C") to ensure valid JSON numbers
41   const char *currentLocale = setlocale(LC_NUMERIC, NULL);
42   if (currentLocale != NULL)
43     setlocale(LC_NUMERIC, "C");
44
45   if (InternalWrite(g, value))
46   {
47     const unsigned char * buffer;
48
49 #if YAJL_MAJOR == 2
50     size_t length;
51     yajl_gen_get_buf(g, &buffer, &length);
52 #else
53     unsigned int length;
54     yajl_gen_get_buf(g, &buffer, &length);
55 #endif
56     output = string((const char *)buffer, length);
57   }
58
59   // Re-set locale to what it was before using yajl
60   if (currentLocale != NULL)
61     setlocale(LC_NUMERIC, currentLocale);
62
63   yajl_gen_clear(g);
64   yajl_gen_free(g);
65
66   return output;
67 }
68
69 bool CJSONVariantWriter::InternalWrite(yajl_gen g, const CVariant &value)
70 {
71   bool success = false;
72
73   switch (value.type())
74   {
75   case CVariant::VariantTypeInteger:
76 #if YAJL_MAJOR == 2
77     success = yajl_gen_status_ok == yajl_gen_integer(g, (long long int)value.asInteger());
78 #else
79     success = yajl_gen_status_ok == yajl_gen_integer(g, (long int)value.asInteger());
80 #endif
81     break;
82   case CVariant::VariantTypeUnsignedInteger:
83 #if YAJL_MAJOR == 2
84     success = yajl_gen_status_ok == yajl_gen_integer(g, (long long int)value.asUnsignedInteger());
85 #else
86     success = yajl_gen_status_ok == yajl_gen_integer(g, (long int)value.asUnsignedInteger());
87 #endif
88     break;
89   case CVariant::VariantTypeDouble:
90     success = yajl_gen_status_ok == yajl_gen_double(g, value.asDouble());
91     break;
92   case CVariant::VariantTypeBoolean:
93     success = yajl_gen_status_ok == yajl_gen_bool(g, value.asBoolean() ? 1 : 0);
94     break;
95   case CVariant::VariantTypeString:
96 #if YAJL_MAJOR == 2
97     success = yajl_gen_status_ok == yajl_gen_string(g, (const unsigned char*)value.c_str(), (size_t)value.size());
98 #else
99     success = yajl_gen_status_ok == yajl_gen_string(g, (const unsigned char*)value.c_str(), value.size());
100 #endif
101     break;
102   case CVariant::VariantTypeArray:
103     success = yajl_gen_status_ok == yajl_gen_array_open(g);
104
105     for (CVariant::const_iterator_array itr = value.begin_array(); itr != value.end_array() && success; itr++)
106       success &= InternalWrite(g, *itr);
107
108     if (success)
109       success = yajl_gen_status_ok == yajl_gen_array_close(g);
110
111     break;
112   case CVariant::VariantTypeObject:
113     success = yajl_gen_status_ok == yajl_gen_map_open(g);
114
115     for (CVariant::const_iterator_map itr = value.begin_map(); itr != value.end_map() && success; itr++)
116     {
117 #if YAJL_MAJOR == 2
118       success &= yajl_gen_status_ok == yajl_gen_string(g, (const unsigned char*)itr->first.c_str(), (size_t)itr->first.length());
119 #else
120       success &= yajl_gen_status_ok == yajl_gen_string(g, (const unsigned char*)itr->first.c_str(), itr->first.length());
121 #endif
122       if (success)
123         success &= InternalWrite(g, itr->second);
124     }
125
126     if (success)
127       success &= yajl_gen_status_ok == yajl_gen_map_close(g);
128
129     break;
130   case CVariant::VariantTypeConstNull:
131   case CVariant::VariantTypeNull:
132   default:
133     success = yajl_gen_status_ok == yajl_gen_null(g);
134     break;
135   }
136
137   return success;
138 }