27#include <nlohmann/detail/exceptions.hpp>
28#include <nlohmann/detail/iterators/iterator_traits.hpp>
29#include <nlohmann/detail/macro_scope.hpp>
30#include <nlohmann/detail/meta/type_traits.hpp>
32NLOHMANN_JSON_NAMESPACE_BEGIN
48class file_input_adapter
51 using char_type = char;
53 JSON_HEDLEY_NON_NULL(2)
54 explicit file_input_adapter(std::FILE* f) noexcept
57 JSON_ASSERT(m_file !=
nullptr);
61 file_input_adapter(
const file_input_adapter&) =
delete;
62 file_input_adapter(file_input_adapter&&)
noexcept =
default;
63 file_input_adapter& operator=(
const file_input_adapter&) =
delete;
64 file_input_adapter& operator=(file_input_adapter&&) =
delete;
65 ~file_input_adapter() =
default;
67 std::char_traits<char>::int_type get_character()
noexcept
69 return std::fgetc(m_file);
74 std::size_t get_elements(T* dest, std::size_t count = 1)
76 return fread(dest, 1,
sizeof(T) * count, m_file);
93class input_stream_adapter
96 using char_type = char;
98 ~input_stream_adapter()
104 is->clear(is->rdstate() & std::ios::eofbit);
108 explicit input_stream_adapter(std::istream& i)
109 : is(&i), sb(i.rdbuf())
113 input_stream_adapter(
const input_stream_adapter&) =
delete;
114 input_stream_adapter& operator=(input_stream_adapter&) =
delete;
115 input_stream_adapter& operator=(input_stream_adapter&&) =
delete;
117 input_stream_adapter(input_stream_adapter&& rhs) noexcept
118 : is(rhs.is), sb(rhs.sb)
127 std::char_traits<char>::int_type get_character()
129 auto res = sb->sbumpc();
131 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
133 is->clear(is->rdstate() | std::ios::eofbit);
139 std::size_t get_elements(T* dest, std::size_t count = 1)
141 auto res =
static_cast<std::size_t
>(sb->sgetn(
reinterpret_cast<char*
>(dest),
static_cast<std::streamsize
>(count *
sizeof(T))));
142 if (JSON_HEDLEY_UNLIKELY(res < count *
sizeof(T)))
144 is->clear(is->rdstate() | std::ios::eofbit);
151 std::istream* is =
nullptr;
152 std::streambuf* sb =
nullptr;
158template<
typename IteratorType>
159class iterator_input_adapter
162 using char_type =
typename std::iterator_traits<IteratorType>::value_type;
164 iterator_input_adapter(IteratorType first, IteratorType last)
165 : current(std::move(first)), end(std::move(last))
170 if (JSON_HEDLEY_LIKELY(current != end))
173 std::advance(current, 1);
182 std::size_t get_elements(T* dest, std::size_t count = 1)
184 auto* ptr =
reinterpret_cast<char*
>(dest);
185 for (std::size_t read_index = 0; read_index < count *
sizeof(T); ++read_index)
187 if (JSON_HEDLEY_LIKELY(current != end))
189 ptr[read_index] =
static_cast<char>(*current);
190 std::advance(current, 1);
197 return count *
sizeof(T);
201 IteratorType current;
204 template<
typename BaseInputAdapter,
size_t T>
205 friend struct wide_string_input_helper;
209 return current == end;
213template<
typename BaseInputAdapter,
size_t T>
216template<
typename BaseInputAdapter>
220 static void fill_buffer(BaseInputAdapter& input,
221 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
222 size_t& utf8_bytes_index,
223 size_t& utf8_bytes_filled)
225 utf8_bytes_index = 0;
227 if (JSON_HEDLEY_UNLIKELY(input.empty()))
229 utf8_bytes[0] = std::char_traits<char>::eof();
230 utf8_bytes_filled = 1;
235 const auto wc = input.get_character();
240 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
241 utf8_bytes_filled = 1;
243 else if (wc <= 0x7FF)
245 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
246 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
247 utf8_bytes_filled = 2;
249 else if (wc <= 0xFFFF)
251 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((
static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
252 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
253 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
254 utf8_bytes_filled = 3;
256 else if (wc <= 0x10FFFF)
258 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | ((
static_cast<unsigned int>(wc) >> 18u) & 0x07u));
259 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
260 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
261 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
262 utf8_bytes_filled = 4;
267 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
268 utf8_bytes_filled = 1;
274template<
typename BaseInputAdapter>
278 static void fill_buffer(BaseInputAdapter& input,
279 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
280 size_t& utf8_bytes_index,
281 size_t& utf8_bytes_filled)
283 utf8_bytes_index = 0;
285 if (JSON_HEDLEY_UNLIKELY(input.empty()))
287 utf8_bytes[0] = std::char_traits<char>::eof();
288 utf8_bytes_filled = 1;
293 const auto wc = input.get_character();
298 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
299 utf8_bytes_filled = 1;
301 else if (wc <= 0x7FF)
303 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xC0u | ((
static_cast<unsigned int>(wc) >> 6u)));
304 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
305 utf8_bytes_filled = 2;
307 else if (0xD800 > wc || wc >= 0xE000)
309 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xE0u | ((
static_cast<unsigned int>(wc) >> 12u)));
310 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((
static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
311 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (
static_cast<unsigned int>(wc) & 0x3Fu));
312 utf8_bytes_filled = 3;
316 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
318 const auto wc2 =
static_cast<unsigned int>(input.get_character());
319 const auto charcode = 0x10000u + (((
static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
320 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(0xF0u | (charcode >> 18u));
321 utf8_bytes[1] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 12u) & 0x3Fu));
322 utf8_bytes[2] =
static_cast<std::char_traits<char>::int_type
>(0x80u | ((charcode >> 6u) & 0x3Fu));
323 utf8_bytes[3] =
static_cast<std::char_traits<char>::int_type
>(0x80u | (charcode & 0x3Fu));
324 utf8_bytes_filled = 4;
328 utf8_bytes[0] =
static_cast<std::char_traits<char>::int_type
>(wc);
329 utf8_bytes_filled = 1;
337template<
typename BaseInputAdapter,
typename W
ideCharType>
338class wide_string_input_adapter
341 using char_type = char;
343 wide_string_input_adapter(BaseInputAdapter base)
344 : base_adapter(base) {}
346 typename std::char_traits<char>::int_type get_character()
noexcept
349 if (utf8_bytes_index == utf8_bytes_filled)
351 fill_buffer<sizeof(WideCharType)>();
353 JSON_ASSERT(utf8_bytes_filled > 0);
354 JSON_ASSERT(utf8_bytes_index == 0);
358 JSON_ASSERT(utf8_bytes_filled > 0);
359 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
360 return utf8_bytes[utf8_bytes_index++];
365 std::size_t get_elements(T* , std::size_t = 1)
367 JSON_THROW(
parse_error::create(112, 1,
"wide string type cannot be interpreted as binary data",
nullptr));
371 BaseInputAdapter base_adapter;
380 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
383 std::size_t utf8_bytes_index = 0;
385 std::size_t utf8_bytes_filled = 0;
388template<
typename IteratorType,
typename Enable =
void>
391 using iterator_type = IteratorType;
392 using char_type =
typename std::iterator_traits<iterator_type>::value_type;
395 static adapter_type create(IteratorType first, IteratorType last)
397 return adapter_type(std::move(first), std::move(last));
404 using value_type =
typename std::iterator_traits<T>::value_type;
407 value =
sizeof(value_type) > 1
411template<
typename IteratorType>
414 using iterator_type = IteratorType;
415 using char_type =
typename std::iterator_traits<iterator_type>::value_type;
419 static adapter_type create(IteratorType first, IteratorType last)
421 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
426template<
typename IteratorType>
427typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
430 return factory_type::create(first, last);
437namespace container_input_adapter_factory_impl
443template<
typename ContainerType,
typename Enable =
void>
446template<
typename ContainerType>
448 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
450 using adapter_type =
decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
452 static adapter_type create(
const ContainerType& container)
454 return input_adapter(begin(container), end(container));
460template<
typename ContainerType>
467using string_input_adapter_type =
decltype(input_adapter(std::declval<std::string>()));
471inline file_input_adapter input_adapter(std::FILE* file)
475 JSON_THROW(
parse_error::create(101, 0,
"attempting to parse an empty input; check that your input string or stream contains the expected JSON",
nullptr));
491using contiguous_bytes_input_adapter =
decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
494template <
typename CharT,
495 typename std::enable_if <
496 std::is_pointer<CharT>::value&&
497 !std::is_array<CharT>::value&&
498 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
499 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
501contiguous_bytes_input_adapter input_adapter(CharT b)
505 JSON_THROW(
parse_error::create(101, 0,
"attempting to parse an empty input; check that your input string or stream contains the expected JSON",
nullptr));
507 auto length = std::strlen(
reinterpret_cast<const char*
>(b));
508 const auto* ptr =
reinterpret_cast<const char*
>(b);
509 return input_adapter(ptr, ptr + length);
512template<
typename T, std::
size_t N>
513auto input_adapter(T (&
array)[N]) ->
decltype(input_adapter(
array,
array + N))
521class span_input_adapter
524 template <
typename CharT,
525 typename std::enable_if <
526 std::is_pointer<CharT>::value&&
527 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
528 sizeof(
typename std::remove_pointer<CharT>::type) == 1,
530 span_input_adapter(CharT b, std::size_t l)
531 : ia(
reinterpret_cast<const char*
>(b),
reinterpret_cast<const char*
>(b) + l) {}
533 template<
class IteratorType,
534 typename std::enable_if<
535 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
537 span_input_adapter(IteratorType first, IteratorType last)
538 : ia(input_adapter(first, last)) {}
540 contiguous_bytes_input_adapter&& get()
542 return std::move(ia);
546 contiguous_bytes_input_adapter ia;
550NLOHMANN_JSON_NAMESPACE_END
static parse_error create(int id_, const position_t &pos, const std::string &what_arg, BasicJsonContext context)
create a parse error exception
定义 exceptions.hpp:179
detail namespace with internal helper functions
定义 from_json.hpp:43
@ array
array (ordered collection of values)
定义 value_t.hpp:57
input_format_t
the supported input formats
定义 input_adapters.hpp:37
定义 input_adapters.hpp:403