File indexing completed on 2025-01-18 10:02:18
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <array> // array
0012 #include <cstddef> // size_t
0013 #include <cstring> // strlen
0014 #include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next
0015 #include <memory> // shared_ptr, make_shared, addressof
0016 #include <numeric> // accumulate
0017 #include <string> // string, char_traits
0018 #include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer
0019 #include <utility> // pair, declval
0020
0021 #ifndef JSON_NO_IO
0022 #include <cstdio> // FILE *
0023 #include <istream> // istream
0024 #endif
0025
0026 #include <nlohmann/detail/iterators/iterator_traits.hpp>
0027 #include <nlohmann/detail/macro_scope.hpp>
0028
0029 NLOHMANN_JSON_NAMESPACE_BEGIN
0030 namespace detail
0031 {
0032
0033
0034 enum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata };
0035
0036
0037
0038
0039
0040 #ifndef JSON_NO_IO
0041
0042
0043
0044
0045 class file_input_adapter
0046 {
0047 public:
0048 using char_type = char;
0049
0050 JSON_HEDLEY_NON_NULL(2)
0051 explicit file_input_adapter(std::FILE* f) noexcept
0052 : m_file(f)
0053 {
0054 JSON_ASSERT(m_file != nullptr);
0055 }
0056
0057
0058 file_input_adapter(const file_input_adapter&) = delete;
0059 file_input_adapter(file_input_adapter&&) noexcept = default;
0060 file_input_adapter& operator=(const file_input_adapter&) = delete;
0061 file_input_adapter& operator=(file_input_adapter&&) = delete;
0062 ~file_input_adapter() = default;
0063
0064 std::char_traits<char>::int_type get_character() noexcept
0065 {
0066 return std::fgetc(m_file);
0067 }
0068
0069 private:
0070
0071 std::FILE* m_file;
0072 };
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 class input_stream_adapter
0085 {
0086 public:
0087 using char_type = char;
0088
0089 ~input_stream_adapter()
0090 {
0091
0092
0093 if (is != nullptr)
0094 {
0095 is->clear(is->rdstate() & std::ios::eofbit);
0096 }
0097 }
0098
0099 explicit input_stream_adapter(std::istream& i)
0100 : is(&i), sb(i.rdbuf())
0101 {}
0102
0103
0104 input_stream_adapter(const input_stream_adapter&) = delete;
0105 input_stream_adapter& operator=(input_stream_adapter&) = delete;
0106 input_stream_adapter& operator=(input_stream_adapter&&) = delete;
0107
0108 input_stream_adapter(input_stream_adapter&& rhs) noexcept
0109 : is(rhs.is), sb(rhs.sb)
0110 {
0111 rhs.is = nullptr;
0112 rhs.sb = nullptr;
0113 }
0114
0115
0116
0117
0118 std::char_traits<char>::int_type get_character()
0119 {
0120 auto res = sb->sbumpc();
0121
0122 if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof()))
0123 {
0124 is->clear(is->rdstate() | std::ios::eofbit);
0125 }
0126 return res;
0127 }
0128
0129 private:
0130
0131 std::istream* is = nullptr;
0132 std::streambuf* sb = nullptr;
0133 };
0134 #endif
0135
0136
0137
0138 template<typename IteratorType>
0139 class iterator_input_adapter
0140 {
0141 public:
0142 using char_type = typename std::iterator_traits<IteratorType>::value_type;
0143
0144 iterator_input_adapter(IteratorType first, IteratorType last)
0145 : current(std::move(first)), end(std::move(last))
0146 {}
0147
0148 typename std::char_traits<char_type>::int_type get_character()
0149 {
0150 if (JSON_HEDLEY_LIKELY(current != end))
0151 {
0152 auto result = std::char_traits<char_type>::to_int_type(*current);
0153 std::advance(current, 1);
0154 return result;
0155 }
0156
0157 return std::char_traits<char_type>::eof();
0158 }
0159
0160 private:
0161 IteratorType current;
0162 IteratorType end;
0163
0164 template<typename BaseInputAdapter, size_t T>
0165 friend struct wide_string_input_helper;
0166
0167 bool empty() const
0168 {
0169 return current == end;
0170 }
0171 };
0172
0173
0174 template<typename BaseInputAdapter, size_t T>
0175 struct wide_string_input_helper;
0176
0177 template<typename BaseInputAdapter>
0178 struct wide_string_input_helper<BaseInputAdapter, 4>
0179 {
0180
0181 static void fill_buffer(BaseInputAdapter& input,
0182 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
0183 size_t& utf8_bytes_index,
0184 size_t& utf8_bytes_filled)
0185 {
0186 utf8_bytes_index = 0;
0187
0188 if (JSON_HEDLEY_UNLIKELY(input.empty()))
0189 {
0190 utf8_bytes[0] = std::char_traits<char>::eof();
0191 utf8_bytes_filled = 1;
0192 }
0193 else
0194 {
0195
0196 const auto wc = input.get_character();
0197
0198
0199 if (wc < 0x80)
0200 {
0201 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
0202 utf8_bytes_filled = 1;
0203 }
0204 else if (wc <= 0x7FF)
0205 {
0206 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu));
0207 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
0208 utf8_bytes_filled = 2;
0209 }
0210 else if (wc <= 0xFFFF)
0211 {
0212 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu));
0213 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
0214 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
0215 utf8_bytes_filled = 3;
0216 }
0217 else if (wc <= 0x10FFFF)
0218 {
0219 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u));
0220 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu));
0221 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
0222 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
0223 utf8_bytes_filled = 4;
0224 }
0225 else
0226 {
0227
0228 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
0229 utf8_bytes_filled = 1;
0230 }
0231 }
0232 }
0233 };
0234
0235 template<typename BaseInputAdapter>
0236 struct wide_string_input_helper<BaseInputAdapter, 2>
0237 {
0238
0239 static void fill_buffer(BaseInputAdapter& input,
0240 std::array<std::char_traits<char>::int_type, 4>& utf8_bytes,
0241 size_t& utf8_bytes_index,
0242 size_t& utf8_bytes_filled)
0243 {
0244 utf8_bytes_index = 0;
0245
0246 if (JSON_HEDLEY_UNLIKELY(input.empty()))
0247 {
0248 utf8_bytes[0] = std::char_traits<char>::eof();
0249 utf8_bytes_filled = 1;
0250 }
0251 else
0252 {
0253
0254 const auto wc = input.get_character();
0255
0256
0257 if (wc < 0x80)
0258 {
0259 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
0260 utf8_bytes_filled = 1;
0261 }
0262 else if (wc <= 0x7FF)
0263 {
0264 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u)));
0265 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
0266 utf8_bytes_filled = 2;
0267 }
0268 else if (0xD800 > wc || wc >= 0xE000)
0269 {
0270 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u)));
0271 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu));
0272 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu));
0273 utf8_bytes_filled = 3;
0274 }
0275 else
0276 {
0277 if (JSON_HEDLEY_UNLIKELY(!input.empty()))
0278 {
0279 const auto wc2 = static_cast<unsigned int>(input.get_character());
0280 const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu));
0281 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u));
0282 utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu));
0283 utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu));
0284 utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu));
0285 utf8_bytes_filled = 4;
0286 }
0287 else
0288 {
0289 utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc);
0290 utf8_bytes_filled = 1;
0291 }
0292 }
0293 }
0294 }
0295 };
0296
0297
0298 template<typename BaseInputAdapter, typename WideCharType>
0299 class wide_string_input_adapter
0300 {
0301 public:
0302 using char_type = char;
0303
0304 wide_string_input_adapter(BaseInputAdapter base)
0305 : base_adapter(base) {}
0306
0307 typename std::char_traits<char>::int_type get_character() noexcept
0308 {
0309
0310 if (utf8_bytes_index == utf8_bytes_filled)
0311 {
0312 fill_buffer<sizeof(WideCharType)>();
0313
0314 JSON_ASSERT(utf8_bytes_filled > 0);
0315 JSON_ASSERT(utf8_bytes_index == 0);
0316 }
0317
0318
0319 JSON_ASSERT(utf8_bytes_filled > 0);
0320 JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled);
0321 return utf8_bytes[utf8_bytes_index++];
0322 }
0323
0324 private:
0325 BaseInputAdapter base_adapter;
0326
0327 template<size_t T>
0328 void fill_buffer()
0329 {
0330 wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled);
0331 }
0332
0333
0334 std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}};
0335
0336
0337 std::size_t utf8_bytes_index = 0;
0338
0339 std::size_t utf8_bytes_filled = 0;
0340 };
0341
0342
0343 template<typename IteratorType, typename Enable = void>
0344 struct iterator_input_adapter_factory
0345 {
0346 using iterator_type = IteratorType;
0347 using char_type = typename std::iterator_traits<iterator_type>::value_type;
0348 using adapter_type = iterator_input_adapter<iterator_type>;
0349
0350 static adapter_type create(IteratorType first, IteratorType last)
0351 {
0352 return adapter_type(std::move(first), std::move(last));
0353 }
0354 };
0355
0356 template<typename T>
0357 struct is_iterator_of_multibyte
0358 {
0359 using value_type = typename std::iterator_traits<T>::value_type;
0360 enum
0361 {
0362 value = sizeof(value_type) > 1
0363 };
0364 };
0365
0366 template<typename IteratorType>
0367 struct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>>
0368 {
0369 using iterator_type = IteratorType;
0370 using char_type = typename std::iterator_traits<iterator_type>::value_type;
0371 using base_adapter_type = iterator_input_adapter<iterator_type>;
0372 using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>;
0373
0374 static adapter_type create(IteratorType first, IteratorType last)
0375 {
0376 return adapter_type(base_adapter_type(std::move(first), std::move(last)));
0377 }
0378 };
0379
0380
0381 template<typename IteratorType>
0382 typename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last)
0383 {
0384 using factory_type = iterator_input_adapter_factory<IteratorType>;
0385 return factory_type::create(first, last);
0386 }
0387
0388
0389
0390
0391
0392 namespace container_input_adapter_factory_impl
0393 {
0394
0395 using std::begin;
0396 using std::end;
0397
0398 template<typename ContainerType, typename Enable = void>
0399 struct container_input_adapter_factory {};
0400
0401 template<typename ContainerType>
0402 struct container_input_adapter_factory< ContainerType,
0403 void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>>
0404 {
0405 using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>())));
0406
0407 static adapter_type create(const ContainerType& container)
0408 {
0409 return input_adapter(begin(container), end(container));
0410 }
0411 };
0412
0413 }
0414
0415 template<typename ContainerType>
0416 typename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container)
0417 {
0418 return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container);
0419 }
0420
0421 #ifndef JSON_NO_IO
0422
0423 inline file_input_adapter input_adapter(std::FILE* file)
0424 {
0425 return file_input_adapter(file);
0426 }
0427
0428 inline input_stream_adapter input_adapter(std::istream& stream)
0429 {
0430 return input_stream_adapter(stream);
0431 }
0432
0433 inline input_stream_adapter input_adapter(std::istream&& stream)
0434 {
0435 return input_stream_adapter(stream);
0436 }
0437 #endif
0438
0439 using contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>()));
0440
0441
0442 template < typename CharT,
0443 typename std::enable_if <
0444 std::is_pointer<CharT>::value&&
0445 !std::is_array<CharT>::value&&
0446 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
0447 sizeof(typename std::remove_pointer<CharT>::type) == 1,
0448 int >::type = 0 >
0449 contiguous_bytes_input_adapter input_adapter(CharT b)
0450 {
0451 auto length = std::strlen(reinterpret_cast<const char*>(b));
0452 const auto* ptr = reinterpret_cast<const char*>(b);
0453 return input_adapter(ptr, ptr + length);
0454 }
0455
0456 template<typename T, std::size_t N>
0457 auto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N))
0458 {
0459 return input_adapter(array, array + N);
0460 }
0461
0462
0463
0464
0465 class span_input_adapter
0466 {
0467 public:
0468 template < typename CharT,
0469 typename std::enable_if <
0470 std::is_pointer<CharT>::value&&
0471 std::is_integral<typename std::remove_pointer<CharT>::type>::value&&
0472 sizeof(typename std::remove_pointer<CharT>::type) == 1,
0473 int >::type = 0 >
0474 span_input_adapter(CharT b, std::size_t l)
0475 : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {}
0476
0477 template<class IteratorType,
0478 typename std::enable_if<
0479 std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value,
0480 int>::type = 0>
0481 span_input_adapter(IteratorType first, IteratorType last)
0482 : ia(input_adapter(first, last)) {}
0483
0484 contiguous_bytes_input_adapter&& get()
0485 {
0486 return std::move(ia);
0487 }
0488
0489 private:
0490 contiguous_bytes_input_adapter ia;
0491 };
0492
0493 }
0494 NLOHMANN_JSON_NAMESPACE_END