(wangle) fix a race in whenAll
[folly.git] / folly / json.h
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /**
18  *
19  * Serialize and deserialize folly::dynamic values as JSON.
20  *
21  * Before you use this you should probably understand the basic
22  * concepts in the JSON type system:
23  *
24  *    Value  : String | Bool | Null | Object | Array | Number
25  *    String : UTF-8 sequence
26  *    Object : (String, Value) pairs, with unique String keys
27  *    Array  : ordered list of Values
28  *    Null   : null
29  *    Bool   : true | false
30  *    Number : (representation unspecified)
31  *
32  * ... That's about it.  For more information see http://json.org or
33  * look up RFC 4627.
34  *
35  * If your dynamic has anything illegal with regard to this type
36  * system, the serializer will throw.
37  *
38  * @author Jordan DeLong <delong.j@fb.com>
39  */
40
41 #ifndef FOLLY_JSON_H_
42 #define FOLLY_JSON_H_
43
44 #include <folly/dynamic.h>
45 #include <folly/FBString.h>
46 #include <folly/Range.h>
47
48 namespace folly {
49
50 //////////////////////////////////////////////////////////////////////
51
52 namespace json {
53
54   //////////////////////////////////////////////////////////////////////
55
56   struct ParseError : std::runtime_error {
57     explicit ParseError(int line)
58       : std::runtime_error(to<std::string>("json parse error on line ", line))
59     {}
60
61     explicit ParseError(int line, std::string const& context,
62         std::string const& expected)
63       : std::runtime_error(to<std::string>("json parse error on line ", line,
64           !context.empty() ? to<std::string>(" near `", context, '\'')
65                           : "",
66           ": ", expected))
67     {}
68
69     explicit ParseError(std::string const& msg)
70       : std::runtime_error("json parse error: " + msg)
71     {}
72   };
73
74
75   struct serialization_opts {
76     explicit serialization_opts()
77       : allow_non_string_keys(false)
78       , javascript_safe(false)
79       , pretty_formatting(false)
80       , encode_non_ascii(false)
81       , validate_utf8(false)
82       , allow_trailing_comma(false)
83       , sort_keys(false)
84       , skip_invalid_utf8(false)
85       , allow_nan_inf(false)
86       , double_mode(double_conversion::DoubleToStringConverter::SHORTEST)
87       , double_num_digits(0) // ignored when mode is SHORTEST
88     {}
89
90     // If true, keys in an object can be non-strings.  (In strict
91     // JSON, object keys must be strings.)  This is used by dynamic's
92     // operator<<.
93     bool allow_non_string_keys;
94
95     /*
96      * If true, refuse to serialize 64-bit numbers that cannot be
97      * precisely represented by fit a double---instead, throws an
98      * exception if the document contains this.
99      */
100     bool javascript_safe;
101
102     // If true, the serialized json will contain space and newlines to
103     // try to be minimally "pretty".
104     bool pretty_formatting;
105
106     // If true, non-ASCII utf8 characters would be encoded as \uXXXX.
107     bool encode_non_ascii;
108
109     // Check that strings are valid utf8
110     bool validate_utf8;
111
112     // Allow trailing comma in lists of values / items
113     bool allow_trailing_comma;
114
115     // Sort keys of all objects before printing out (potentially slow)
116     bool sort_keys;
117
118     // Replace invalid utf8 characters with U+FFFD and continue
119     bool skip_invalid_utf8;
120
121     // true to allow NaN or INF values
122     bool allow_nan_inf;
123
124     // Options for how to print floating point values.  See Conv.h
125     // toAppend implementation for floating point for more info
126     double_conversion::DoubleToStringConverter::DtoaMode double_mode;
127     unsigned int double_num_digits;
128   };
129
130   /*
131    * Main JSON serialization routine taking folly::dynamic parameters.
132    * For the most common use cases there are simpler functions in the
133    * main folly namespace below.
134    */
135   fbstring serialize(dynamic const&, serialization_opts const&);
136
137   /*
138    * Escape a string so that it is legal to print it in JSON text and
139    * append the result to out.
140    */
141
142   void escapeString(StringPiece input,
143                     fbstring& out,
144                     const serialization_opts& opts);
145
146   /*
147    * Strip all C99-like comments (i.e. // and / * ... * /)
148    */
149   fbstring stripComments(StringPiece jsonC);
150 }
151
152 //////////////////////////////////////////////////////////////////////
153
154 /*
155  * Parse a json blob out of a range and produce a dynamic representing
156  * it.
157  */
158 dynamic parseJson(StringPiece, json::serialization_opts const&);
159 dynamic parseJson(StringPiece);
160
161 /*
162  * Serialize a dynamic into a json string.
163  */
164 fbstring toJson(dynamic const&);
165
166 /*
167  * Same as the above, except format the json with some minimal
168  * indentation.
169  */
170 fbstring toPrettyJson(dynamic const&);
171
172 //////////////////////////////////////////////////////////////////////
173
174 }
175
176 #endif