조성현

중간저장4

Showing 46 changed files with 3769 additions and 69 deletions
...@@ -86,6 +86,9 @@ ...@@ -86,6 +86,9 @@
86 <ClCompile Include="curl_processor.cpp"> 86 <ClCompile Include="curl_processor.cpp">
87 <Filter>Source Files</Filter> 87 <Filter>Source Files</Filter>
88 </ClCompile> 88 </ClCompile>
89 + <ClCompile Include="bibtex_processor.cpp">
90 + <Filter>Source Files</Filter>
91 + </ClCompile>
89 </ItemGroup> 92 </ItemGroup>
90 <ItemGroup> 93 <ItemGroup>
91 <CustomBuild Include="PaperGraphWidget.h"> 94 <CustomBuild Include="PaperGraphWidget.h">
...@@ -117,5 +120,8 @@ ...@@ -117,5 +120,8 @@
117 <ClInclude Include="curl_processor.h"> 120 <ClInclude Include="curl_processor.h">
118 <Filter>Header Files</Filter> 121 <Filter>Header Files</Filter>
119 </ClInclude> 122 </ClInclude>
123 + <ClInclude Include="bibtex_processor.h">
124 + <Filter>Header Files</Filter>
125 + </ClInclude>
120 </ItemGroup> 126 </ItemGroup>
121 </Project> 127 </Project>
...\ No newline at end of file ...\ No newline at end of file
......
1 +#include "stdafx.h"
2 +#include "bibtex_processor.h"
3 +
4 +//////////////////////////////////////////////////////////////////
5 +// constructor, destructor
6 +//////////////////////////////////////////////////////////////////
7 +bibtex_processor::bibtex_processor() {
8 +}
9 +
10 +bibtex_processor::~bibtex_processor() {
11 +}
12 +
13 +
14 +//////////////////////////////////////////////////////////////////
15 +// methods
16 +//////////////////////////////////////////////////////////////////
17 +void bibtex_processor::read(const std::string& bibtex_string) {
18 + bibtex::read(bibtex_string, entry);
19 +}
20 +
21 +bool bibtex_processor::get_value(const std::string& field_name, std::string& return_val) {
22 + if (entry.fields.empty()) return false;
23 +
24 + bool found = false;
25 + for (auto& field: entry.fields) {
26 + if (field.first == field_name) {
27 + found = true;
28 + return_val = field.second.front();
29 + break;
30 + }
31 + }
32 + return found;
33 +}
...\ No newline at end of file ...\ No newline at end of file
1 +#pragma once
2 +#include "stdafx.h"
3 +
4 +class bibtex_processor
5 +{
6 + //private var
7 +private:
8 + bibtex::BibTeXEntry entry;
9 +
10 + //constructor, destructor
11 +public:
12 + bibtex_processor();
13 + ~bibtex_processor();
14 +
15 + //methods
16 +public:
17 + void read(const std::string& bibtex_string);
18 + bool get_value(const std::string& field_name, std::string& return_val);
19 +};
20 +
...@@ -5,18 +5,18 @@ ...@@ -5,18 +5,18 @@
5 ////////////////////////////////////////////////////////////////// 5 //////////////////////////////////////////////////////////////////
6 // private func 6 // private func
7 ////////////////////////////////////////////////////////////////// 7 //////////////////////////////////////////////////////////////////
8 -size_t curl_processor::write_callback(void *contents, size_t size, size_t nmemb, void *userp) { 8 +//size_t curl_processor::write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
9 - //copy ptr 9 +// //copy ptr
10 - std::string* p_str = (std::string*)userp; 10 +// std::string* p_str = (std::string*)userp;
11 - 11 +//
12 - //clear 12 +// //clear
13 - if (!p_str->empty()) 13 +// if (!p_str->empty())
14 - p_str->clear(); 14 +// p_str->clear();
15 - 15 +//
16 - //write 16 +// //write
17 - p_str->append((char*)contents, size*nmemb); 17 +// p_str->append((char*)contents, size*nmemb);
18 - return size*nmemb; 18 +// return size*nmemb;
19 -} 19 +//}
20 20
21 21
22 ////////////////////////////////////////////////////////////////// 22 //////////////////////////////////////////////////////////////////
...@@ -29,7 +29,7 @@ curl_processor::curl_processor() { ...@@ -29,7 +29,7 @@ curl_processor::curl_processor() {
29 } 29 }
30 30
31 //set curl option 31 //set curl option
32 - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, this->write_callback); 32 + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
33 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result_buffer); 33 curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result_buffer);
34 } 34 }
35 35
......
1 -#ifndef CURL_PROCESSOR_H 1 +#pragma once
2 -#define CURL_PROCESSOR_H 2 +#include "stdafx.h"
3 -
4 -#include <stdafx.h>
5 3
6 class curl_processor 4 class curl_processor
7 { 5 {
...@@ -11,10 +9,6 @@ private: ...@@ -11,10 +9,6 @@ private:
11 CURLcode res; 9 CURLcode res;
12 std::string result_buffer; 10 std::string result_buffer;
13 11
14 - //private func
15 -private:
16 - size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp);
17 -
18 //constructor, destructor 12 //constructor, destructor
19 public: 13 public:
20 curl_processor(); 14 curl_processor();
...@@ -27,4 +21,3 @@ public: ...@@ -27,4 +21,3 @@ public:
27 bool perform(); 21 bool perform();
28 }; 22 };
29 23
30 -#endif // CURL_PROCESSOR_H
...\ No newline at end of file ...\ No newline at end of file
......
1 +// Copyright (c) 2012 Sergiu Dotenco
2 +//
3 +// Permission is hereby granted, free of charge, to any person obtaining a copy
4 +// of this software and associated documentation files (the "Software"), to deal
5 +// in the Software without restriction, including without limitation the rights
6 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 +// copies of the Software, and to permit persons to whom the Software is
8 +// furnished to do so, subject to the following conditions:
9 +//
10 +// The above copyright notice and this permission notice shall be included in
11 +// all copies or substantial portions of the Software.
12 +//
13 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 +// SOFTWARE.
20 +
21 +/**
22 + * @brief BibTeX entry.
23 + * @file bibtexentry.hpp
24 + * @author Sergiu Dotenco
25 + * @version 0.1
26 + */
27 +
28 +#ifndef BIBTEXENTRY_HPP
29 +#define BIBTEXENTRY_HPP
30 +
31 +#pragma once
32 +
33 +#include <string>
34 +#include <utility>
35 +#include <vector>
36 +
37 +#include <boost/fusion/include/adapt_struct.hpp>
38 +#include <boost/fusion/include/std_pair.hpp>
39 +#include <boost/operators.hpp>
40 +#include <boost/optional.hpp>
41 +#include <boost/spirit/include/qi.hpp>
42 +#include <boost/typeof/typeof.hpp>
43 +
44 +#ifndef BOOST_SPIRIT_AUTO
45 +#define BOOST_SPIRIT_AUTO(domain_, name, expr) \
46 + typedef boost::proto::result_of:: \
47 + deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
48 + BOOST_SPIRIT_ASSERT_MATCH( \
49 + boost::spirit::domain_::domain, name##_expr_type); \
50 + BOOST_AUTO(const name, boost::proto::deep_copy(expr));
51 +#endif // BOOST_SPIRIT_AUTO
52 +
53 +namespace bibtex {
54 +
55 +namespace detail {
56 +
57 +namespace encoding = boost::spirit::standard_wide;
58 +
59 +} // namespace detail
60 +
61 +typedef std::vector<std::string> ValueVector;
62 +typedef std::pair<std::string, ValueVector> KeyValue;
63 +typedef std::vector<KeyValue> KeyValueVector;
64 +typedef detail::encoding::space_type Space;
65 +
66 +BOOST_SPIRIT_AUTO(qi, space, detail::encoding::space |
67 + '%' >> *(boost::spirit::qi::char_ - boost::spirit::qi::eol)
68 + >> boost::spirit::qi::eol)
69 +
70 +/**
71 + * @brief Single BibTeX entry.
72 + */
73 +struct BibTeXEntry
74 + : boost::equality_comparable<BibTeXEntry>
75 +{
76 + //! Entry's tag.
77 + std::string tag;
78 + //! Entry's optional key.
79 + boost::optional<std::string> key;
80 + //! Entry's key/value pairs.
81 + KeyValueVector fields;
82 +};
83 +
84 +inline bool operator==(const BibTeXEntry& lhs, const BibTeXEntry& rhs)
85 +{
86 + return lhs.tag == rhs.tag && lhs.tag == rhs.tag &&
87 + lhs.fields == rhs.fields;
88 +}
89 +
90 +} // namespace bibtex
91 +
92 +BOOST_FUSION_ADAPT_STRUCT(
93 + bibtex::BibTeXEntry,
94 + (std::string, tag)
95 + (boost::optional<std::string>, key)
96 + (bibtex::KeyValueVector, fields)
97 +)
98 +
99 +#endif // BIBTEXENTRY_HPP
This diff is collapsed. Click to expand it.
1 +// Copyright (c) 2012 Sergiu Dotenco
2 +//
3 +// Permission is hereby granted, free of charge, to any person obtaining a copy
4 +// of this software and associated documentation files (the "Software"), to deal
5 +// in the Software without restriction, including without limitation the rights
6 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 +// copies of the Software, and to permit persons to whom the Software is
8 +// furnished to do so, subject to the following conditions:
9 +//
10 +// The above copyright notice and this permission notice shall be included in
11 +// all copies or substantial portions of the Software.
12 +//
13 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 +// SOFTWARE.
20 +
21 +/**
22 + * @brief Boost.Spirit based BibTeX generator.
23 + * @file bibtexwriter.hpp
24 + * @author Sergiu Dotenco
25 + * @version 0.1
26 + */
27 +
28 +#ifndef BIBTEXWRITER_HPP
29 +#define BIBTEXWRITER_HPP
30 +
31 +#pragma once
32 +
33 +#include <iterator>
34 +#include <ostream>
35 +#include <string>
36 +
37 +#include <boost/algorithm/string/case_conv.hpp>
38 +#include <boost/fusion/adapted/std_pair.hpp>
39 +#include <boost/mpl/and.hpp>
40 +#include <boost/range/has_range_iterator.hpp>
41 +#include <boost/spirit/include/karma.hpp>
42 +#include <boost/spirit/include/phoenix.hpp>
43 +#include <boost/type_traits/is_same.hpp>
44 +#include <boost/utility/enable_if.hpp>
45 +
46 +#include "bibtexentry.hpp"
47 +
48 +namespace bibtex {
49 +
50 +template<class OutputIterator, class Skipper>
51 +class BibTeXWriter
52 + : public boost::spirit::karma::grammar
53 + <
54 + OutputIterator,
55 + BibTeXEntry(),
56 + Skipper
57 + >
58 +{
59 +public:
60 + BibTeXWriter()
61 + : BibTeXWriter::base_type(start_, "single BibTeX entry")
62 + {
63 + using namespace boost::spirit;
64 + namespace ph = boost::phoenix;
65 + namespace enc = detail::encoding;
66 +
67 + escapedBrace.add
68 + ('{', "\\{")
69 + ('}', "\\}")
70 + ;
71 +
72 + tag_ = +enc::alnum;
73 + key_ = +~karma::char_(',');
74 + value_ = *(escapedBrace | ~karma::char_("{}"));
75 +
76 + values_
77 + = ('{' << value_ << '}') % " # ";
78 + ;
79 +
80 + field_
81 + = enc::string
82 + << " = "
83 + << values_
84 + ;
85 +
86 + fields_
87 + = (repeat(4)[' '] << field_) % (',' << karma::eol)
88 + ;
89 +
90 + generic_
91 + = '@' << tag_ <<
92 + '{'
93 + << -key_ << ',' << karma::eol
94 + << fields_ << karma::eol <<
95 + '}'
96 + ;
97 +
98 + simple_
99 + =
100 + &
101 + (
102 + karma::string("comment")
103 + |
104 + karma::string("include")
105 + |
106 + karma::string("preamble")
107 + )
108 + [
109 + _1 = ph::bind(tolower, ph::at_c<0>(_val))
110 + ]
111 + <<
112 + '@'
113 + <<
114 + karma::string
115 + [
116 + _1 = ph::at_c<0>(_val)
117 + ]
118 + <<
119 + '{'
120 + << values_
121 + [
122 + _1 = ph::bind(&KeyValue::second,
123 + ph::front(ph::at_c<2>(_val)))
124 + ]
125 + <<
126 + '}'
127 + ;
128 +
129 + string_
130 + =
131 + &karma::string("string")
132 + [
133 + _1 = ph::bind(tolower, ph::at_c<0>(_val))
134 + ]
135 + <<
136 + '@'
137 + <<
138 + karma::string
139 + [
140 + _1 = ph::at_c<0>(_val)
141 + ]
142 + <<
143 + '{'
144 + << field_
145 + [
146 + ph::let(ph::local_names::_a = ph::front(ph::at_c<2>(_val)))
147 + [
148 + _1 = ph::construct<KeyValue>
149 + (ph::bind(&KeyValue::first, ph::local_names::_a),
150 + ph::bind(&KeyValue::second, ph::local_names::_a))
151 + ]
152 + ]
153 + <<
154 + '}'
155 + ;
156 +
157 + start_
158 + = string_
159 + | simple_
160 + | generic_
161 + ;
162 + }
163 +
164 + static std::string tolower(const std::string& in)
165 + {
166 + return boost::algorithm::to_lower_copy(in);
167 + }
168 +
169 +private:
170 + boost::spirit::karma::rule<OutputIterator, BibTeXEntry(), Skipper> start_;
171 + boost::spirit::karma::rule<OutputIterator, BibTeXEntry(), Skipper> generic_;
172 + boost::spirit::karma::rule<OutputIterator, BibTeXEntry(), Skipper> simple_;
173 + boost::spirit::karma::rule<OutputIterator, BibTeXEntry()> string_;
174 + boost::spirit::karma::rule<OutputIterator, std::string()> tag_;
175 + boost::spirit::karma::rule<OutputIterator, std::string()> key_;
176 + boost::spirit::karma::rule<OutputIterator, std::string()> value_;
177 + boost::spirit::karma::rule<OutputIterator, ValueVector(), Skipper>
178 + values_;
179 + boost::spirit::karma::rule<OutputIterator, KeyValue(), Skipper>
180 + field_;
181 + boost::spirit::karma::rule<OutputIterator, KeyValueVector(), Skipper>
182 + fields_;
183 + boost::spirit::karma::symbols<char, const char*> escapedBrace;
184 +};
185 +
186 +template<class OutputIterator, class Skipper>
187 +inline bool write(OutputIterator out, const Skipper& skipper,
188 + const BibTeXEntry& entry)
189 +{
190 + BibTeXWriter<OutputIterator, Skipper> writer;
191 + return boost::spirit::karma::generate_delimited(out, writer,
192 + boost::spirit::karma::eol, entry);
193 +}
194 +
195 +template<class OutputIterator, class Skipper, class Range>
196 +inline bool write(OutputIterator out, Skipper& skipper, const Range& range,
197 + typename boost::enable_if<boost::has_range_iterator<Range> >::type*
198 + /*dummy*/ = NULL)
199 +{
200 + BibTeXWriter<OutputIterator, Skipper> writer;
201 + return boost::spirit::karma::generate_delimited(out, *writer,
202 + boost::spirit::karma::eol, range);
203 +}
204 +
205 +template<class OutputIterator>
206 +inline bool write(OutputIterator out, const BibTeXEntry& entry)
207 +{
208 + return write(out, space, entry);
209 +}
210 +
211 +template<class OutputIterator, class Range>
212 +inline bool write(OutputIterator out, const Range& range,
213 + typename boost::enable_if<boost::has_range_iterator<Range> >::type*
214 + /*dummy*/ = NULL)
215 +{
216 + return write(out, space, range);
217 +}
218 +
219 +template<class E, class T>
220 +inline std::basic_ostream<E, T>& operator<<(std::basic_ostream<E, T>& out,
221 + const BibTeXEntry& entry)
222 +{
223 + write(std::ostream_iterator<E>(out), entry);
224 + return out;
225 +}
226 +
227 +template<class E, class T, class Range>
228 +inline typename boost::enable_if<
229 + boost::mpl::and_<
230 + boost::has_range_iterator<Range>,
231 + boost::is_same<typename Range::value_type, BibTeXEntry>
232 + >, std::basic_ostream<E, T>
233 +>::type& operator<<(std::basic_ostream<E, T>& out, const Range& entries)
234 +{
235 + write(std::ostream_iterator<E>(out), entries);
236 + return out;
237 +}
238 +
239 +} // namespace bibtex
240 +
241 +#endif // BIBTEXWRITER_HPP
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_ERROR_EN_H_
16 +#define RAPIDJSON_ERROR_EN_H_
17 +
18 +#include "error.h"
19 +
20 +#ifdef __clang__
21 +RAPIDJSON_DIAG_PUSH
22 +RAPIDJSON_DIAG_OFF(switch-enum)
23 +RAPIDJSON_DIAG_OFF(covered-switch-default)
24 +#endif
25 +
26 +RAPIDJSON_NAMESPACE_BEGIN
27 +
28 +//! Maps error code of parsing into error message.
29 +/*!
30 + \ingroup RAPIDJSON_ERRORS
31 + \param parseErrorCode Error code obtained in parsing.
32 + \return the error message.
33 + \note User can make a copy of this function for localization.
34 + Using switch-case is safer for future modification of error codes.
35 +*/
36 +inline const RAPIDJSON_ERROR_CHARTYPE* GetParseError_En(ParseErrorCode parseErrorCode) {
37 + switch (parseErrorCode) {
38 + case kParseErrorNone: return RAPIDJSON_ERROR_STRING("No error.");
39 +
40 + case kParseErrorDocumentEmpty: return RAPIDJSON_ERROR_STRING("The document is empty.");
41 + case kParseErrorDocumentRootNotSingular: return RAPIDJSON_ERROR_STRING("The document root must not be followed by other values.");
42 +
43 + case kParseErrorValueInvalid: return RAPIDJSON_ERROR_STRING("Invalid value.");
44 +
45 + case kParseErrorObjectMissName: return RAPIDJSON_ERROR_STRING("Missing a name for object member.");
46 + case kParseErrorObjectMissColon: return RAPIDJSON_ERROR_STRING("Missing a colon after a name of object member.");
47 + case kParseErrorObjectMissCommaOrCurlyBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or '}' after an object member.");
48 +
49 + case kParseErrorArrayMissCommaOrSquareBracket: return RAPIDJSON_ERROR_STRING("Missing a comma or ']' after an array element.");
50 +
51 + case kParseErrorStringUnicodeEscapeInvalidHex: return RAPIDJSON_ERROR_STRING("Incorrect hex digit after \\u escape in string.");
52 + case kParseErrorStringUnicodeSurrogateInvalid: return RAPIDJSON_ERROR_STRING("The surrogate pair in string is invalid.");
53 + case kParseErrorStringEscapeInvalid: return RAPIDJSON_ERROR_STRING("Invalid escape character in string.");
54 + case kParseErrorStringMissQuotationMark: return RAPIDJSON_ERROR_STRING("Missing a closing quotation mark in string.");
55 + case kParseErrorStringInvalidEncoding: return RAPIDJSON_ERROR_STRING("Invalid encoding in string.");
56 +
57 + case kParseErrorNumberTooBig: return RAPIDJSON_ERROR_STRING("Number too big to be stored in double.");
58 + case kParseErrorNumberMissFraction: return RAPIDJSON_ERROR_STRING("Miss fraction part in number.");
59 + case kParseErrorNumberMissExponent: return RAPIDJSON_ERROR_STRING("Miss exponent in number.");
60 +
61 + case kParseErrorTermination: return RAPIDJSON_ERROR_STRING("Terminate parsing due to Handler error.");
62 + case kParseErrorUnspecificSyntaxError: return RAPIDJSON_ERROR_STRING("Unspecific syntax error.");
63 +
64 + default: return RAPIDJSON_ERROR_STRING("Unknown error.");
65 + }
66 +}
67 +
68 +RAPIDJSON_NAMESPACE_END
69 +
70 +#ifdef __clang__
71 +RAPIDJSON_DIAG_POP
72 +#endif
73 +
74 +#endif // RAPIDJSON_ERROR_EN_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_ERROR_ERROR_H_
16 +#define RAPIDJSON_ERROR_ERROR_H_
17 +
18 +#include "../rapidjson.h"
19 +
20 +#ifdef __clang__
21 +RAPIDJSON_DIAG_PUSH
22 +RAPIDJSON_DIAG_OFF(padded)
23 +#endif
24 +
25 +/*! \file error.h */
26 +
27 +/*! \defgroup RAPIDJSON_ERRORS RapidJSON error handling */
28 +
29 +///////////////////////////////////////////////////////////////////////////////
30 +// RAPIDJSON_ERROR_CHARTYPE
31 +
32 +//! Character type of error messages.
33 +/*! \ingroup RAPIDJSON_ERRORS
34 + The default character type is \c char.
35 + On Windows, user can define this macro as \c TCHAR for supporting both
36 + unicode/non-unicode settings.
37 +*/
38 +#ifndef RAPIDJSON_ERROR_CHARTYPE
39 +#define RAPIDJSON_ERROR_CHARTYPE char
40 +#endif
41 +
42 +///////////////////////////////////////////////////////////////////////////////
43 +// RAPIDJSON_ERROR_STRING
44 +
45 +//! Macro for converting string literial to \ref RAPIDJSON_ERROR_CHARTYPE[].
46 +/*! \ingroup RAPIDJSON_ERRORS
47 + By default this conversion macro does nothing.
48 + On Windows, user can define this macro as \c _T(x) for supporting both
49 + unicode/non-unicode settings.
50 +*/
51 +#ifndef RAPIDJSON_ERROR_STRING
52 +#define RAPIDJSON_ERROR_STRING(x) x
53 +#endif
54 +
55 +RAPIDJSON_NAMESPACE_BEGIN
56 +
57 +///////////////////////////////////////////////////////////////////////////////
58 +// ParseErrorCode
59 +
60 +//! Error code of parsing.
61 +/*! \ingroup RAPIDJSON_ERRORS
62 + \see GenericReader::Parse, GenericReader::GetParseErrorCode
63 +*/
64 +enum ParseErrorCode {
65 + kParseErrorNone = 0, //!< No error.
66 +
67 + kParseErrorDocumentEmpty, //!< The document is empty.
68 + kParseErrorDocumentRootNotSingular, //!< The document root must not follow by other values.
69 +
70 + kParseErrorValueInvalid, //!< Invalid value.
71 +
72 + kParseErrorObjectMissName, //!< Missing a name for object member.
73 + kParseErrorObjectMissColon, //!< Missing a colon after a name of object member.
74 + kParseErrorObjectMissCommaOrCurlyBracket, //!< Missing a comma or '}' after an object member.
75 +
76 + kParseErrorArrayMissCommaOrSquareBracket, //!< Missing a comma or ']' after an array element.
77 +
78 + kParseErrorStringUnicodeEscapeInvalidHex, //!< Incorrect hex digit after \\u escape in string.
79 + kParseErrorStringUnicodeSurrogateInvalid, //!< The surrogate pair in string is invalid.
80 + kParseErrorStringEscapeInvalid, //!< Invalid escape character in string.
81 + kParseErrorStringMissQuotationMark, //!< Missing a closing quotation mark in string.
82 + kParseErrorStringInvalidEncoding, //!< Invalid encoding in string.
83 +
84 + kParseErrorNumberTooBig, //!< Number too big to be stored in double.
85 + kParseErrorNumberMissFraction, //!< Miss fraction part in number.
86 + kParseErrorNumberMissExponent, //!< Miss exponent in number.
87 +
88 + kParseErrorTermination, //!< Parsing was terminated.
89 + kParseErrorUnspecificSyntaxError //!< Unspecific syntax error.
90 +};
91 +
92 +//! Result of parsing (wraps ParseErrorCode)
93 +/*!
94 + \ingroup RAPIDJSON_ERRORS
95 + \code
96 + Document doc;
97 + ParseResult ok = doc.Parse("[42]");
98 + if (!ok) {
99 + fprintf(stderr, "JSON parse error: %s (%u)",
100 + GetParseError_En(ok.Code()), ok.Offset());
101 + exit(EXIT_FAILURE);
102 + }
103 + \endcode
104 + \see GenericReader::Parse, GenericDocument::Parse
105 +*/
106 +struct ParseResult {
107 +public:
108 + //! Default constructor, no error.
109 + ParseResult() : code_(kParseErrorNone), offset_(0) {}
110 + //! Constructor to set an error.
111 + ParseResult(ParseErrorCode code, size_t offset) : code_(code), offset_(offset) {}
112 +
113 + //! Get the error code.
114 + ParseErrorCode Code() const { return code_; }
115 + //! Get the error offset, if \ref IsError(), 0 otherwise.
116 + size_t Offset() const { return offset_; }
117 +
118 + //! Conversion to \c bool, returns \c true, iff !\ref IsError().
119 + operator bool() const { return !IsError(); }
120 + //! Whether the result is an error.
121 + bool IsError() const { return code_ != kParseErrorNone; }
122 +
123 + bool operator==(const ParseResult& that) const { return code_ == that.code_; }
124 + bool operator==(ParseErrorCode code) const { return code_ == code; }
125 + friend bool operator==(ParseErrorCode code, const ParseResult & err) { return code == err.code_; }
126 +
127 + //! Reset error code.
128 + void Clear() { Set(kParseErrorNone); }
129 + //! Update error code and offset.
130 + void Set(ParseErrorCode code, size_t offset = 0) { code_ = code; offset_ = offset; }
131 +
132 +private:
133 + ParseErrorCode code_;
134 + size_t offset_;
135 +};
136 +
137 +//! Function pointer type of GetParseError().
138 +/*! \ingroup RAPIDJSON_ERRORS
139 +
140 + This is the prototype for \c GetParseError_X(), where \c X is a locale.
141 + User can dynamically change locale in runtime, e.g.:
142 +\code
143 + GetParseErrorFunc GetParseError = GetParseError_En; // or whatever
144 + const RAPIDJSON_ERROR_CHARTYPE* s = GetParseError(document.GetParseErrorCode());
145 +\endcode
146 +*/
147 +typedef const RAPIDJSON_ERROR_CHARTYPE* (*GetParseErrorFunc)(ParseErrorCode);
148 +
149 +RAPIDJSON_NAMESPACE_END
150 +
151 +#ifdef __clang__
152 +RAPIDJSON_DIAG_POP
153 +#endif
154 +
155 +#endif // RAPIDJSON_ERROR_ERROR_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_FILEREADSTREAM_H_
16 +#define RAPIDJSON_FILEREADSTREAM_H_
17 +
18 +#include "stream.h"
19 +#include <cstdio>
20 +
21 +#ifdef __clang__
22 +RAPIDJSON_DIAG_PUSH
23 +RAPIDJSON_DIAG_OFF(padded)
24 +RAPIDJSON_DIAG_OFF(unreachable-code)
25 +RAPIDJSON_DIAG_OFF(missing-noreturn)
26 +#endif
27 +
28 +RAPIDJSON_NAMESPACE_BEGIN
29 +
30 +//! File byte stream for input using fread().
31 +/*!
32 + \note implements Stream concept
33 +*/
34 +class FileReadStream {
35 +public:
36 + typedef char Ch; //!< Character type (byte).
37 +
38 + //! Constructor.
39 + /*!
40 + \param fp File pointer opened for read.
41 + \param buffer user-supplied buffer.
42 + \param bufferSize size of buffer in bytes. Must >=4 bytes.
43 + */
44 + FileReadStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferSize_(bufferSize), bufferLast_(0), current_(buffer_), readCount_(0), count_(0), eof_(false) {
45 + RAPIDJSON_ASSERT(fp_ != 0);
46 + RAPIDJSON_ASSERT(bufferSize >= 4);
47 + Read();
48 + }
49 +
50 + Ch Peek() const { return *current_; }
51 + Ch Take() { Ch c = *current_; Read(); return c; }
52 + size_t Tell() const { return count_ + static_cast<size_t>(current_ - buffer_); }
53 +
54 + // Not implemented
55 + void Put(Ch) { RAPIDJSON_ASSERT(false); }
56 + void Flush() { RAPIDJSON_ASSERT(false); }
57 + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
58 + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
59 +
60 + // For encoding detection only.
61 + const Ch* Peek4() const {
62 + return (current_ + 4 <= bufferLast_) ? current_ : 0;
63 + }
64 +
65 +private:
66 + void Read() {
67 + if (current_ < bufferLast_)
68 + ++current_;
69 + else if (!eof_) {
70 + count_ += readCount_;
71 + readCount_ = fread(buffer_, 1, bufferSize_, fp_);
72 + bufferLast_ = buffer_ + readCount_ - 1;
73 + current_ = buffer_;
74 +
75 + if (readCount_ < bufferSize_) {
76 + buffer_[readCount_] = '\0';
77 + ++bufferLast_;
78 + eof_ = true;
79 + }
80 + }
81 + }
82 +
83 + std::FILE* fp_;
84 + Ch *buffer_;
85 + size_t bufferSize_;
86 + Ch *bufferLast_;
87 + Ch *current_;
88 + size_t readCount_;
89 + size_t count_; //!< Number of characters read
90 + bool eof_;
91 +};
92 +
93 +RAPIDJSON_NAMESPACE_END
94 +
95 +#ifdef __clang__
96 +RAPIDJSON_DIAG_POP
97 +#endif
98 +
99 +#endif // RAPIDJSON_FILESTREAM_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_FILEWRITESTREAM_H_
16 +#define RAPIDJSON_FILEWRITESTREAM_H_
17 +
18 +#include "stream.h"
19 +#include <cstdio>
20 +
21 +#ifdef __clang__
22 +RAPIDJSON_DIAG_PUSH
23 +RAPIDJSON_DIAG_OFF(unreachable-code)
24 +#endif
25 +
26 +RAPIDJSON_NAMESPACE_BEGIN
27 +
28 +//! Wrapper of C file stream for input using fread().
29 +/*!
30 + \note implements Stream concept
31 +*/
32 +class FileWriteStream {
33 +public:
34 + typedef char Ch; //!< Character type. Only support char.
35 +
36 + FileWriteStream(std::FILE* fp, char* buffer, size_t bufferSize) : fp_(fp), buffer_(buffer), bufferEnd_(buffer + bufferSize), current_(buffer_) {
37 + RAPIDJSON_ASSERT(fp_ != 0);
38 + }
39 +
40 + void Put(char c) {
41 + if (current_ >= bufferEnd_)
42 + Flush();
43 +
44 + *current_++ = c;
45 + }
46 +
47 + void PutN(char c, size_t n) {
48 + size_t avail = static_cast<size_t>(bufferEnd_ - current_);
49 + while (n > avail) {
50 + std::memset(current_, c, avail);
51 + current_ += avail;
52 + Flush();
53 + n -= avail;
54 + avail = static_cast<size_t>(bufferEnd_ - current_);
55 + }
56 +
57 + if (n > 0) {
58 + std::memset(current_, c, n);
59 + current_ += n;
60 + }
61 + }
62 +
63 + void Flush() {
64 + if (current_ != buffer_) {
65 + size_t result = fwrite(buffer_, 1, static_cast<size_t>(current_ - buffer_), fp_);
66 + if (result < static_cast<size_t>(current_ - buffer_)) {
67 + // failure deliberately ignored at this time
68 + // added to avoid warn_unused_result build errors
69 + }
70 + current_ = buffer_;
71 + }
72 + }
73 +
74 + // Not implemented
75 + char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
76 + char Take() { RAPIDJSON_ASSERT(false); return 0; }
77 + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
78 + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
79 + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
80 +
81 +private:
82 + // Prohibit copy constructor & assignment operator.
83 + FileWriteStream(const FileWriteStream&);
84 + FileWriteStream& operator=(const FileWriteStream&);
85 +
86 + std::FILE* fp_;
87 + char *buffer_;
88 + char *bufferEnd_;
89 + char *current_;
90 +};
91 +
92 +//! Implement specialized version of PutN() with memset() for better performance.
93 +template<>
94 +inline void PutN(FileWriteStream& stream, char c, size_t n) {
95 + stream.PutN(c, n);
96 +}
97 +
98 +RAPIDJSON_NAMESPACE_END
99 +
100 +#ifdef __clang__
101 +RAPIDJSON_DIAG_POP
102 +#endif
103 +
104 +#endif // RAPIDJSON_FILESTREAM_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_FWD_H_
16 +#define RAPIDJSON_FWD_H_
17 +
18 +#include "rapidjson.h"
19 +
20 +RAPIDJSON_NAMESPACE_BEGIN
21 +
22 +// encodings.h
23 +
24 +template<typename CharType> struct UTF8;
25 +template<typename CharType> struct UTF16;
26 +template<typename CharType> struct UTF16BE;
27 +template<typename CharType> struct UTF16LE;
28 +template<typename CharType> struct UTF32;
29 +template<typename CharType> struct UTF32BE;
30 +template<typename CharType> struct UTF32LE;
31 +template<typename CharType> struct ASCII;
32 +template<typename CharType> struct AutoUTF;
33 +
34 +template<typename SourceEncoding, typename TargetEncoding>
35 +struct Transcoder;
36 +
37 +// allocators.h
38 +
39 +class CrtAllocator;
40 +
41 +template <typename BaseAllocator>
42 +class MemoryPoolAllocator;
43 +
44 +// stream.h
45 +
46 +template <typename Encoding>
47 +struct GenericStringStream;
48 +
49 +typedef GenericStringStream<UTF8<char> > StringStream;
50 +
51 +template <typename Encoding>
52 +struct GenericInsituStringStream;
53 +
54 +typedef GenericInsituStringStream<UTF8<char> > InsituStringStream;
55 +
56 +// stringbuffer.h
57 +
58 +template <typename Encoding, typename Allocator>
59 +class GenericStringBuffer;
60 +
61 +typedef GenericStringBuffer<UTF8<char>, CrtAllocator> StringBuffer;
62 +
63 +// filereadstream.h
64 +
65 +class FileReadStream;
66 +
67 +// filewritestream.h
68 +
69 +class FileWriteStream;
70 +
71 +// memorybuffer.h
72 +
73 +template <typename Allocator>
74 +struct GenericMemoryBuffer;
75 +
76 +typedef GenericMemoryBuffer<CrtAllocator> MemoryBuffer;
77 +
78 +// memorystream.h
79 +
80 +struct MemoryStream;
81 +
82 +// reader.h
83 +
84 +template<typename Encoding, typename Derived>
85 +struct BaseReaderHandler;
86 +
87 +template <typename SourceEncoding, typename TargetEncoding, typename StackAllocator>
88 +class GenericReader;
89 +
90 +typedef GenericReader<UTF8<char>, UTF8<char>, CrtAllocator> Reader;
91 +
92 +// writer.h
93 +
94 +template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
95 +class Writer;
96 +
97 +// prettywriter.h
98 +
99 +template<typename OutputStream, typename SourceEncoding, typename TargetEncoding, typename StackAllocator, unsigned writeFlags>
100 +class PrettyWriter;
101 +
102 +// document.h
103 +
104 +template <typename Encoding, typename Allocator>
105 +struct GenericMember;
106 +
107 +template <bool Const, typename Encoding, typename Allocator>
108 +class GenericMemberIterator;
109 +
110 +template<typename CharType>
111 +struct GenericStringRef;
112 +
113 +template <typename Encoding, typename Allocator>
114 +class GenericValue;
115 +
116 +typedef GenericValue<UTF8<char>, MemoryPoolAllocator<CrtAllocator> > Value;
117 +
118 +template <typename Encoding, typename Allocator, typename StackAllocator>
119 +class GenericDocument;
120 +
121 +typedef GenericDocument<UTF8<char>, MemoryPoolAllocator<CrtAllocator>, CrtAllocator> Document;
122 +
123 +// pointer.h
124 +
125 +template <typename ValueType, typename Allocator>
126 +class GenericPointer;
127 +
128 +typedef GenericPointer<Value, CrtAllocator> Pointer;
129 +
130 +// schema.h
131 +
132 +template <typename SchemaDocumentType>
133 +class IGenericRemoteSchemaDocumentProvider;
134 +
135 +template <typename ValueT, typename Allocator>
136 +class GenericSchemaDocument;
137 +
138 +typedef GenericSchemaDocument<Value, CrtAllocator> SchemaDocument;
139 +typedef IGenericRemoteSchemaDocumentProvider<SchemaDocument> IRemoteSchemaDocumentProvider;
140 +
141 +template <
142 + typename SchemaDocumentType,
143 + typename OutputHandler,
144 + typename StateAllocator>
145 +class GenericSchemaValidator;
146 +
147 +typedef GenericSchemaValidator<SchemaDocument, BaseReaderHandler<UTF8<char>, void>, CrtAllocator> SchemaValidator;
148 +
149 +RAPIDJSON_NAMESPACE_END
150 +
151 +#endif // RAPIDJSON_RAPIDJSONFWD_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_BIGINTEGER_H_
16 +#define RAPIDJSON_BIGINTEGER_H_
17 +
18 +#include "../rapidjson.h"
19 +
20 +#if defined(_MSC_VER) && defined(_M_AMD64)
21 +#include <intrin.h> // for _umul128
22 +#pragma intrinsic(_umul128)
23 +#endif
24 +
25 +RAPIDJSON_NAMESPACE_BEGIN
26 +namespace internal {
27 +
28 +class BigInteger {
29 +public:
30 + typedef uint64_t Type;
31 +
32 + BigInteger(const BigInteger& rhs) : count_(rhs.count_) {
33 + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
34 + }
35 +
36 + explicit BigInteger(uint64_t u) : count_(1) {
37 + digits_[0] = u;
38 + }
39 +
40 + BigInteger(const char* decimals, size_t length) : count_(1) {
41 + RAPIDJSON_ASSERT(length > 0);
42 + digits_[0] = 0;
43 + size_t i = 0;
44 + const size_t kMaxDigitPerIteration = 19; // 2^64 = 18446744073709551616 > 10^19
45 + while (length >= kMaxDigitPerIteration) {
46 + AppendDecimal64(decimals + i, decimals + i + kMaxDigitPerIteration);
47 + length -= kMaxDigitPerIteration;
48 + i += kMaxDigitPerIteration;
49 + }
50 +
51 + if (length > 0)
52 + AppendDecimal64(decimals + i, decimals + i + length);
53 + }
54 +
55 + BigInteger& operator=(const BigInteger &rhs)
56 + {
57 + if (this != &rhs) {
58 + count_ = rhs.count_;
59 + std::memcpy(digits_, rhs.digits_, count_ * sizeof(Type));
60 + }
61 + return *this;
62 + }
63 +
64 + BigInteger& operator=(uint64_t u) {
65 + digits_[0] = u;
66 + count_ = 1;
67 + return *this;
68 + }
69 +
70 + BigInteger& operator+=(uint64_t u) {
71 + Type backup = digits_[0];
72 + digits_[0] += u;
73 + for (size_t i = 0; i < count_ - 1; i++) {
74 + if (digits_[i] >= backup)
75 + return *this; // no carry
76 + backup = digits_[i + 1];
77 + digits_[i + 1] += 1;
78 + }
79 +
80 + // Last carry
81 + if (digits_[count_ - 1] < backup)
82 + PushBack(1);
83 +
84 + return *this;
85 + }
86 +
87 + BigInteger& operator*=(uint64_t u) {
88 + if (u == 0) return *this = 0;
89 + if (u == 1) return *this;
90 + if (*this == 1) return *this = u;
91 +
92 + uint64_t k = 0;
93 + for (size_t i = 0; i < count_; i++) {
94 + uint64_t hi;
95 + digits_[i] = MulAdd64(digits_[i], u, k, &hi);
96 + k = hi;
97 + }
98 +
99 + if (k > 0)
100 + PushBack(k);
101 +
102 + return *this;
103 + }
104 +
105 + BigInteger& operator*=(uint32_t u) {
106 + if (u == 0) return *this = 0;
107 + if (u == 1) return *this;
108 + if (*this == 1) return *this = u;
109 +
110 + uint64_t k = 0;
111 + for (size_t i = 0; i < count_; i++) {
112 + const uint64_t c = digits_[i] >> 32;
113 + const uint64_t d = digits_[i] & 0xFFFFFFFF;
114 + const uint64_t uc = u * c;
115 + const uint64_t ud = u * d;
116 + const uint64_t p0 = ud + k;
117 + const uint64_t p1 = uc + (p0 >> 32);
118 + digits_[i] = (p0 & 0xFFFFFFFF) | (p1 << 32);
119 + k = p1 >> 32;
120 + }
121 +
122 + if (k > 0)
123 + PushBack(k);
124 +
125 + return *this;
126 + }
127 +
128 + BigInteger& operator<<=(size_t shift) {
129 + if (IsZero() || shift == 0) return *this;
130 +
131 + size_t offset = shift / kTypeBit;
132 + size_t interShift = shift % kTypeBit;
133 + RAPIDJSON_ASSERT(count_ + offset <= kCapacity);
134 +
135 + if (interShift == 0) {
136 + std::memmove(&digits_[count_ - 1 + offset], &digits_[count_ - 1], count_ * sizeof(Type));
137 + count_ += offset;
138 + }
139 + else {
140 + digits_[count_] = 0;
141 + for (size_t i = count_; i > 0; i--)
142 + digits_[i + offset] = (digits_[i] << interShift) | (digits_[i - 1] >> (kTypeBit - interShift));
143 + digits_[offset] = digits_[0] << interShift;
144 + count_ += offset;
145 + if (digits_[count_])
146 + count_++;
147 + }
148 +
149 + std::memset(digits_, 0, offset * sizeof(Type));
150 +
151 + return *this;
152 + }
153 +
154 + bool operator==(const BigInteger& rhs) const {
155 + return count_ == rhs.count_ && std::memcmp(digits_, rhs.digits_, count_ * sizeof(Type)) == 0;
156 + }
157 +
158 + bool operator==(const Type rhs) const {
159 + return count_ == 1 && digits_[0] == rhs;
160 + }
161 +
162 + BigInteger& MultiplyPow5(unsigned exp) {
163 + static const uint32_t kPow5[12] = {
164 + 5,
165 + 5 * 5,
166 + 5 * 5 * 5,
167 + 5 * 5 * 5 * 5,
168 + 5 * 5 * 5 * 5 * 5,
169 + 5 * 5 * 5 * 5 * 5 * 5,
170 + 5 * 5 * 5 * 5 * 5 * 5 * 5,
171 + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
172 + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
173 + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
174 + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
175 + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
176 + };
177 + if (exp == 0) return *this;
178 + for (; exp >= 27; exp -= 27) *this *= RAPIDJSON_UINT64_C2(0X6765C793, 0XFA10079D); // 5^27
179 + for (; exp >= 13; exp -= 13) *this *= static_cast<uint32_t>(1220703125u); // 5^13
180 + if (exp > 0) *this *= kPow5[exp - 1];
181 + return *this;
182 + }
183 +
184 + // Compute absolute difference of this and rhs.
185 + // Assume this != rhs
186 + bool Difference(const BigInteger& rhs, BigInteger* out) const {
187 + int cmp = Compare(rhs);
188 + RAPIDJSON_ASSERT(cmp != 0);
189 + const BigInteger *a, *b; // Makes a > b
190 + bool ret;
191 + if (cmp < 0) { a = &rhs; b = this; ret = true; }
192 + else { a = this; b = &rhs; ret = false; }
193 +
194 + Type borrow = 0;
195 + for (size_t i = 0; i < a->count_; i++) {
196 + Type d = a->digits_[i] - borrow;
197 + if (i < b->count_)
198 + d -= b->digits_[i];
199 + borrow = (d > a->digits_[i]) ? 1 : 0;
200 + out->digits_[i] = d;
201 + if (d != 0)
202 + out->count_ = i + 1;
203 + }
204 +
205 + return ret;
206 + }
207 +
208 + int Compare(const BigInteger& rhs) const {
209 + if (count_ != rhs.count_)
210 + return count_ < rhs.count_ ? -1 : 1;
211 +
212 + for (size_t i = count_; i-- > 0;)
213 + if (digits_[i] != rhs.digits_[i])
214 + return digits_[i] < rhs.digits_[i] ? -1 : 1;
215 +
216 + return 0;
217 + }
218 +
219 + size_t GetCount() const { return count_; }
220 + Type GetDigit(size_t index) const { RAPIDJSON_ASSERT(index < count_); return digits_[index]; }
221 + bool IsZero() const { return count_ == 1 && digits_[0] == 0; }
222 +
223 +private:
224 + void AppendDecimal64(const char* begin, const char* end) {
225 + uint64_t u = ParseUint64(begin, end);
226 + if (IsZero())
227 + *this = u;
228 + else {
229 + unsigned exp = static_cast<unsigned>(end - begin);
230 + (MultiplyPow5(exp) <<= exp) += u; // *this = *this * 10^exp + u
231 + }
232 + }
233 +
234 + void PushBack(Type digit) {
235 + RAPIDJSON_ASSERT(count_ < kCapacity);
236 + digits_[count_++] = digit;
237 + }
238 +
239 + static uint64_t ParseUint64(const char* begin, const char* end) {
240 + uint64_t r = 0;
241 + for (const char* p = begin; p != end; ++p) {
242 + RAPIDJSON_ASSERT(*p >= '0' && *p <= '9');
243 + r = r * 10u + static_cast<unsigned>(*p - '0');
244 + }
245 + return r;
246 + }
247 +
248 + // Assume a * b + k < 2^128
249 + static uint64_t MulAdd64(uint64_t a, uint64_t b, uint64_t k, uint64_t* outHigh) {
250 +#if defined(_MSC_VER) && defined(_M_AMD64)
251 + uint64_t low = _umul128(a, b, outHigh) + k;
252 + if (low < k)
253 + (*outHigh)++;
254 + return low;
255 +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
256 + __extension__ typedef unsigned __int128 uint128;
257 + uint128 p = static_cast<uint128>(a) * static_cast<uint128>(b);
258 + p += k;
259 + *outHigh = static_cast<uint64_t>(p >> 64);
260 + return static_cast<uint64_t>(p);
261 +#else
262 + const uint64_t a0 = a & 0xFFFFFFFF, a1 = a >> 32, b0 = b & 0xFFFFFFFF, b1 = b >> 32;
263 + uint64_t x0 = a0 * b0, x1 = a0 * b1, x2 = a1 * b0, x3 = a1 * b1;
264 + x1 += (x0 >> 32); // can't give carry
265 + x1 += x2;
266 + if (x1 < x2)
267 + x3 += (static_cast<uint64_t>(1) << 32);
268 + uint64_t lo = (x1 << 32) + (x0 & 0xFFFFFFFF);
269 + uint64_t hi = x3 + (x1 >> 32);
270 +
271 + lo += k;
272 + if (lo < k)
273 + hi++;
274 + *outHigh = hi;
275 + return lo;
276 +#endif
277 + }
278 +
279 + static const size_t kBitCount = 3328; // 64bit * 54 > 10^1000
280 + static const size_t kCapacity = kBitCount / sizeof(Type);
281 + static const size_t kTypeBit = sizeof(Type) * 8;
282 +
283 + Type digits_[kCapacity];
284 + size_t count_;
285 +};
286 +
287 +} // namespace internal
288 +RAPIDJSON_NAMESPACE_END
289 +
290 +#endif // RAPIDJSON_BIGINTEGER_H_
This diff is collapsed. Click to expand it.
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +// This is a C++ header-only implementation of Grisu2 algorithm from the publication:
16 +// Loitsch, Florian. "Printing floating-point numbers quickly and accurately with
17 +// integers." ACM Sigplan Notices 45.6 (2010): 233-243.
18 +
19 +#ifndef RAPIDJSON_DTOA_
20 +#define RAPIDJSON_DTOA_
21 +
22 +#include "itoa.h" // GetDigitsLut()
23 +#include "diyfp.h"
24 +#include "ieee754.h"
25 +
26 +RAPIDJSON_NAMESPACE_BEGIN
27 +namespace internal {
28 +
29 +#ifdef __GNUC__
30 +RAPIDJSON_DIAG_PUSH
31 +RAPIDJSON_DIAG_OFF(effc++)
32 +RAPIDJSON_DIAG_OFF(array-bounds) // some gcc versions generate wrong warnings https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59124
33 +#endif
34 +
35 +inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
36 + while (rest < wp_w && delta - rest >= ten_kappa &&
37 + (rest + ten_kappa < wp_w || /// closer
38 + wp_w - rest > rest + ten_kappa - wp_w)) {
39 + buffer[len - 1]--;
40 + rest += ten_kappa;
41 + }
42 +}
43 +
44 +inline int CountDecimalDigit32(uint32_t n) {
45 + // Simple pure C++ implementation was faster than __builtin_clz version in this situation.
46 + if (n < 10) return 1;
47 + if (n < 100) return 2;
48 + if (n < 1000) return 3;
49 + if (n < 10000) return 4;
50 + if (n < 100000) return 5;
51 + if (n < 1000000) return 6;
52 + if (n < 10000000) return 7;
53 + if (n < 100000000) return 8;
54 + // Will not reach 10 digits in DigitGen()
55 + //if (n < 1000000000) return 9;
56 + //return 10;
57 + return 9;
58 +}
59 +
60 +inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
61 + static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
62 + const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
63 + const DiyFp wp_w = Mp - W;
64 + uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
65 + uint64_t p2 = Mp.f & (one.f - 1);
66 + int kappa = CountDecimalDigit32(p1); // kappa in [0, 9]
67 + *len = 0;
68 +
69 + while (kappa > 0) {
70 + uint32_t d = 0;
71 + switch (kappa) {
72 + case 9: d = p1 / 100000000; p1 %= 100000000; break;
73 + case 8: d = p1 / 10000000; p1 %= 10000000; break;
74 + case 7: d = p1 / 1000000; p1 %= 1000000; break;
75 + case 6: d = p1 / 100000; p1 %= 100000; break;
76 + case 5: d = p1 / 10000; p1 %= 10000; break;
77 + case 4: d = p1 / 1000; p1 %= 1000; break;
78 + case 3: d = p1 / 100; p1 %= 100; break;
79 + case 2: d = p1 / 10; p1 %= 10; break;
80 + case 1: d = p1; p1 = 0; break;
81 + default:;
82 + }
83 + if (d || *len)
84 + buffer[(*len)++] = static_cast<char>('0' + static_cast<char>(d));
85 + kappa--;
86 + uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
87 + if (tmp <= delta) {
88 + *K += kappa;
89 + GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
90 + return;
91 + }
92 + }
93 +
94 + // kappa = 0
95 + for (;;) {
96 + p2 *= 10;
97 + delta *= 10;
98 + char d = static_cast<char>(p2 >> -one.e);
99 + if (d || *len)
100 + buffer[(*len)++] = static_cast<char>('0' + d);
101 + p2 &= one.f - 1;
102 + kappa--;
103 + if (p2 < delta) {
104 + *K += kappa;
105 + int index = -kappa;
106 + GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * (index < 9 ? kPow10[index] : 0));
107 + return;
108 + }
109 + }
110 +}
111 +
112 +inline void Grisu2(double value, char* buffer, int* length, int* K) {
113 + const DiyFp v(value);
114 + DiyFp w_m, w_p;
115 + v.NormalizedBoundaries(&w_m, &w_p);
116 +
117 + const DiyFp c_mk = GetCachedPower(w_p.e, K);
118 + const DiyFp W = v.Normalize() * c_mk;
119 + DiyFp Wp = w_p * c_mk;
120 + DiyFp Wm = w_m * c_mk;
121 + Wm.f++;
122 + Wp.f--;
123 + DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
124 +}
125 +
126 +inline char* WriteExponent(int K, char* buffer) {
127 + if (K < 0) {
128 + *buffer++ = '-';
129 + K = -K;
130 + }
131 +
132 + if (K >= 100) {
133 + *buffer++ = static_cast<char>('0' + static_cast<char>(K / 100));
134 + K %= 100;
135 + const char* d = GetDigitsLut() + K * 2;
136 + *buffer++ = d[0];
137 + *buffer++ = d[1];
138 + }
139 + else if (K >= 10) {
140 + const char* d = GetDigitsLut() + K * 2;
141 + *buffer++ = d[0];
142 + *buffer++ = d[1];
143 + }
144 + else
145 + *buffer++ = static_cast<char>('0' + static_cast<char>(K));
146 +
147 + return buffer;
148 +}
149 +
150 +inline char* Prettify(char* buffer, int length, int k, int maxDecimalPlaces) {
151 + const int kk = length + k; // 10^(kk-1) <= v < 10^kk
152 +
153 + if (0 <= k && kk <= 21) {
154 + // 1234e7 -> 12340000000
155 + for (int i = length; i < kk; i++)
156 + buffer[i] = '0';
157 + buffer[kk] = '.';
158 + buffer[kk + 1] = '0';
159 + return &buffer[kk + 2];
160 + }
161 + else if (0 < kk && kk <= 21) {
162 + // 1234e-2 -> 12.34
163 + std::memmove(&buffer[kk + 1], &buffer[kk], static_cast<size_t>(length - kk));
164 + buffer[kk] = '.';
165 + if (0 > k + maxDecimalPlaces) {
166 + // When maxDecimalPlaces = 2, 1.2345 -> 1.23, 1.102 -> 1.1
167 + // Remove extra trailing zeros (at least one) after truncation.
168 + for (int i = kk + maxDecimalPlaces; i > kk + 1; i--)
169 + if (buffer[i] != '0')
170 + return &buffer[i + 1];
171 + return &buffer[kk + 2]; // Reserve one zero
172 + }
173 + else
174 + return &buffer[length + 1];
175 + }
176 + else if (-6 < kk && kk <= 0) {
177 + // 1234e-6 -> 0.001234
178 + const int offset = 2 - kk;
179 + std::memmove(&buffer[offset], &buffer[0], static_cast<size_t>(length));
180 + buffer[0] = '0';
181 + buffer[1] = '.';
182 + for (int i = 2; i < offset; i++)
183 + buffer[i] = '0';
184 + if (length - kk > maxDecimalPlaces) {
185 + // When maxDecimalPlaces = 2, 0.123 -> 0.12, 0.102 -> 0.1
186 + // Remove extra trailing zeros (at least one) after truncation.
187 + for (int i = maxDecimalPlaces + 1; i > 2; i--)
188 + if (buffer[i] != '0')
189 + return &buffer[i + 1];
190 + return &buffer[3]; // Reserve one zero
191 + }
192 + else
193 + return &buffer[length + offset];
194 + }
195 + else if (kk < -maxDecimalPlaces) {
196 + // Truncate to zero
197 + buffer[0] = '0';
198 + buffer[1] = '.';
199 + buffer[2] = '0';
200 + return &buffer[3];
201 + }
202 + else if (length == 1) {
203 + // 1e30
204 + buffer[1] = 'e';
205 + return WriteExponent(kk - 1, &buffer[2]);
206 + }
207 + else {
208 + // 1234e30 -> 1.234e33
209 + std::memmove(&buffer[2], &buffer[1], static_cast<size_t>(length - 1));
210 + buffer[1] = '.';
211 + buffer[length + 1] = 'e';
212 + return WriteExponent(kk - 1, &buffer[0 + length + 2]);
213 + }
214 +}
215 +
216 +inline char* dtoa(double value, char* buffer, int maxDecimalPlaces = 324) {
217 + RAPIDJSON_ASSERT(maxDecimalPlaces >= 1);
218 + Double d(value);
219 + if (d.IsZero()) {
220 + if (d.Sign())
221 + *buffer++ = '-'; // -0.0, Issue #289
222 + buffer[0] = '0';
223 + buffer[1] = '.';
224 + buffer[2] = '0';
225 + return &buffer[3];
226 + }
227 + else {
228 + if (value < 0) {
229 + *buffer++ = '-';
230 + value = -value;
231 + }
232 + int length, K;
233 + Grisu2(value, buffer, &length, &K);
234 + return Prettify(buffer, length, K, maxDecimalPlaces);
235 + }
236 +}
237 +
238 +#ifdef __GNUC__
239 +RAPIDJSON_DIAG_POP
240 +#endif
241 +
242 +} // namespace internal
243 +RAPIDJSON_NAMESPACE_END
244 +
245 +#endif // RAPIDJSON_DTOA_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_IEEE754_
16 +#define RAPIDJSON_IEEE754_
17 +
18 +#include "../rapidjson.h"
19 +
20 +RAPIDJSON_NAMESPACE_BEGIN
21 +namespace internal {
22 +
23 +class Double {
24 +public:
25 + Double() {}
26 + Double(double d) : d_(d) {}
27 + Double(uint64_t u) : u_(u) {}
28 +
29 + double Value() const { return d_; }
30 + uint64_t Uint64Value() const { return u_; }
31 +
32 + double NextPositiveDouble() const {
33 + RAPIDJSON_ASSERT(!Sign());
34 + return Double(u_ + 1).Value();
35 + }
36 +
37 + bool Sign() const { return (u_ & kSignMask) != 0; }
38 + uint64_t Significand() const { return u_ & kSignificandMask; }
39 + int Exponent() const { return static_cast<int>(((u_ & kExponentMask) >> kSignificandSize) - kExponentBias); }
40 +
41 + bool IsNan() const { return (u_ & kExponentMask) == kExponentMask && Significand() != 0; }
42 + bool IsInf() const { return (u_ & kExponentMask) == kExponentMask && Significand() == 0; }
43 + bool IsNanOrInf() const { return (u_ & kExponentMask) == kExponentMask; }
44 + bool IsNormal() const { return (u_ & kExponentMask) != 0 || Significand() == 0; }
45 + bool IsZero() const { return (u_ & (kExponentMask | kSignificandMask)) == 0; }
46 +
47 + uint64_t IntegerSignificand() const { return IsNormal() ? Significand() | kHiddenBit : Significand(); }
48 + int IntegerExponent() const { return (IsNormal() ? Exponent() : kDenormalExponent) - kSignificandSize; }
49 + uint64_t ToBias() const { return (u_ & kSignMask) ? ~u_ + 1 : u_ | kSignMask; }
50 +
51 + static int EffectiveSignificandSize(int order) {
52 + if (order >= -1021)
53 + return 53;
54 + else if (order <= -1074)
55 + return 0;
56 + else
57 + return order + 1074;
58 + }
59 +
60 +private:
61 + static const int kSignificandSize = 52;
62 + static const int kExponentBias = 0x3FF;
63 + static const int kDenormalExponent = 1 - kExponentBias;
64 + static const uint64_t kSignMask = RAPIDJSON_UINT64_C2(0x80000000, 0x00000000);
65 + static const uint64_t kExponentMask = RAPIDJSON_UINT64_C2(0x7FF00000, 0x00000000);
66 + static const uint64_t kSignificandMask = RAPIDJSON_UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
67 + static const uint64_t kHiddenBit = RAPIDJSON_UINT64_C2(0x00100000, 0x00000000);
68 +
69 + union {
70 + double d_;
71 + uint64_t u_;
72 + };
73 +};
74 +
75 +} // namespace internal
76 +RAPIDJSON_NAMESPACE_END
77 +
78 +#endif // RAPIDJSON_IEEE754_
This diff is collapsed. Click to expand it.
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_INTERNAL_META_H_
16 +#define RAPIDJSON_INTERNAL_META_H_
17 +
18 +#include "../rapidjson.h"
19 +
20 +#ifdef __GNUC__
21 +RAPIDJSON_DIAG_PUSH
22 +RAPIDJSON_DIAG_OFF(effc++)
23 +#endif
24 +#if defined(_MSC_VER)
25 +RAPIDJSON_DIAG_PUSH
26 +RAPIDJSON_DIAG_OFF(6334)
27 +#endif
28 +
29 +#if RAPIDJSON_HAS_CXX11_TYPETRAITS
30 +#include <type_traits>
31 +#endif
32 +
33 +//@cond RAPIDJSON_INTERNAL
34 +RAPIDJSON_NAMESPACE_BEGIN
35 +namespace internal {
36 +
37 +// Helper to wrap/convert arbitrary types to void, useful for arbitrary type matching
38 +template <typename T> struct Void { typedef void Type; };
39 +
40 +///////////////////////////////////////////////////////////////////////////////
41 +// BoolType, TrueType, FalseType
42 +//
43 +template <bool Cond> struct BoolType {
44 + static const bool Value = Cond;
45 + typedef BoolType Type;
46 +};
47 +typedef BoolType<true> TrueType;
48 +typedef BoolType<false> FalseType;
49 +
50 +
51 +///////////////////////////////////////////////////////////////////////////////
52 +// SelectIf, BoolExpr, NotExpr, AndExpr, OrExpr
53 +//
54 +
55 +template <bool C> struct SelectIfImpl { template <typename T1, typename T2> struct Apply { typedef T1 Type; }; };
56 +template <> struct SelectIfImpl<false> { template <typename T1, typename T2> struct Apply { typedef T2 Type; }; };
57 +template <bool C, typename T1, typename T2> struct SelectIfCond : SelectIfImpl<C>::template Apply<T1,T2> {};
58 +template <typename C, typename T1, typename T2> struct SelectIf : SelectIfCond<C::Value, T1, T2> {};
59 +
60 +template <bool Cond1, bool Cond2> struct AndExprCond : FalseType {};
61 +template <> struct AndExprCond<true, true> : TrueType {};
62 +template <bool Cond1, bool Cond2> struct OrExprCond : TrueType {};
63 +template <> struct OrExprCond<false, false> : FalseType {};
64 +
65 +template <typename C> struct BoolExpr : SelectIf<C,TrueType,FalseType>::Type {};
66 +template <typename C> struct NotExpr : SelectIf<C,FalseType,TrueType>::Type {};
67 +template <typename C1, typename C2> struct AndExpr : AndExprCond<C1::Value, C2::Value>::Type {};
68 +template <typename C1, typename C2> struct OrExpr : OrExprCond<C1::Value, C2::Value>::Type {};
69 +
70 +
71 +///////////////////////////////////////////////////////////////////////////////
72 +// AddConst, MaybeAddConst, RemoveConst
73 +template <typename T> struct AddConst { typedef const T Type; };
74 +template <bool Constify, typename T> struct MaybeAddConst : SelectIfCond<Constify, const T, T> {};
75 +template <typename T> struct RemoveConst { typedef T Type; };
76 +template <typename T> struct RemoveConst<const T> { typedef T Type; };
77 +
78 +
79 +///////////////////////////////////////////////////////////////////////////////
80 +// IsSame, IsConst, IsMoreConst, IsPointer
81 +//
82 +template <typename T, typename U> struct IsSame : FalseType {};
83 +template <typename T> struct IsSame<T, T> : TrueType {};
84 +
85 +template <typename T> struct IsConst : FalseType {};
86 +template <typename T> struct IsConst<const T> : TrueType {};
87 +
88 +template <typename CT, typename T>
89 +struct IsMoreConst
90 + : AndExpr<IsSame<typename RemoveConst<CT>::Type, typename RemoveConst<T>::Type>,
91 + BoolType<IsConst<CT>::Value >= IsConst<T>::Value> >::Type {};
92 +
93 +template <typename T> struct IsPointer : FalseType {};
94 +template <typename T> struct IsPointer<T*> : TrueType {};
95 +
96 +///////////////////////////////////////////////////////////////////////////////
97 +// IsBaseOf
98 +//
99 +#if RAPIDJSON_HAS_CXX11_TYPETRAITS
100 +
101 +template <typename B, typename D> struct IsBaseOf
102 + : BoolType< ::std::is_base_of<B,D>::value> {};
103 +
104 +#else // simplified version adopted from Boost
105 +
106 +template<typename B, typename D> struct IsBaseOfImpl {
107 + RAPIDJSON_STATIC_ASSERT(sizeof(B) != 0);
108 + RAPIDJSON_STATIC_ASSERT(sizeof(D) != 0);
109 +
110 + typedef char (&Yes)[1];
111 + typedef char (&No) [2];
112 +
113 + template <typename T>
114 + static Yes Check(const D*, T);
115 + static No Check(const B*, int);
116 +
117 + struct Host {
118 + operator const B*() const;
119 + operator const D*();
120 + };
121 +
122 + enum { Value = (sizeof(Check(Host(), 0)) == sizeof(Yes)) };
123 +};
124 +
125 +template <typename B, typename D> struct IsBaseOf
126 + : OrExpr<IsSame<B, D>, BoolExpr<IsBaseOfImpl<B, D> > >::Type {};
127 +
128 +#endif // RAPIDJSON_HAS_CXX11_TYPETRAITS
129 +
130 +
131 +//////////////////////////////////////////////////////////////////////////
132 +// EnableIf / DisableIf
133 +//
134 +template <bool Condition, typename T = void> struct EnableIfCond { typedef T Type; };
135 +template <typename T> struct EnableIfCond<false, T> { /* empty */ };
136 +
137 +template <bool Condition, typename T = void> struct DisableIfCond { typedef T Type; };
138 +template <typename T> struct DisableIfCond<true, T> { /* empty */ };
139 +
140 +template <typename Condition, typename T = void>
141 +struct EnableIf : EnableIfCond<Condition::Value, T> {};
142 +
143 +template <typename Condition, typename T = void>
144 +struct DisableIf : DisableIfCond<Condition::Value, T> {};
145 +
146 +// SFINAE helpers
147 +struct SfinaeTag {};
148 +template <typename T> struct RemoveSfinaeTag;
149 +template <typename T> struct RemoveSfinaeTag<SfinaeTag&(*)(T)> { typedef T Type; };
150 +
151 +#define RAPIDJSON_REMOVEFPTR_(type) \
152 + typename ::RAPIDJSON_NAMESPACE::internal::RemoveSfinaeTag \
153 + < ::RAPIDJSON_NAMESPACE::internal::SfinaeTag&(*) type>::Type
154 +
155 +#define RAPIDJSON_ENABLEIF(cond) \
156 + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
157 + <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
158 +
159 +#define RAPIDJSON_DISABLEIF(cond) \
160 + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
161 + <RAPIDJSON_REMOVEFPTR_(cond)>::Type * = NULL
162 +
163 +#define RAPIDJSON_ENABLEIF_RETURN(cond,returntype) \
164 + typename ::RAPIDJSON_NAMESPACE::internal::EnableIf \
165 + <RAPIDJSON_REMOVEFPTR_(cond), \
166 + RAPIDJSON_REMOVEFPTR_(returntype)>::Type
167 +
168 +#define RAPIDJSON_DISABLEIF_RETURN(cond,returntype) \
169 + typename ::RAPIDJSON_NAMESPACE::internal::DisableIf \
170 + <RAPIDJSON_REMOVEFPTR_(cond), \
171 + RAPIDJSON_REMOVEFPTR_(returntype)>::Type
172 +
173 +} // namespace internal
174 +RAPIDJSON_NAMESPACE_END
175 +//@endcond
176 +
177 +#if defined(__GNUC__) || defined(_MSC_VER)
178 +RAPIDJSON_DIAG_POP
179 +#endif
180 +
181 +#endif // RAPIDJSON_INTERNAL_META_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_POW10_
16 +#define RAPIDJSON_POW10_
17 +
18 +#include "../rapidjson.h"
19 +
20 +RAPIDJSON_NAMESPACE_BEGIN
21 +namespace internal {
22 +
23 +//! Computes integer powers of 10 in double (10.0^n).
24 +/*! This function uses lookup table for fast and accurate results.
25 + \param n non-negative exponent. Must <= 308.
26 + \return 10.0^n
27 +*/
28 +inline double Pow10(int n) {
29 + static const double e[] = { // 1e-0...1e308: 309 * 8 bytes = 2472 bytes
30 + 1e+0,
31 + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20,
32 + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40,
33 + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60,
34 + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80,
35 + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100,
36 + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120,
37 + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140,
38 + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160,
39 + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180,
40 + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200,
41 + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220,
42 + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240,
43 + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260,
44 + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280,
45 + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300,
46 + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308
47 + };
48 + RAPIDJSON_ASSERT(n >= 0 && n <= 308);
49 + return e[n];
50 +}
51 +
52 +} // namespace internal
53 +RAPIDJSON_NAMESPACE_END
54 +
55 +#endif // RAPIDJSON_POW10_
This diff is collapsed. Click to expand it.
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_INTERNAL_STACK_H_
16 +#define RAPIDJSON_INTERNAL_STACK_H_
17 +
18 +#include "../allocators.h"
19 +#include "swap.h"
20 +
21 +#if defined(__clang__)
22 +RAPIDJSON_DIAG_PUSH
23 +RAPIDJSON_DIAG_OFF(c++98-compat)
24 +#endif
25 +
26 +RAPIDJSON_NAMESPACE_BEGIN
27 +namespace internal {
28 +
29 +///////////////////////////////////////////////////////////////////////////////
30 +// Stack
31 +
32 +//! A type-unsafe stack for storing different types of data.
33 +/*! \tparam Allocator Allocator for allocating stack memory.
34 +*/
35 +template <typename Allocator>
36 +class Stack {
37 +public:
38 + // Optimization note: Do not allocate memory for stack_ in constructor.
39 + // Do it lazily when first Push() -> Expand() -> Resize().
40 + Stack(Allocator* allocator, size_t stackCapacity) : allocator_(allocator), ownAllocator_(0), stack_(0), stackTop_(0), stackEnd_(0), initialCapacity_(stackCapacity) {
41 + }
42 +
43 +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
44 + Stack(Stack&& rhs)
45 + : allocator_(rhs.allocator_),
46 + ownAllocator_(rhs.ownAllocator_),
47 + stack_(rhs.stack_),
48 + stackTop_(rhs.stackTop_),
49 + stackEnd_(rhs.stackEnd_),
50 + initialCapacity_(rhs.initialCapacity_)
51 + {
52 + rhs.allocator_ = 0;
53 + rhs.ownAllocator_ = 0;
54 + rhs.stack_ = 0;
55 + rhs.stackTop_ = 0;
56 + rhs.stackEnd_ = 0;
57 + rhs.initialCapacity_ = 0;
58 + }
59 +#endif
60 +
61 + ~Stack() {
62 + Destroy();
63 + }
64 +
65 +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
66 + Stack& operator=(Stack&& rhs) {
67 + if (&rhs != this)
68 + {
69 + Destroy();
70 +
71 + allocator_ = rhs.allocator_;
72 + ownAllocator_ = rhs.ownAllocator_;
73 + stack_ = rhs.stack_;
74 + stackTop_ = rhs.stackTop_;
75 + stackEnd_ = rhs.stackEnd_;
76 + initialCapacity_ = rhs.initialCapacity_;
77 +
78 + rhs.allocator_ = 0;
79 + rhs.ownAllocator_ = 0;
80 + rhs.stack_ = 0;
81 + rhs.stackTop_ = 0;
82 + rhs.stackEnd_ = 0;
83 + rhs.initialCapacity_ = 0;
84 + }
85 + return *this;
86 + }
87 +#endif
88 +
89 + void Swap(Stack& rhs) RAPIDJSON_NOEXCEPT {
90 + internal::Swap(allocator_, rhs.allocator_);
91 + internal::Swap(ownAllocator_, rhs.ownAllocator_);
92 + internal::Swap(stack_, rhs.stack_);
93 + internal::Swap(stackTop_, rhs.stackTop_);
94 + internal::Swap(stackEnd_, rhs.stackEnd_);
95 + internal::Swap(initialCapacity_, rhs.initialCapacity_);
96 + }
97 +
98 + void Clear() { stackTop_ = stack_; }
99 +
100 + void ShrinkToFit() {
101 + if (Empty()) {
102 + // If the stack is empty, completely deallocate the memory.
103 + Allocator::Free(stack_);
104 + stack_ = 0;
105 + stackTop_ = 0;
106 + stackEnd_ = 0;
107 + }
108 + else
109 + Resize(GetSize());
110 + }
111 +
112 + // Optimization note: try to minimize the size of this function for force inline.
113 + // Expansion is run very infrequently, so it is moved to another (probably non-inline) function.
114 + template<typename T>
115 + RAPIDJSON_FORCEINLINE void Reserve(size_t count = 1) {
116 + // Expand the stack if needed
117 + if (RAPIDJSON_UNLIKELY(stackTop_ + sizeof(T) * count > stackEnd_))
118 + Expand<T>(count);
119 + }
120 +
121 + template<typename T>
122 + RAPIDJSON_FORCEINLINE T* Push(size_t count = 1) {
123 + Reserve<T>(count);
124 + return PushUnsafe<T>(count);
125 + }
126 +
127 + template<typename T>
128 + RAPIDJSON_FORCEINLINE T* PushUnsafe(size_t count = 1) {
129 + RAPIDJSON_ASSERT(stackTop_);
130 + RAPIDJSON_ASSERT(stackTop_ + sizeof(T) * count <= stackEnd_);
131 + T* ret = reinterpret_cast<T*>(stackTop_);
132 + stackTop_ += sizeof(T) * count;
133 + return ret;
134 + }
135 +
136 + template<typename T>
137 + T* Pop(size_t count) {
138 + RAPIDJSON_ASSERT(GetSize() >= count * sizeof(T));
139 + stackTop_ -= count * sizeof(T);
140 + return reinterpret_cast<T*>(stackTop_);
141 + }
142 +
143 + template<typename T>
144 + T* Top() {
145 + RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
146 + return reinterpret_cast<T*>(stackTop_ - sizeof(T));
147 + }
148 +
149 + template<typename T>
150 + const T* Top() const {
151 + RAPIDJSON_ASSERT(GetSize() >= sizeof(T));
152 + return reinterpret_cast<T*>(stackTop_ - sizeof(T));
153 + }
154 +
155 + template<typename T>
156 + T* End() { return reinterpret_cast<T*>(stackTop_); }
157 +
158 + template<typename T>
159 + const T* End() const { return reinterpret_cast<T*>(stackTop_); }
160 +
161 + template<typename T>
162 + T* Bottom() { return reinterpret_cast<T*>(stack_); }
163 +
164 + template<typename T>
165 + const T* Bottom() const { return reinterpret_cast<T*>(stack_); }
166 +
167 + bool HasAllocator() const {
168 + return allocator_ != 0;
169 + }
170 +
171 + Allocator& GetAllocator() {
172 + RAPIDJSON_ASSERT(allocator_);
173 + return *allocator_;
174 + }
175 +
176 + bool Empty() const { return stackTop_ == stack_; }
177 + size_t GetSize() const { return static_cast<size_t>(stackTop_ - stack_); }
178 + size_t GetCapacity() const { return static_cast<size_t>(stackEnd_ - stack_); }
179 +
180 +private:
181 + template<typename T>
182 + void Expand(size_t count) {
183 + // Only expand the capacity if the current stack exists. Otherwise just create a stack with initial capacity.
184 + size_t newCapacity;
185 + if (stack_ == 0) {
186 + if (!allocator_)
187 + ownAllocator_ = allocator_ = RAPIDJSON_NEW(Allocator)();
188 + newCapacity = initialCapacity_;
189 + } else {
190 + newCapacity = GetCapacity();
191 + newCapacity += (newCapacity + 1) / 2;
192 + }
193 + size_t newSize = GetSize() + sizeof(T) * count;
194 + if (newCapacity < newSize)
195 + newCapacity = newSize;
196 +
197 + Resize(newCapacity);
198 + }
199 +
200 + void Resize(size_t newCapacity) {
201 + const size_t size = GetSize(); // Backup the current size
202 + stack_ = static_cast<char*>(allocator_->Realloc(stack_, GetCapacity(), newCapacity));
203 + stackTop_ = stack_ + size;
204 + stackEnd_ = stack_ + newCapacity;
205 + }
206 +
207 + void Destroy() {
208 + Allocator::Free(stack_);
209 + RAPIDJSON_DELETE(ownAllocator_); // Only delete if it is owned by the stack
210 + }
211 +
212 + // Prohibit copy constructor & assignment operator.
213 + Stack(const Stack&);
214 + Stack& operator=(const Stack&);
215 +
216 + Allocator* allocator_;
217 + Allocator* ownAllocator_;
218 + char *stack_;
219 + char *stackTop_;
220 + char *stackEnd_;
221 + size_t initialCapacity_;
222 +};
223 +
224 +} // namespace internal
225 +RAPIDJSON_NAMESPACE_END
226 +
227 +#if defined(__clang__)
228 +RAPIDJSON_DIAG_POP
229 +#endif
230 +
231 +#endif // RAPIDJSON_STACK_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_INTERNAL_STRFUNC_H_
16 +#define RAPIDJSON_INTERNAL_STRFUNC_H_
17 +
18 +#include "../stream.h"
19 +#include <cwchar>
20 +
21 +RAPIDJSON_NAMESPACE_BEGIN
22 +namespace internal {
23 +
24 +//! Custom strlen() which works on different character types.
25 +/*! \tparam Ch Character type (e.g. char, wchar_t, short)
26 + \param s Null-terminated input string.
27 + \return Number of characters in the string.
28 + \note This has the same semantics as strlen(), the return value is not number of Unicode codepoints.
29 +*/
30 +template <typename Ch>
31 +inline SizeType StrLen(const Ch* s) {
32 + RAPIDJSON_ASSERT(s != 0);
33 + const Ch* p = s;
34 + while (*p) ++p;
35 + return SizeType(p - s);
36 +}
37 +
38 +template <>
39 +inline SizeType StrLen(const char* s) {
40 + return SizeType(std::strlen(s));
41 +}
42 +
43 +template <>
44 +inline SizeType StrLen(const wchar_t* s) {
45 + return SizeType(std::wcslen(s));
46 +}
47 +
48 +//! Returns number of code points in a encoded string.
49 +template<typename Encoding>
50 +bool CountStringCodePoint(const typename Encoding::Ch* s, SizeType length, SizeType* outCount) {
51 + RAPIDJSON_ASSERT(s != 0);
52 + RAPIDJSON_ASSERT(outCount != 0);
53 + GenericStringStream<Encoding> is(s);
54 + const typename Encoding::Ch* end = s + length;
55 + SizeType count = 0;
56 + while (is.src_ < end) {
57 + unsigned codepoint;
58 + if (!Encoding::Decode(is, &codepoint))
59 + return false;
60 + count++;
61 + }
62 + *outCount = count;
63 + return true;
64 +}
65 +
66 +} // namespace internal
67 +RAPIDJSON_NAMESPACE_END
68 +
69 +#endif // RAPIDJSON_INTERNAL_STRFUNC_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_STRTOD_
16 +#define RAPIDJSON_STRTOD_
17 +
18 +#include "ieee754.h"
19 +#include "biginteger.h"
20 +#include "diyfp.h"
21 +#include "pow10.h"
22 +
23 +RAPIDJSON_NAMESPACE_BEGIN
24 +namespace internal {
25 +
26 +inline double FastPath(double significand, int exp) {
27 + if (exp < -308)
28 + return 0.0;
29 + else if (exp >= 0)
30 + return significand * internal::Pow10(exp);
31 + else
32 + return significand / internal::Pow10(-exp);
33 +}
34 +
35 +inline double StrtodNormalPrecision(double d, int p) {
36 + if (p < -308) {
37 + // Prevent expSum < -308, making Pow10(p) = 0
38 + d = FastPath(d, -308);
39 + d = FastPath(d, p + 308);
40 + }
41 + else
42 + d = FastPath(d, p);
43 + return d;
44 +}
45 +
46 +template <typename T>
47 +inline T Min3(T a, T b, T c) {
48 + T m = a;
49 + if (m > b) m = b;
50 + if (m > c) m = c;
51 + return m;
52 +}
53 +
54 +inline int CheckWithinHalfULP(double b, const BigInteger& d, int dExp) {
55 + const Double db(b);
56 + const uint64_t bInt = db.IntegerSignificand();
57 + const int bExp = db.IntegerExponent();
58 + const int hExp = bExp - 1;
59 +
60 + int dS_Exp2 = 0, dS_Exp5 = 0, bS_Exp2 = 0, bS_Exp5 = 0, hS_Exp2 = 0, hS_Exp5 = 0;
61 +
62 + // Adjust for decimal exponent
63 + if (dExp >= 0) {
64 + dS_Exp2 += dExp;
65 + dS_Exp5 += dExp;
66 + }
67 + else {
68 + bS_Exp2 -= dExp;
69 + bS_Exp5 -= dExp;
70 + hS_Exp2 -= dExp;
71 + hS_Exp5 -= dExp;
72 + }
73 +
74 + // Adjust for binary exponent
75 + if (bExp >= 0)
76 + bS_Exp2 += bExp;
77 + else {
78 + dS_Exp2 -= bExp;
79 + hS_Exp2 -= bExp;
80 + }
81 +
82 + // Adjust for half ulp exponent
83 + if (hExp >= 0)
84 + hS_Exp2 += hExp;
85 + else {
86 + dS_Exp2 -= hExp;
87 + bS_Exp2 -= hExp;
88 + }
89 +
90 + // Remove common power of two factor from all three scaled values
91 + int common_Exp2 = Min3(dS_Exp2, bS_Exp2, hS_Exp2);
92 + dS_Exp2 -= common_Exp2;
93 + bS_Exp2 -= common_Exp2;
94 + hS_Exp2 -= common_Exp2;
95 +
96 + BigInteger dS = d;
97 + dS.MultiplyPow5(static_cast<unsigned>(dS_Exp5)) <<= static_cast<unsigned>(dS_Exp2);
98 +
99 + BigInteger bS(bInt);
100 + bS.MultiplyPow5(static_cast<unsigned>(bS_Exp5)) <<= static_cast<unsigned>(bS_Exp2);
101 +
102 + BigInteger hS(1);
103 + hS.MultiplyPow5(static_cast<unsigned>(hS_Exp5)) <<= static_cast<unsigned>(hS_Exp2);
104 +
105 + BigInteger delta(0);
106 + dS.Difference(bS, &delta);
107 +
108 + return delta.Compare(hS);
109 +}
110 +
111 +inline bool StrtodFast(double d, int p, double* result) {
112 + // Use fast path for string-to-double conversion if possible
113 + // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
114 + if (p > 22 && p < 22 + 16) {
115 + // Fast Path Cases In Disguise
116 + d *= internal::Pow10(p - 22);
117 + p = 22;
118 + }
119 +
120 + if (p >= -22 && p <= 22 && d <= 9007199254740991.0) { // 2^53 - 1
121 + *result = FastPath(d, p);
122 + return true;
123 + }
124 + else
125 + return false;
126 +}
127 +
128 +// Compute an approximation and see if it is within 1/2 ULP
129 +inline bool StrtodDiyFp(const char* decimals, size_t length, size_t decimalPosition, int exp, double* result) {
130 + uint64_t significand = 0;
131 + size_t i = 0; // 2^64 - 1 = 18446744073709551615, 1844674407370955161 = 0x1999999999999999
132 + for (; i < length; i++) {
133 + if (significand > RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) ||
134 + (significand == RAPIDJSON_UINT64_C2(0x19999999, 0x99999999) && decimals[i] > '5'))
135 + break;
136 + significand = significand * 10u + static_cast<unsigned>(decimals[i] - '0');
137 + }
138 +
139 + if (i < length && decimals[i] >= '5') // Rounding
140 + significand++;
141 +
142 + size_t remaining = length - i;
143 + const int kUlpShift = 3;
144 + const int kUlp = 1 << kUlpShift;
145 + int64_t error = (remaining == 0) ? 0 : kUlp / 2;
146 +
147 + DiyFp v(significand, 0);
148 + v = v.Normalize();
149 + error <<= -v.e;
150 +
151 + const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(i) + exp;
152 +
153 + int actualExp;
154 + DiyFp cachedPower = GetCachedPower10(dExp, &actualExp);
155 + if (actualExp != dExp) {
156 + static const DiyFp kPow10[] = {
157 + DiyFp(RAPIDJSON_UINT64_C2(0xa0000000, 00000000), -60), // 10^1
158 + DiyFp(RAPIDJSON_UINT64_C2(0xc8000000, 00000000), -57), // 10^2
159 + DiyFp(RAPIDJSON_UINT64_C2(0xfa000000, 00000000), -54), // 10^3
160 + DiyFp(RAPIDJSON_UINT64_C2(0x9c400000, 00000000), -50), // 10^4
161 + DiyFp(RAPIDJSON_UINT64_C2(0xc3500000, 00000000), -47), // 10^5
162 + DiyFp(RAPIDJSON_UINT64_C2(0xf4240000, 00000000), -44), // 10^6
163 + DiyFp(RAPIDJSON_UINT64_C2(0x98968000, 00000000), -40) // 10^7
164 + };
165 + int adjustment = dExp - actualExp - 1;
166 + RAPIDJSON_ASSERT(adjustment >= 0 && adjustment < 7);
167 + v = v * kPow10[adjustment];
168 + if (length + static_cast<unsigned>(adjustment)> 19u) // has more digits than decimal digits in 64-bit
169 + error += kUlp / 2;
170 + }
171 +
172 + v = v * cachedPower;
173 +
174 + error += kUlp + (error == 0 ? 0 : 1);
175 +
176 + const int oldExp = v.e;
177 + v = v.Normalize();
178 + error <<= oldExp - v.e;
179 +
180 + const int effectiveSignificandSize = Double::EffectiveSignificandSize(64 + v.e);
181 + int precisionSize = 64 - effectiveSignificandSize;
182 + if (precisionSize + kUlpShift >= 64) {
183 + int scaleExp = (precisionSize + kUlpShift) - 63;
184 + v.f >>= scaleExp;
185 + v.e += scaleExp;
186 + error = (error >> scaleExp) + 1 + kUlp;
187 + precisionSize -= scaleExp;
188 + }
189 +
190 + DiyFp rounded(v.f >> precisionSize, v.e + precisionSize);
191 + const uint64_t precisionBits = (v.f & ((uint64_t(1) << precisionSize) - 1)) * kUlp;
192 + const uint64_t halfWay = (uint64_t(1) << (precisionSize - 1)) * kUlp;
193 + if (precisionBits >= halfWay + static_cast<unsigned>(error)) {
194 + rounded.f++;
195 + if (rounded.f & (DiyFp::kDpHiddenBit << 1)) { // rounding overflows mantissa (issue #340)
196 + rounded.f >>= 1;
197 + rounded.e++;
198 + }
199 + }
200 +
201 + *result = rounded.ToDouble();
202 +
203 + return halfWay - static_cast<unsigned>(error) >= precisionBits || precisionBits >= halfWay + static_cast<unsigned>(error);
204 +}
205 +
206 +inline double StrtodBigInteger(double approx, const char* decimals, size_t length, size_t decimalPosition, int exp) {
207 + const BigInteger dInt(decimals, length);
208 + const int dExp = static_cast<int>(decimalPosition) - static_cast<int>(length) + exp;
209 + Double a(approx);
210 + int cmp = CheckWithinHalfULP(a.Value(), dInt, dExp);
211 + if (cmp < 0)
212 + return a.Value(); // within half ULP
213 + else if (cmp == 0) {
214 + // Round towards even
215 + if (a.Significand() & 1)
216 + return a.NextPositiveDouble();
217 + else
218 + return a.Value();
219 + }
220 + else // adjustment
221 + return a.NextPositiveDouble();
222 +}
223 +
224 +inline double StrtodFullPrecision(double d, int p, const char* decimals, size_t length, size_t decimalPosition, int exp) {
225 + RAPIDJSON_ASSERT(d >= 0.0);
226 + RAPIDJSON_ASSERT(length >= 1);
227 +
228 + double result;
229 + if (StrtodFast(d, p, &result))
230 + return result;
231 +
232 + // Trim leading zeros
233 + while (*decimals == '0' && length > 1) {
234 + length--;
235 + decimals++;
236 + decimalPosition--;
237 + }
238 +
239 + // Trim trailing zeros
240 + while (decimals[length - 1] == '0' && length > 1) {
241 + length--;
242 + decimalPosition--;
243 + exp++;
244 + }
245 +
246 + // Trim right-most digits
247 + const int kMaxDecimalDigit = 780;
248 + if (static_cast<int>(length) > kMaxDecimalDigit) {
249 + int delta = (static_cast<int>(length) - kMaxDecimalDigit);
250 + exp += delta;
251 + decimalPosition -= static_cast<unsigned>(delta);
252 + length = kMaxDecimalDigit;
253 + }
254 +
255 + // If too small, underflow to zero
256 + if (int(length) + exp < -324)
257 + return 0.0;
258 +
259 + if (StrtodDiyFp(decimals, length, decimalPosition, exp, &result))
260 + return result;
261 +
262 + // Use approximation from StrtodDiyFp and make adjustment with BigInteger comparison
263 + return StrtodBigInteger(result, decimals, length, decimalPosition, exp);
264 +}
265 +
266 +} // namespace internal
267 +RAPIDJSON_NAMESPACE_END
268 +
269 +#endif // RAPIDJSON_STRTOD_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_INTERNAL_SWAP_H_
16 +#define RAPIDJSON_INTERNAL_SWAP_H_
17 +
18 +#include "../rapidjson.h"
19 +
20 +#if defined(__clang__)
21 +RAPIDJSON_DIAG_PUSH
22 +RAPIDJSON_DIAG_OFF(c++98-compat)
23 +#endif
24 +
25 +RAPIDJSON_NAMESPACE_BEGIN
26 +namespace internal {
27 +
28 +//! Custom swap() to avoid dependency on C++ <algorithm> header
29 +/*! \tparam T Type of the arguments to swap, should be instantiated with primitive C++ types only.
30 + \note This has the same semantics as std::swap().
31 +*/
32 +template <typename T>
33 +inline void Swap(T& a, T& b) RAPIDJSON_NOEXCEPT {
34 + T tmp = a;
35 + a = b;
36 + b = tmp;
37 +}
38 +
39 +} // namespace internal
40 +RAPIDJSON_NAMESPACE_END
41 +
42 +#if defined(__clang__)
43 +RAPIDJSON_DIAG_POP
44 +#endif
45 +
46 +#endif // RAPIDJSON_INTERNAL_SWAP_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_ISTREAMWRAPPER_H_
16 +#define RAPIDJSON_ISTREAMWRAPPER_H_
17 +
18 +#include "stream.h"
19 +#include <iosfwd>
20 +
21 +#ifdef __clang__
22 +RAPIDJSON_DIAG_PUSH
23 +RAPIDJSON_DIAG_OFF(padded)
24 +#endif
25 +
26 +#ifdef _MSC_VER
27 +RAPIDJSON_DIAG_PUSH
28 +RAPIDJSON_DIAG_OFF(4351) // new behavior: elements of array 'array' will be default initialized
29 +#endif
30 +
31 +RAPIDJSON_NAMESPACE_BEGIN
32 +
33 +//! Wrapper of \c std::basic_istream into RapidJSON's Stream concept.
34 +/*!
35 + The classes can be wrapped including but not limited to:
36 +
37 + - \c std::istringstream
38 + - \c std::stringstream
39 + - \c std::wistringstream
40 + - \c std::wstringstream
41 + - \c std::ifstream
42 + - \c std::fstream
43 + - \c std::wifstream
44 + - \c std::wfstream
45 +
46 + \tparam StreamType Class derived from \c std::basic_istream.
47 +*/
48 +
49 +template <typename StreamType>
50 +class BasicIStreamWrapper {
51 +public:
52 + typedef typename StreamType::char_type Ch;
53 + BasicIStreamWrapper(StreamType& stream) : stream_(stream), count_(), peekBuffer_() {}
54 +
55 + Ch Peek() const {
56 + typename StreamType::int_type c = stream_.peek();
57 + return RAPIDJSON_LIKELY(c != StreamType::traits_type::eof()) ? static_cast<Ch>(c) : static_cast<Ch>('\0');
58 + }
59 +
60 + Ch Take() {
61 + typename StreamType::int_type c = stream_.get();
62 + if (RAPIDJSON_LIKELY(c != StreamType::traits_type::eof())) {
63 + count_++;
64 + return static_cast<Ch>(c);
65 + }
66 + else
67 + return '\0';
68 + }
69 +
70 + // tellg() may return -1 when failed. So we count by ourself.
71 + size_t Tell() const { return count_; }
72 +
73 + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
74 + void Put(Ch) { RAPIDJSON_ASSERT(false); }
75 + void Flush() { RAPIDJSON_ASSERT(false); }
76 + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
77 +
78 + // For encoding detection only.
79 + const Ch* Peek4() const {
80 + RAPIDJSON_ASSERT(sizeof(Ch) == 1); // Only usable for byte stream.
81 + int i;
82 + bool hasError = false;
83 + for (i = 0; i < 4; ++i) {
84 + typename StreamType::int_type c = stream_.get();
85 + if (c == StreamType::traits_type::eof()) {
86 + hasError = true;
87 + stream_.clear();
88 + break;
89 + }
90 + peekBuffer_[i] = static_cast<Ch>(c);
91 + }
92 + for (--i; i >= 0; --i)
93 + stream_.putback(peekBuffer_[i]);
94 + return !hasError ? peekBuffer_ : 0;
95 + }
96 +
97 +private:
98 + BasicIStreamWrapper(const BasicIStreamWrapper&);
99 + BasicIStreamWrapper& operator=(const BasicIStreamWrapper&);
100 +
101 + StreamType& stream_;
102 + size_t count_; //!< Number of characters read. Note:
103 + mutable Ch peekBuffer_[4];
104 +};
105 +
106 +typedef BasicIStreamWrapper<std::istream> IStreamWrapper;
107 +typedef BasicIStreamWrapper<std::wistream> WIStreamWrapper;
108 +
109 +#if defined(__clang__) || defined(_MSC_VER)
110 +RAPIDJSON_DIAG_POP
111 +#endif
112 +
113 +RAPIDJSON_NAMESPACE_END
114 +
115 +#endif // RAPIDJSON_ISTREAMWRAPPER_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_MEMORYBUFFER_H_
16 +#define RAPIDJSON_MEMORYBUFFER_H_
17 +
18 +#include "stream.h"
19 +#include "internal/stack.h"
20 +
21 +RAPIDJSON_NAMESPACE_BEGIN
22 +
23 +//! Represents an in-memory output byte stream.
24 +/*!
25 + This class is mainly for being wrapped by EncodedOutputStream or AutoUTFOutputStream.
26 +
27 + It is similar to FileWriteBuffer but the destination is an in-memory buffer instead of a file.
28 +
29 + Differences between MemoryBuffer and StringBuffer:
30 + 1. StringBuffer has Encoding but MemoryBuffer is only a byte buffer.
31 + 2. StringBuffer::GetString() returns a null-terminated string. MemoryBuffer::GetBuffer() returns a buffer without terminator.
32 +
33 + \tparam Allocator type for allocating memory buffer.
34 + \note implements Stream concept
35 +*/
36 +template <typename Allocator = CrtAllocator>
37 +struct GenericMemoryBuffer {
38 + typedef char Ch; // byte
39 +
40 + GenericMemoryBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
41 +
42 + void Put(Ch c) { *stack_.template Push<Ch>() = c; }
43 + void Flush() {}
44 +
45 + void Clear() { stack_.Clear(); }
46 + void ShrinkToFit() { stack_.ShrinkToFit(); }
47 + Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
48 + void Pop(size_t count) { stack_.template Pop<Ch>(count); }
49 +
50 + const Ch* GetBuffer() const {
51 + return stack_.template Bottom<Ch>();
52 + }
53 +
54 + size_t GetSize() const { return stack_.GetSize(); }
55 +
56 + static const size_t kDefaultCapacity = 256;
57 + mutable internal::Stack<Allocator> stack_;
58 +};
59 +
60 +typedef GenericMemoryBuffer<> MemoryBuffer;
61 +
62 +//! Implement specialized version of PutN() with memset() for better performance.
63 +template<>
64 +inline void PutN(MemoryBuffer& memoryBuffer, char c, size_t n) {
65 + std::memset(memoryBuffer.stack_.Push<char>(n), c, n * sizeof(c));
66 +}
67 +
68 +RAPIDJSON_NAMESPACE_END
69 +
70 +#endif // RAPIDJSON_MEMORYBUFFER_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_MEMORYSTREAM_H_
16 +#define RAPIDJSON_MEMORYSTREAM_H_
17 +
18 +#include "stream.h"
19 +
20 +#ifdef __clang__
21 +RAPIDJSON_DIAG_PUSH
22 +RAPIDJSON_DIAG_OFF(unreachable-code)
23 +RAPIDJSON_DIAG_OFF(missing-noreturn)
24 +#endif
25 +
26 +RAPIDJSON_NAMESPACE_BEGIN
27 +
28 +//! Represents an in-memory input byte stream.
29 +/*!
30 + This class is mainly for being wrapped by EncodedInputStream or AutoUTFInputStream.
31 +
32 + It is similar to FileReadBuffer but the source is an in-memory buffer instead of a file.
33 +
34 + Differences between MemoryStream and StringStream:
35 + 1. StringStream has encoding but MemoryStream is a byte stream.
36 + 2. MemoryStream needs size of the source buffer and the buffer don't need to be null terminated. StringStream assume null-terminated string as source.
37 + 3. MemoryStream supports Peek4() for encoding detection. StringStream is specified with an encoding so it should not have Peek4().
38 + \note implements Stream concept
39 +*/
40 +struct MemoryStream {
41 + typedef char Ch; // byte
42 +
43 + MemoryStream(const Ch *src, size_t size) : src_(src), begin_(src), end_(src + size), size_(size) {}
44 +
45 + Ch Peek() const { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_; }
46 + Ch Take() { return RAPIDJSON_UNLIKELY(src_ == end_) ? '\0' : *src_++; }
47 + size_t Tell() const { return static_cast<size_t>(src_ - begin_); }
48 +
49 + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
50 + void Put(Ch) { RAPIDJSON_ASSERT(false); }
51 + void Flush() { RAPIDJSON_ASSERT(false); }
52 + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
53 +
54 + // For encoding detection only.
55 + const Ch* Peek4() const {
56 + return Tell() + 4 <= size_ ? src_ : 0;
57 + }
58 +
59 + const Ch* src_; //!< Current read position.
60 + const Ch* begin_; //!< Original head of the string.
61 + const Ch* end_; //!< End of stream.
62 + size_t size_; //!< Size of the stream.
63 +};
64 +
65 +RAPIDJSON_NAMESPACE_END
66 +
67 +#ifdef __clang__
68 +RAPIDJSON_DIAG_POP
69 +#endif
70 +
71 +#endif // RAPIDJSON_MEMORYBUFFER_H_
1 +// ISO C9x compliant inttypes.h for Microsoft Visual Studio
2 +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
3 +//
4 +// Copyright (c) 2006-2013 Alexander Chemeris
5 +//
6 +// Redistribution and use in source and binary forms, with or without
7 +// modification, are permitted provided that the following conditions are met:
8 +//
9 +// 1. Redistributions of source code must retain the above copyright notice,
10 +// this list of conditions and the following disclaimer.
11 +//
12 +// 2. Redistributions in binary form must reproduce the above copyright
13 +// notice, this list of conditions and the following disclaimer in the
14 +// documentation and/or other materials provided with the distribution.
15 +//
16 +// 3. Neither the name of the product nor the names of its contributors may
17 +// be used to endorse or promote products derived from this software
18 +// without specific prior written permission.
19 +//
20 +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23 +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 +//
31 +///////////////////////////////////////////////////////////////////////////////
32 +
33 +// The above software in this distribution may have been modified by
34 +// THL A29 Limited ("Tencent Modifications").
35 +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
36 +
37 +#ifndef _MSC_VER // [
38 +#error "Use this header only with Microsoft Visual C++ compilers!"
39 +#endif // _MSC_VER ]
40 +
41 +#ifndef _MSC_INTTYPES_H_ // [
42 +#define _MSC_INTTYPES_H_
43 +
44 +#if _MSC_VER > 1000
45 +#pragma once
46 +#endif
47 +
48 +#include "stdint.h"
49 +
50 +// miloyip: VC supports inttypes.h since VC2013
51 +#if _MSC_VER >= 1800
52 +#include <inttypes.h>
53 +#else
54 +
55 +// 7.8 Format conversion of integer types
56 +
57 +typedef struct {
58 + intmax_t quot;
59 + intmax_t rem;
60 +} imaxdiv_t;
61 +
62 +// 7.8.1 Macros for format specifiers
63 +
64 +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
65 +
66 +// The fprintf macros for signed integers are:
67 +#define PRId8 "d"
68 +#define PRIi8 "i"
69 +#define PRIdLEAST8 "d"
70 +#define PRIiLEAST8 "i"
71 +#define PRIdFAST8 "d"
72 +#define PRIiFAST8 "i"
73 +
74 +#define PRId16 "hd"
75 +#define PRIi16 "hi"
76 +#define PRIdLEAST16 "hd"
77 +#define PRIiLEAST16 "hi"
78 +#define PRIdFAST16 "hd"
79 +#define PRIiFAST16 "hi"
80 +
81 +#define PRId32 "I32d"
82 +#define PRIi32 "I32i"
83 +#define PRIdLEAST32 "I32d"
84 +#define PRIiLEAST32 "I32i"
85 +#define PRIdFAST32 "I32d"
86 +#define PRIiFAST32 "I32i"
87 +
88 +#define PRId64 "I64d"
89 +#define PRIi64 "I64i"
90 +#define PRIdLEAST64 "I64d"
91 +#define PRIiLEAST64 "I64i"
92 +#define PRIdFAST64 "I64d"
93 +#define PRIiFAST64 "I64i"
94 +
95 +#define PRIdMAX "I64d"
96 +#define PRIiMAX "I64i"
97 +
98 +#define PRIdPTR "Id"
99 +#define PRIiPTR "Ii"
100 +
101 +// The fprintf macros for unsigned integers are:
102 +#define PRIo8 "o"
103 +#define PRIu8 "u"
104 +#define PRIx8 "x"
105 +#define PRIX8 "X"
106 +#define PRIoLEAST8 "o"
107 +#define PRIuLEAST8 "u"
108 +#define PRIxLEAST8 "x"
109 +#define PRIXLEAST8 "X"
110 +#define PRIoFAST8 "o"
111 +#define PRIuFAST8 "u"
112 +#define PRIxFAST8 "x"
113 +#define PRIXFAST8 "X"
114 +
115 +#define PRIo16 "ho"
116 +#define PRIu16 "hu"
117 +#define PRIx16 "hx"
118 +#define PRIX16 "hX"
119 +#define PRIoLEAST16 "ho"
120 +#define PRIuLEAST16 "hu"
121 +#define PRIxLEAST16 "hx"
122 +#define PRIXLEAST16 "hX"
123 +#define PRIoFAST16 "ho"
124 +#define PRIuFAST16 "hu"
125 +#define PRIxFAST16 "hx"
126 +#define PRIXFAST16 "hX"
127 +
128 +#define PRIo32 "I32o"
129 +#define PRIu32 "I32u"
130 +#define PRIx32 "I32x"
131 +#define PRIX32 "I32X"
132 +#define PRIoLEAST32 "I32o"
133 +#define PRIuLEAST32 "I32u"
134 +#define PRIxLEAST32 "I32x"
135 +#define PRIXLEAST32 "I32X"
136 +#define PRIoFAST32 "I32o"
137 +#define PRIuFAST32 "I32u"
138 +#define PRIxFAST32 "I32x"
139 +#define PRIXFAST32 "I32X"
140 +
141 +#define PRIo64 "I64o"
142 +#define PRIu64 "I64u"
143 +#define PRIx64 "I64x"
144 +#define PRIX64 "I64X"
145 +#define PRIoLEAST64 "I64o"
146 +#define PRIuLEAST64 "I64u"
147 +#define PRIxLEAST64 "I64x"
148 +#define PRIXLEAST64 "I64X"
149 +#define PRIoFAST64 "I64o"
150 +#define PRIuFAST64 "I64u"
151 +#define PRIxFAST64 "I64x"
152 +#define PRIXFAST64 "I64X"
153 +
154 +#define PRIoMAX "I64o"
155 +#define PRIuMAX "I64u"
156 +#define PRIxMAX "I64x"
157 +#define PRIXMAX "I64X"
158 +
159 +#define PRIoPTR "Io"
160 +#define PRIuPTR "Iu"
161 +#define PRIxPTR "Ix"
162 +#define PRIXPTR "IX"
163 +
164 +// The fscanf macros for signed integers are:
165 +#define SCNd8 "d"
166 +#define SCNi8 "i"
167 +#define SCNdLEAST8 "d"
168 +#define SCNiLEAST8 "i"
169 +#define SCNdFAST8 "d"
170 +#define SCNiFAST8 "i"
171 +
172 +#define SCNd16 "hd"
173 +#define SCNi16 "hi"
174 +#define SCNdLEAST16 "hd"
175 +#define SCNiLEAST16 "hi"
176 +#define SCNdFAST16 "hd"
177 +#define SCNiFAST16 "hi"
178 +
179 +#define SCNd32 "ld"
180 +#define SCNi32 "li"
181 +#define SCNdLEAST32 "ld"
182 +#define SCNiLEAST32 "li"
183 +#define SCNdFAST32 "ld"
184 +#define SCNiFAST32 "li"
185 +
186 +#define SCNd64 "I64d"
187 +#define SCNi64 "I64i"
188 +#define SCNdLEAST64 "I64d"
189 +#define SCNiLEAST64 "I64i"
190 +#define SCNdFAST64 "I64d"
191 +#define SCNiFAST64 "I64i"
192 +
193 +#define SCNdMAX "I64d"
194 +#define SCNiMAX "I64i"
195 +
196 +#ifdef _WIN64 // [
197 +# define SCNdPTR "I64d"
198 +# define SCNiPTR "I64i"
199 +#else // _WIN64 ][
200 +# define SCNdPTR "ld"
201 +# define SCNiPTR "li"
202 +#endif // _WIN64 ]
203 +
204 +// The fscanf macros for unsigned integers are:
205 +#define SCNo8 "o"
206 +#define SCNu8 "u"
207 +#define SCNx8 "x"
208 +#define SCNX8 "X"
209 +#define SCNoLEAST8 "o"
210 +#define SCNuLEAST8 "u"
211 +#define SCNxLEAST8 "x"
212 +#define SCNXLEAST8 "X"
213 +#define SCNoFAST8 "o"
214 +#define SCNuFAST8 "u"
215 +#define SCNxFAST8 "x"
216 +#define SCNXFAST8 "X"
217 +
218 +#define SCNo16 "ho"
219 +#define SCNu16 "hu"
220 +#define SCNx16 "hx"
221 +#define SCNX16 "hX"
222 +#define SCNoLEAST16 "ho"
223 +#define SCNuLEAST16 "hu"
224 +#define SCNxLEAST16 "hx"
225 +#define SCNXLEAST16 "hX"
226 +#define SCNoFAST16 "ho"
227 +#define SCNuFAST16 "hu"
228 +#define SCNxFAST16 "hx"
229 +#define SCNXFAST16 "hX"
230 +
231 +#define SCNo32 "lo"
232 +#define SCNu32 "lu"
233 +#define SCNx32 "lx"
234 +#define SCNX32 "lX"
235 +#define SCNoLEAST32 "lo"
236 +#define SCNuLEAST32 "lu"
237 +#define SCNxLEAST32 "lx"
238 +#define SCNXLEAST32 "lX"
239 +#define SCNoFAST32 "lo"
240 +#define SCNuFAST32 "lu"
241 +#define SCNxFAST32 "lx"
242 +#define SCNXFAST32 "lX"
243 +
244 +#define SCNo64 "I64o"
245 +#define SCNu64 "I64u"
246 +#define SCNx64 "I64x"
247 +#define SCNX64 "I64X"
248 +#define SCNoLEAST64 "I64o"
249 +#define SCNuLEAST64 "I64u"
250 +#define SCNxLEAST64 "I64x"
251 +#define SCNXLEAST64 "I64X"
252 +#define SCNoFAST64 "I64o"
253 +#define SCNuFAST64 "I64u"
254 +#define SCNxFAST64 "I64x"
255 +#define SCNXFAST64 "I64X"
256 +
257 +#define SCNoMAX "I64o"
258 +#define SCNuMAX "I64u"
259 +#define SCNxMAX "I64x"
260 +#define SCNXMAX "I64X"
261 +
262 +#ifdef _WIN64 // [
263 +# define SCNoPTR "I64o"
264 +# define SCNuPTR "I64u"
265 +# define SCNxPTR "I64x"
266 +# define SCNXPTR "I64X"
267 +#else // _WIN64 ][
268 +# define SCNoPTR "lo"
269 +# define SCNuPTR "lu"
270 +# define SCNxPTR "lx"
271 +# define SCNXPTR "lX"
272 +#endif // _WIN64 ]
273 +
274 +#endif // __STDC_FORMAT_MACROS ]
275 +
276 +// 7.8.2 Functions for greatest-width integer types
277 +
278 +// 7.8.2.1 The imaxabs function
279 +#define imaxabs _abs64
280 +
281 +// 7.8.2.2 The imaxdiv function
282 +
283 +// This is modified version of div() function from Microsoft's div.c found
284 +// in %MSVC.NET%\crt\src\div.c
285 +#ifdef STATIC_IMAXDIV // [
286 +static
287 +#else // STATIC_IMAXDIV ][
288 +_inline
289 +#endif // STATIC_IMAXDIV ]
290 +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
291 +{
292 + imaxdiv_t result;
293 +
294 + result.quot = numer / denom;
295 + result.rem = numer % denom;
296 +
297 + if (numer < 0 && result.rem > 0) {
298 + // did division wrong; must fix up
299 + ++result.quot;
300 + result.rem -= denom;
301 + }
302 +
303 + return result;
304 +}
305 +
306 +// 7.8.2.3 The strtoimax and strtoumax functions
307 +#define strtoimax _strtoi64
308 +#define strtoumax _strtoui64
309 +
310 +// 7.8.2.4 The wcstoimax and wcstoumax functions
311 +#define wcstoimax _wcstoi64
312 +#define wcstoumax _wcstoui64
313 +
314 +#endif // _MSC_VER >= 1800
315 +
316 +#endif // _MSC_INTTYPES_H_ ]
1 +// ISO C9x compliant stdint.h for Microsoft Visual Studio
2 +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
3 +//
4 +// Copyright (c) 2006-2013 Alexander Chemeris
5 +//
6 +// Redistribution and use in source and binary forms, with or without
7 +// modification, are permitted provided that the following conditions are met:
8 +//
9 +// 1. Redistributions of source code must retain the above copyright notice,
10 +// this list of conditions and the following disclaimer.
11 +//
12 +// 2. Redistributions in binary form must reproduce the above copyright
13 +// notice, this list of conditions and the following disclaimer in the
14 +// documentation and/or other materials provided with the distribution.
15 +//
16 +// 3. Neither the name of the product nor the names of its contributors may
17 +// be used to endorse or promote products derived from this software
18 +// without specific prior written permission.
19 +//
20 +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23 +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 +//
31 +///////////////////////////////////////////////////////////////////////////////
32 +
33 +// The above software in this distribution may have been modified by
34 +// THL A29 Limited ("Tencent Modifications").
35 +// All Tencent Modifications are Copyright (C) 2015 THL A29 Limited.
36 +
37 +#ifndef _MSC_VER // [
38 +#error "Use this header only with Microsoft Visual C++ compilers!"
39 +#endif // _MSC_VER ]
40 +
41 +#ifndef _MSC_STDINT_H_ // [
42 +#define _MSC_STDINT_H_
43 +
44 +#if _MSC_VER > 1000
45 +#pragma once
46 +#endif
47 +
48 +// miloyip: Originally Visual Studio 2010 uses its own stdint.h. However it generates warning with INT64_C(), so change to use this file for vs2010.
49 +#if _MSC_VER >= 1600 // [
50 +#include <stdint.h>
51 +
52 +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
53 +
54 +#undef INT8_C
55 +#undef INT16_C
56 +#undef INT32_C
57 +#undef INT64_C
58 +#undef UINT8_C
59 +#undef UINT16_C
60 +#undef UINT32_C
61 +#undef UINT64_C
62 +
63 +// 7.18.4.1 Macros for minimum-width integer constants
64 +
65 +#define INT8_C(val) val##i8
66 +#define INT16_C(val) val##i16
67 +#define INT32_C(val) val##i32
68 +#define INT64_C(val) val##i64
69 +
70 +#define UINT8_C(val) val##ui8
71 +#define UINT16_C(val) val##ui16
72 +#define UINT32_C(val) val##ui32
73 +#define UINT64_C(val) val##ui64
74 +
75 +// 7.18.4.2 Macros for greatest-width integer constants
76 +// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
77 +// Check out Issue 9 for the details.
78 +#ifndef INTMAX_C // [
79 +# define INTMAX_C INT64_C
80 +#endif // INTMAX_C ]
81 +#ifndef UINTMAX_C // [
82 +# define UINTMAX_C UINT64_C
83 +#endif // UINTMAX_C ]
84 +
85 +#endif // __STDC_CONSTANT_MACROS ]
86 +
87 +#else // ] _MSC_VER >= 1700 [
88 +
89 +#include <limits.h>
90 +
91 +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
92 +// compiling for ARM we have to wrap <wchar.h> include with 'extern "C++" {}'
93 +// or compiler would give many errors like this:
94 +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
95 +#if defined(__cplusplus) && !defined(_M_ARM)
96 +extern "C" {
97 +#endif
98 +# include <wchar.h>
99 +#if defined(__cplusplus) && !defined(_M_ARM)
100 +}
101 +#endif
102 +
103 +// Define _W64 macros to mark types changing their size, like intptr_t.
104 +#ifndef _W64
105 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
106 +# define _W64 __w64
107 +# else
108 +# define _W64
109 +# endif
110 +#endif
111 +
112 +
113 +// 7.18.1 Integer types
114 +
115 +// 7.18.1.1 Exact-width integer types
116 +
117 +// Visual Studio 6 and Embedded Visual C++ 4 doesn't
118 +// realize that, e.g. char has the same size as __int8
119 +// so we give up on __intX for them.
120 +#if (_MSC_VER < 1300)
121 + typedef signed char int8_t;
122 + typedef signed short int16_t;
123 + typedef signed int int32_t;
124 + typedef unsigned char uint8_t;
125 + typedef unsigned short uint16_t;
126 + typedef unsigned int uint32_t;
127 +#else
128 + typedef signed __int8 int8_t;
129 + typedef signed __int16 int16_t;
130 + typedef signed __int32 int32_t;
131 + typedef unsigned __int8 uint8_t;
132 + typedef unsigned __int16 uint16_t;
133 + typedef unsigned __int32 uint32_t;
134 +#endif
135 +typedef signed __int64 int64_t;
136 +typedef unsigned __int64 uint64_t;
137 +
138 +
139 +// 7.18.1.2 Minimum-width integer types
140 +typedef int8_t int_least8_t;
141 +typedef int16_t int_least16_t;
142 +typedef int32_t int_least32_t;
143 +typedef int64_t int_least64_t;
144 +typedef uint8_t uint_least8_t;
145 +typedef uint16_t uint_least16_t;
146 +typedef uint32_t uint_least32_t;
147 +typedef uint64_t uint_least64_t;
148 +
149 +// 7.18.1.3 Fastest minimum-width integer types
150 +typedef int8_t int_fast8_t;
151 +typedef int16_t int_fast16_t;
152 +typedef int32_t int_fast32_t;
153 +typedef int64_t int_fast64_t;
154 +typedef uint8_t uint_fast8_t;
155 +typedef uint16_t uint_fast16_t;
156 +typedef uint32_t uint_fast32_t;
157 +typedef uint64_t uint_fast64_t;
158 +
159 +// 7.18.1.4 Integer types capable of holding object pointers
160 +#ifdef _WIN64 // [
161 + typedef signed __int64 intptr_t;
162 + typedef unsigned __int64 uintptr_t;
163 +#else // _WIN64 ][
164 + typedef _W64 signed int intptr_t;
165 + typedef _W64 unsigned int uintptr_t;
166 +#endif // _WIN64 ]
167 +
168 +// 7.18.1.5 Greatest-width integer types
169 +typedef int64_t intmax_t;
170 +typedef uint64_t uintmax_t;
171 +
172 +
173 +// 7.18.2 Limits of specified-width integer types
174 +
175 +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
176 +
177 +// 7.18.2.1 Limits of exact-width integer types
178 +#define INT8_MIN ((int8_t)_I8_MIN)
179 +#define INT8_MAX _I8_MAX
180 +#define INT16_MIN ((int16_t)_I16_MIN)
181 +#define INT16_MAX _I16_MAX
182 +#define INT32_MIN ((int32_t)_I32_MIN)
183 +#define INT32_MAX _I32_MAX
184 +#define INT64_MIN ((int64_t)_I64_MIN)
185 +#define INT64_MAX _I64_MAX
186 +#define UINT8_MAX _UI8_MAX
187 +#define UINT16_MAX _UI16_MAX
188 +#define UINT32_MAX _UI32_MAX
189 +#define UINT64_MAX _UI64_MAX
190 +
191 +// 7.18.2.2 Limits of minimum-width integer types
192 +#define INT_LEAST8_MIN INT8_MIN
193 +#define INT_LEAST8_MAX INT8_MAX
194 +#define INT_LEAST16_MIN INT16_MIN
195 +#define INT_LEAST16_MAX INT16_MAX
196 +#define INT_LEAST32_MIN INT32_MIN
197 +#define INT_LEAST32_MAX INT32_MAX
198 +#define INT_LEAST64_MIN INT64_MIN
199 +#define INT_LEAST64_MAX INT64_MAX
200 +#define UINT_LEAST8_MAX UINT8_MAX
201 +#define UINT_LEAST16_MAX UINT16_MAX
202 +#define UINT_LEAST32_MAX UINT32_MAX
203 +#define UINT_LEAST64_MAX UINT64_MAX
204 +
205 +// 7.18.2.3 Limits of fastest minimum-width integer types
206 +#define INT_FAST8_MIN INT8_MIN
207 +#define INT_FAST8_MAX INT8_MAX
208 +#define INT_FAST16_MIN INT16_MIN
209 +#define INT_FAST16_MAX INT16_MAX
210 +#define INT_FAST32_MIN INT32_MIN
211 +#define INT_FAST32_MAX INT32_MAX
212 +#define INT_FAST64_MIN INT64_MIN
213 +#define INT_FAST64_MAX INT64_MAX
214 +#define UINT_FAST8_MAX UINT8_MAX
215 +#define UINT_FAST16_MAX UINT16_MAX
216 +#define UINT_FAST32_MAX UINT32_MAX
217 +#define UINT_FAST64_MAX UINT64_MAX
218 +
219 +// 7.18.2.4 Limits of integer types capable of holding object pointers
220 +#ifdef _WIN64 // [
221 +# define INTPTR_MIN INT64_MIN
222 +# define INTPTR_MAX INT64_MAX
223 +# define UINTPTR_MAX UINT64_MAX
224 +#else // _WIN64 ][
225 +# define INTPTR_MIN INT32_MIN
226 +# define INTPTR_MAX INT32_MAX
227 +# define UINTPTR_MAX UINT32_MAX
228 +#endif // _WIN64 ]
229 +
230 +// 7.18.2.5 Limits of greatest-width integer types
231 +#define INTMAX_MIN INT64_MIN
232 +#define INTMAX_MAX INT64_MAX
233 +#define UINTMAX_MAX UINT64_MAX
234 +
235 +// 7.18.3 Limits of other integer types
236 +
237 +#ifdef _WIN64 // [
238 +# define PTRDIFF_MIN _I64_MIN
239 +# define PTRDIFF_MAX _I64_MAX
240 +#else // _WIN64 ][
241 +# define PTRDIFF_MIN _I32_MIN
242 +# define PTRDIFF_MAX _I32_MAX
243 +#endif // _WIN64 ]
244 +
245 +#define SIG_ATOMIC_MIN INT_MIN
246 +#define SIG_ATOMIC_MAX INT_MAX
247 +
248 +#ifndef SIZE_MAX // [
249 +# ifdef _WIN64 // [
250 +# define SIZE_MAX _UI64_MAX
251 +# else // _WIN64 ][
252 +# define SIZE_MAX _UI32_MAX
253 +# endif // _WIN64 ]
254 +#endif // SIZE_MAX ]
255 +
256 +// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
257 +#ifndef WCHAR_MIN // [
258 +# define WCHAR_MIN 0
259 +#endif // WCHAR_MIN ]
260 +#ifndef WCHAR_MAX // [
261 +# define WCHAR_MAX _UI16_MAX
262 +#endif // WCHAR_MAX ]
263 +
264 +#define WINT_MIN 0
265 +#define WINT_MAX _UI16_MAX
266 +
267 +#endif // __STDC_LIMIT_MACROS ]
268 +
269 +
270 +// 7.18.4 Limits of other integer types
271 +
272 +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
273 +
274 +// 7.18.4.1 Macros for minimum-width integer constants
275 +
276 +#define INT8_C(val) val##i8
277 +#define INT16_C(val) val##i16
278 +#define INT32_C(val) val##i32
279 +#define INT64_C(val) val##i64
280 +
281 +#define UINT8_C(val) val##ui8
282 +#define UINT16_C(val) val##ui16
283 +#define UINT32_C(val) val##ui32
284 +#define UINT64_C(val) val##ui64
285 +
286 +// 7.18.4.2 Macros for greatest-width integer constants
287 +// These #ifndef's are needed to prevent collisions with <boost/cstdint.hpp>.
288 +// Check out Issue 9 for the details.
289 +#ifndef INTMAX_C // [
290 +# define INTMAX_C INT64_C
291 +#endif // INTMAX_C ]
292 +#ifndef UINTMAX_C // [
293 +# define UINTMAX_C UINT64_C
294 +#endif // UINTMAX_C ]
295 +
296 +#endif // __STDC_CONSTANT_MACROS ]
297 +
298 +#endif // _MSC_VER >= 1600 ]
299 +
300 +#endif // _MSC_STDINT_H_ ]
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_OSTREAMWRAPPER_H_
16 +#define RAPIDJSON_OSTREAMWRAPPER_H_
17 +
18 +#include "stream.h"
19 +#include <iosfwd>
20 +
21 +#ifdef __clang__
22 +RAPIDJSON_DIAG_PUSH
23 +RAPIDJSON_DIAG_OFF(padded)
24 +#endif
25 +
26 +RAPIDJSON_NAMESPACE_BEGIN
27 +
28 +//! Wrapper of \c std::basic_ostream into RapidJSON's Stream concept.
29 +/*!
30 + The classes can be wrapped including but not limited to:
31 +
32 + - \c std::ostringstream
33 + - \c std::stringstream
34 + - \c std::wpstringstream
35 + - \c std::wstringstream
36 + - \c std::ifstream
37 + - \c std::fstream
38 + - \c std::wofstream
39 + - \c std::wfstream
40 +
41 + \tparam StreamType Class derived from \c std::basic_ostream.
42 +*/
43 +
44 +template <typename StreamType>
45 +class BasicOStreamWrapper {
46 +public:
47 + typedef typename StreamType::char_type Ch;
48 + BasicOStreamWrapper(StreamType& stream) : stream_(stream) {}
49 +
50 + void Put(Ch c) {
51 + stream_.put(c);
52 + }
53 +
54 + void Flush() {
55 + stream_.flush();
56 + }
57 +
58 + // Not implemented
59 + char Peek() const { RAPIDJSON_ASSERT(false); return 0; }
60 + char Take() { RAPIDJSON_ASSERT(false); return 0; }
61 + size_t Tell() const { RAPIDJSON_ASSERT(false); return 0; }
62 + char* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
63 + size_t PutEnd(char*) { RAPIDJSON_ASSERT(false); return 0; }
64 +
65 +private:
66 + BasicOStreamWrapper(const BasicOStreamWrapper&);
67 + BasicOStreamWrapper& operator=(const BasicOStreamWrapper&);
68 +
69 + StreamType& stream_;
70 +};
71 +
72 +typedef BasicOStreamWrapper<std::ostream> OStreamWrapper;
73 +typedef BasicOStreamWrapper<std::wostream> WOStreamWrapper;
74 +
75 +#ifdef __clang__
76 +RAPIDJSON_DIAG_POP
77 +#endif
78 +
79 +RAPIDJSON_NAMESPACE_END
80 +
81 +#endif // RAPIDJSON_OSTREAMWRAPPER_H_
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#include "rapidjson.h"
16 +
17 +#ifndef RAPIDJSON_STREAM_H_
18 +#define RAPIDJSON_STREAM_H_
19 +
20 +#include "encodings.h"
21 +
22 +RAPIDJSON_NAMESPACE_BEGIN
23 +
24 +///////////////////////////////////////////////////////////////////////////////
25 +// Stream
26 +
27 +/*! \class rapidjson::Stream
28 + \brief Concept for reading and writing characters.
29 +
30 + For read-only stream, no need to implement PutBegin(), Put(), Flush() and PutEnd().
31 +
32 + For write-only stream, only need to implement Put() and Flush().
33 +
34 +\code
35 +concept Stream {
36 + typename Ch; //!< Character type of the stream.
37 +
38 + //! Read the current character from stream without moving the read cursor.
39 + Ch Peek() const;
40 +
41 + //! Read the current character from stream and moving the read cursor to next character.
42 + Ch Take();
43 +
44 + //! Get the current read cursor.
45 + //! \return Number of characters read from start.
46 + size_t Tell();
47 +
48 + //! Begin writing operation at the current read pointer.
49 + //! \return The begin writer pointer.
50 + Ch* PutBegin();
51 +
52 + //! Write a character.
53 + void Put(Ch c);
54 +
55 + //! Flush the buffer.
56 + void Flush();
57 +
58 + //! End the writing operation.
59 + //! \param begin The begin write pointer returned by PutBegin().
60 + //! \return Number of characters written.
61 + size_t PutEnd(Ch* begin);
62 +}
63 +\endcode
64 +*/
65 +
66 +//! Provides additional information for stream.
67 +/*!
68 + By using traits pattern, this type provides a default configuration for stream.
69 + For custom stream, this type can be specialized for other configuration.
70 + See TEST(Reader, CustomStringStream) in readertest.cpp for example.
71 +*/
72 +template<typename Stream>
73 +struct StreamTraits {
74 + //! Whether to make local copy of stream for optimization during parsing.
75 + /*!
76 + By default, for safety, streams do not use local copy optimization.
77 + Stream that can be copied fast should specialize this, like StreamTraits<StringStream>.
78 + */
79 + enum { copyOptimization = 0 };
80 +};
81 +
82 +//! Reserve n characters for writing to a stream.
83 +template<typename Stream>
84 +inline void PutReserve(Stream& stream, size_t count) {
85 + (void)stream;
86 + (void)count;
87 +}
88 +
89 +//! Write character to a stream, presuming buffer is reserved.
90 +template<typename Stream>
91 +inline void PutUnsafe(Stream& stream, typename Stream::Ch c) {
92 + stream.Put(c);
93 +}
94 +
95 +//! Put N copies of a character to a stream.
96 +template<typename Stream, typename Ch>
97 +inline void PutN(Stream& stream, Ch c, size_t n) {
98 + PutReserve(stream, n);
99 + for (size_t i = 0; i < n; i++)
100 + PutUnsafe(stream, c);
101 +}
102 +
103 +///////////////////////////////////////////////////////////////////////////////
104 +// StringStream
105 +
106 +//! Read-only string stream.
107 +/*! \note implements Stream concept
108 +*/
109 +template <typename Encoding>
110 +struct GenericStringStream {
111 + typedef typename Encoding::Ch Ch;
112 +
113 + GenericStringStream(const Ch *src) : src_(src), head_(src) {}
114 +
115 + Ch Peek() const { return *src_; }
116 + Ch Take() { return *src_++; }
117 + size_t Tell() const { return static_cast<size_t>(src_ - head_); }
118 +
119 + Ch* PutBegin() { RAPIDJSON_ASSERT(false); return 0; }
120 + void Put(Ch) { RAPIDJSON_ASSERT(false); }
121 + void Flush() { RAPIDJSON_ASSERT(false); }
122 + size_t PutEnd(Ch*) { RAPIDJSON_ASSERT(false); return 0; }
123 +
124 + const Ch* src_; //!< Current read position.
125 + const Ch* head_; //!< Original head of the string.
126 +};
127 +
128 +template <typename Encoding>
129 +struct StreamTraits<GenericStringStream<Encoding> > {
130 + enum { copyOptimization = 1 };
131 +};
132 +
133 +//! String stream with UTF8 encoding.
134 +typedef GenericStringStream<UTF8<> > StringStream;
135 +
136 +///////////////////////////////////////////////////////////////////////////////
137 +// InsituStringStream
138 +
139 +//! A read-write string stream.
140 +/*! This string stream is particularly designed for in-situ parsing.
141 + \note implements Stream concept
142 +*/
143 +template <typename Encoding>
144 +struct GenericInsituStringStream {
145 + typedef typename Encoding::Ch Ch;
146 +
147 + GenericInsituStringStream(Ch *src) : src_(src), dst_(0), head_(src) {}
148 +
149 + // Read
150 + Ch Peek() { return *src_; }
151 + Ch Take() { return *src_++; }
152 + size_t Tell() { return static_cast<size_t>(src_ - head_); }
153 +
154 + // Write
155 + void Put(Ch c) { RAPIDJSON_ASSERT(dst_ != 0); *dst_++ = c; }
156 +
157 + Ch* PutBegin() { return dst_ = src_; }
158 + size_t PutEnd(Ch* begin) { return static_cast<size_t>(dst_ - begin); }
159 + void Flush() {}
160 +
161 + Ch* Push(size_t count) { Ch* begin = dst_; dst_ += count; return begin; }
162 + void Pop(size_t count) { dst_ -= count; }
163 +
164 + Ch* src_;
165 + Ch* dst_;
166 + Ch* head_;
167 +};
168 +
169 +template <typename Encoding>
170 +struct StreamTraits<GenericInsituStringStream<Encoding> > {
171 + enum { copyOptimization = 1 };
172 +};
173 +
174 +//! Insitu string stream with UTF8 encoding.
175 +typedef GenericInsituStringStream<UTF8<> > InsituStringStream;
176 +
177 +RAPIDJSON_NAMESPACE_END
178 +
179 +#endif // RAPIDJSON_STREAM_H_
1 +// Tencent is pleased to support the open source community by making RapidJSON available.
2 +//
3 +// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4 +//
5 +// Licensed under the MIT License (the "License"); you may not use this file except
6 +// in compliance with the License. You may obtain a copy of the License at
7 +//
8 +// http://opensource.org/licenses/MIT
9 +//
10 +// Unless required by applicable law or agreed to in writing, software distributed
11 +// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 +// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 +// specific language governing permissions and limitations under the License.
14 +
15 +#ifndef RAPIDJSON_STRINGBUFFER_H_
16 +#define RAPIDJSON_STRINGBUFFER_H_
17 +
18 +#include "stream.h"
19 +#include "internal/stack.h"
20 +
21 +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
22 +#include <utility> // std::move
23 +#endif
24 +
25 +#include "internal/stack.h"
26 +
27 +#if defined(__clang__)
28 +RAPIDJSON_DIAG_PUSH
29 +RAPIDJSON_DIAG_OFF(c++98-compat)
30 +#endif
31 +
32 +RAPIDJSON_NAMESPACE_BEGIN
33 +
34 +//! Represents an in-memory output stream.
35 +/*!
36 + \tparam Encoding Encoding of the stream.
37 + \tparam Allocator type for allocating memory buffer.
38 + \note implements Stream concept
39 +*/
40 +template <typename Encoding, typename Allocator = CrtAllocator>
41 +class GenericStringBuffer {
42 +public:
43 + typedef typename Encoding::Ch Ch;
44 +
45 + GenericStringBuffer(Allocator* allocator = 0, size_t capacity = kDefaultCapacity) : stack_(allocator, capacity) {}
46 +
47 +#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
48 + GenericStringBuffer(GenericStringBuffer&& rhs) : stack_(std::move(rhs.stack_)) {}
49 + GenericStringBuffer& operator=(GenericStringBuffer&& rhs) {
50 + if (&rhs != this)
51 + stack_ = std::move(rhs.stack_);
52 + return *this;
53 + }
54 +#endif
55 +
56 + void Put(Ch c) { *stack_.template Push<Ch>() = c; }
57 + void PutUnsafe(Ch c) { *stack_.template PushUnsafe<Ch>() = c; }
58 + void Flush() {}
59 +
60 + void Clear() { stack_.Clear(); }
61 + void ShrinkToFit() {
62 + // Push and pop a null terminator. This is safe.
63 + *stack_.template Push<Ch>() = '\0';
64 + stack_.ShrinkToFit();
65 + stack_.template Pop<Ch>(1);
66 + }
67 +
68 + void Reserve(size_t count) { stack_.template Reserve<Ch>(count); }
69 + Ch* Push(size_t count) { return stack_.template Push<Ch>(count); }
70 + Ch* PushUnsafe(size_t count) { return stack_.template PushUnsafe<Ch>(count); }
71 + void Pop(size_t count) { stack_.template Pop<Ch>(count); }
72 +
73 + const Ch* GetString() const {
74 + // Push and pop a null terminator. This is safe.
75 + *stack_.template Push<Ch>() = '\0';
76 + stack_.template Pop<Ch>(1);
77 +
78 + return stack_.template Bottom<Ch>();
79 + }
80 +
81 + //! Get the size of string in bytes in the string buffer.
82 + size_t GetSize() const { return stack_.GetSize(); }
83 +
84 + //! Get the length of string in Ch in the string buffer.
85 + size_t GetLength() const { return stack_.GetSize() / sizeof(Ch); }
86 +
87 + static const size_t kDefaultCapacity = 256;
88 + mutable internal::Stack<Allocator> stack_;
89 +
90 +private:
91 + // Prohibit copy constructor & assignment operator.
92 + GenericStringBuffer(const GenericStringBuffer&);
93 + GenericStringBuffer& operator=(const GenericStringBuffer&);
94 +};
95 +
96 +//! String buffer with UTF8 encoding
97 +typedef GenericStringBuffer<UTF8<> > StringBuffer;
98 +
99 +template<typename Encoding, typename Allocator>
100 +inline void PutReserve(GenericStringBuffer<Encoding, Allocator>& stream, size_t count) {
101 + stream.Reserve(count);
102 +}
103 +
104 +template<typename Encoding, typename Allocator>
105 +inline void PutUnsafe(GenericStringBuffer<Encoding, Allocator>& stream, typename Encoding::Ch c) {
106 + stream.PutUnsafe(c);
107 +}
108 +
109 +//! Implement specialized version of PutN() with memset() for better performance.
110 +template<>
111 +inline void PutN(GenericStringBuffer<UTF8<> >& stream, char c, size_t n) {
112 + std::memset(stream.stack_.Push<char>(n), c, n * sizeof(c));
113 +}
114 +
115 +RAPIDJSON_NAMESPACE_END
116 +
117 +#if defined(__clang__)
118 +RAPIDJSON_DIAG_POP
119 +#endif
120 +
121 +#endif // RAPIDJSON_STRINGBUFFER_H_
This diff is collapsed. Click to expand it.
...@@ -2,50 +2,26 @@ ...@@ -2,50 +2,26 @@
2 #include "PaperGraphWidget.h" 2 #include "PaperGraphWidget.h"
3 #include "MainWindow.h" 3 #include "MainWindow.h"
4 4
5 -size_t write_callback(void *contents, size_t size, 5 +int main(int argc, char *argv[]) {
6 - size_t nmemb, void *userp) {
7 - std::string* p_str = (std::string*)userp;
8 -
9 - //clear
10 - if (!p_str->empty())
11 - p_str->clear();
12 -
13 - //write
14 - p_str->append((char*)contents, size*nmemb);
15 - return size*nmemb;
16 -}
17 -
18 -int main(int argc, char *argv[])
19 -{
20 if (1) { 6 if (1) {
21 - CURL *curl; 7 + _curl_processor.set_url("http://dblp.uni-trier.de/rec/bib1/conf/sbrn/WedemannCD06");
22 - CURLcode res; 8 + _curl_processor.perform();
23 - std::string read_buffer; 9 + printf("%s", _curl_processor.get_buffer().c_str());
24 - 10 +
25 - curl = curl_easy_init(); 11 + _bibtex_processor.read(_curl_processor.get_buffer());
26 - if (curl) { 12 + std::string doi;
27 - curl_easy_setopt(curl, CURLOPT_URL, "http://dblp.uni-trier.de/rec/bib/conf/sbrn/WedemannCD06"); 13 + _bibtex_processor.get_value("doi", doi);
28 - /* example.com is redirected, so we tell libcurl to follow redirection */
29 -
30 - //write option
31 - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
32 - curl_easy_setopt(curl, CURLOPT_WRITEDATA, &read_buffer);
33 -
34 - /* Perform the request, res will get the return code */
35 - res = curl_easy_perform(curl);
36 - res = curl_easy_perform(curl);
37 14
15 + std::string address = std::string("http://api.crossref.org/works/")+doi;
16 + _curl_processor.set_url(address.c_str());
17 + _curl_processor.perform();
38 18
39 - printf("%s\n", read_buffer.c_str()); 19 + printf("json: %s\n", _curl_processor.get_buffer().c_str());
40 20
41 - /* Check for errors */ 21 + //rapidjson test
42 - if (res != CURLE_OK) 22 + rapidjson::Document d;
43 - fprintf(stderr, "curl_easy_perform() failed: %s\n", 23 + d.Parse(_curl_processor.get_buffer().c_str());
44 - curl_easy_strerror(res));
45 24
46 - /* always cleanup */
47 - curl_easy_cleanup(curl);
48 - }
49 return 0; 25 return 0;
50 } 26 }
51 27
......
1 #include "stdafx.h" 1 #include "stdafx.h"
2 +
3 +size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
4 + //copy ptr
5 + std::string* p_str = (std::string*)userp;
6 +
7 + //clear
8 + if (!p_str->empty())
9 + p_str->clear();
10 +
11 + //write
12 + p_str->append((char*)contents, size*nmemb);
13 + return size*nmemb;
14 +}
...\ No newline at end of file ...\ No newline at end of file
......
1 #pragma once 1 #pragma once
2 +#define _CRT_SECURE_NO_WARNINGS
3 +
2 #include <QColor> 4 #include <QColor>
3 #include <QComboBox> 5 #include <QComboBox>
4 #include <QDebug> 6 #include <QDebug>
...@@ -47,17 +49,32 @@ ...@@ -47,17 +49,32 @@
47 #include <utility> 49 #include <utility>
48 #include <vector> 50 #include <vector>
49 51
52 +#include <bibtexreader.hpp>
53 +
54 +#include <rapidjson/document.h>
55 +#include <rapidjson/writer.h>
56 +#include <rapidjson/stringbuffer.h>
57 +
58 +#include "bibtex_processor.h"
59 +#include "curl_processor.h"
60 +
61 +using bibtex::BibTeXEntry;
50 using namespace boost; 62 using namespace boost;
51 using namespace std; 63 using namespace std;
52 64
65 +/* function declaration */
66 +size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp);
67 +
53 /* enums */ 68 /* enums */
54 enum vertex_position_t { vertex_position }; 69 enum vertex_position_t { vertex_position };
55 enum vertex_type_t { vertex_type }; 70 enum vertex_type_t { vertex_type };
56 enum vertex_record_t { vertex_record }; 71 enum vertex_record_t { vertex_record };
72 +enum vertex_citation_t { vertex_citation };
57 namespace boost { 73 namespace boost {
58 BOOST_INSTALL_PROPERTY(vertex, position); 74 BOOST_INSTALL_PROPERTY(vertex, position);
59 BOOST_INSTALL_PROPERTY(vertex, type); 75 BOOST_INSTALL_PROPERTY(vertex, type);
60 BOOST_INSTALL_PROPERTY(vertex, record); 76 BOOST_INSTALL_PROPERTY(vertex, record);
77 + BOOST_INSTALL_PROPERTY(vertex, citation);
61 } 78 }
62 enum NODE_TYPE { 79 enum NODE_TYPE {
63 NODE_PAPER, 80 NODE_PAPER,
...@@ -75,9 +92,11 @@ typedef boost::bimap<string, int> bm_type; ...@@ -75,9 +92,11 @@ typedef boost::bimap<string, int> bm_type;
75 typedef square_topology<>::point_type point; 92 typedef square_topology<>::point_type point;
76 typedef boost::property<vertex_index_t, int, 93 typedef boost::property<vertex_index_t, int,
77 boost::property<vertex_name_t, std::string, 94 boost::property<vertex_name_t, std::string,
78 - boost::property<vertex_position_t, point, 95 + boost::property<vertex_position_t, point, //좌표값
79 - boost::property<vertex_type_t, int, 96 + boost::property<vertex_type_t, int, //타입. enum NODE_TYPE에 정의됨
80 - boost::property<vertex_record_t, int>>>> 97 + boost::property<vertex_record_t, int, //이웃 노드 개수
98 + boost::property<vertex_citation_t, int>
99 + >>>>
81 > VertexProperties; 100 > VertexProperties;
82 typedef boost::adjacency_list< 101 typedef boost::adjacency_list<
83 listS, //outEdgeList 102 listS, //outEdgeList
...@@ -108,11 +127,11 @@ namespace { ...@@ -108,11 +127,11 @@ namespace {
108 //const int READ_LINE_UNIT = 20; //한 번에 몇 라인을 읽을지 127 //const int READ_LINE_UNIT = 20; //한 번에 몇 라인을 읽을지
109 const int READ_LINE_UNIT = 100; 128 const int READ_LINE_UNIT = 100;
110 129
111 - /* topK */ 130 + /* curl processor */
112 - //const int TOP_K = 5; //상위 몇 개 아이템에 대해 highlight 할 지 131 + curl_processor _curl_processor;
113 132
114 - /* a research you might know */ 133 + /* bibtex processor */
115 - //const char* TARGET_AUTHOR_NAME = "Shuichi Itoh"; 134 + bibtex_processor _bibtex_processor;
116 } 135 }
117 136
118 /* boost */ 137 /* boost */
...@@ -204,4 +223,4 @@ public: ...@@ -204,4 +223,4 @@ public:
204 } 223 }
205 int getSize() {return size;} 224 int getSize() {return size;}
206 bool isFull() {return k==size;} 225 bool isFull() {return k==size;}
207 -};
...\ No newline at end of file ...\ No newline at end of file
226 +};
......