1c5f01b2fSopenharmony_ci// __ _____ _____ _____ 2c5f01b2fSopenharmony_ci// __| | __| | | | JSON for Modern C++ 3c5f01b2fSopenharmony_ci// | | |__ | | | | | | version 3.11.2 4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___| https://github.com/nlohmann/json 5c5f01b2fSopenharmony_ci// 6c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me> 7c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT 8c5f01b2fSopenharmony_ci 9c5f01b2fSopenharmony_ci#pragma once 10c5f01b2fSopenharmony_ci 11c5f01b2fSopenharmony_ci#include <array> // array 12c5f01b2fSopenharmony_ci#include <cstddef> // size_t 13c5f01b2fSopenharmony_ci#include <cstring> // strlen 14c5f01b2fSopenharmony_ci#include <iterator> // begin, end, iterator_traits, random_access_iterator_tag, distance, next 15c5f01b2fSopenharmony_ci#include <memory> // shared_ptr, make_shared, addressof 16c5f01b2fSopenharmony_ci#include <numeric> // accumulate 17c5f01b2fSopenharmony_ci#include <string> // string, char_traits 18c5f01b2fSopenharmony_ci#include <type_traits> // enable_if, is_base_of, is_pointer, is_integral, remove_pointer 19c5f01b2fSopenharmony_ci#include <utility> // pair, declval 20c5f01b2fSopenharmony_ci 21c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO 22c5f01b2fSopenharmony_ci #include <cstdio> // FILE * 23c5f01b2fSopenharmony_ci #include <istream> // istream 24c5f01b2fSopenharmony_ci#endif // JSON_NO_IO 25c5f01b2fSopenharmony_ci 26c5f01b2fSopenharmony_ci#include <nlohmann/detail/iterators/iterator_traits.hpp> 27c5f01b2fSopenharmony_ci#include <nlohmann/detail/macro_scope.hpp> 28c5f01b2fSopenharmony_ci 29c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_BEGIN 30c5f01b2fSopenharmony_cinamespace detail 31c5f01b2fSopenharmony_ci{ 32c5f01b2fSopenharmony_ci 33c5f01b2fSopenharmony_ci/// the supported input formats 34c5f01b2fSopenharmony_cienum class input_format_t { json, cbor, msgpack, ubjson, bson, bjdata }; 35c5f01b2fSopenharmony_ci 36c5f01b2fSopenharmony_ci//////////////////// 37c5f01b2fSopenharmony_ci// input adapters // 38c5f01b2fSopenharmony_ci//////////////////// 39c5f01b2fSopenharmony_ci 40c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO 41c5f01b2fSopenharmony_ci/*! 42c5f01b2fSopenharmony_ciInput adapter for stdio file access. This adapter read only 1 byte and do not use any 43c5f01b2fSopenharmony_ci buffer. This adapter is a very low level adapter. 44c5f01b2fSopenharmony_ci*/ 45c5f01b2fSopenharmony_ciclass file_input_adapter 46c5f01b2fSopenharmony_ci{ 47c5f01b2fSopenharmony_ci public: 48c5f01b2fSopenharmony_ci using char_type = char; 49c5f01b2fSopenharmony_ci 50c5f01b2fSopenharmony_ci JSON_HEDLEY_NON_NULL(2) 51c5f01b2fSopenharmony_ci explicit file_input_adapter(std::FILE* f) noexcept 52c5f01b2fSopenharmony_ci : m_file(f) 53c5f01b2fSopenharmony_ci { 54c5f01b2fSopenharmony_ci JSON_ASSERT(m_file != nullptr); 55c5f01b2fSopenharmony_ci } 56c5f01b2fSopenharmony_ci 57c5f01b2fSopenharmony_ci // make class move-only 58c5f01b2fSopenharmony_ci file_input_adapter(const file_input_adapter&) = delete; 59c5f01b2fSopenharmony_ci file_input_adapter(file_input_adapter&&) noexcept = default; 60c5f01b2fSopenharmony_ci file_input_adapter& operator=(const file_input_adapter&) = delete; 61c5f01b2fSopenharmony_ci file_input_adapter& operator=(file_input_adapter&&) = delete; 62c5f01b2fSopenharmony_ci ~file_input_adapter() = default; 63c5f01b2fSopenharmony_ci 64c5f01b2fSopenharmony_ci std::char_traits<char>::int_type get_character() noexcept 65c5f01b2fSopenharmony_ci { 66c5f01b2fSopenharmony_ci return std::fgetc(m_file); 67c5f01b2fSopenharmony_ci } 68c5f01b2fSopenharmony_ci 69c5f01b2fSopenharmony_ci private: 70c5f01b2fSopenharmony_ci /// the file pointer to read from 71c5f01b2fSopenharmony_ci std::FILE* m_file; 72c5f01b2fSopenharmony_ci}; 73c5f01b2fSopenharmony_ci 74c5f01b2fSopenharmony_ci 75c5f01b2fSopenharmony_ci/*! 76c5f01b2fSopenharmony_ciInput adapter for a (caching) istream. Ignores a UFT Byte Order Mark at 77c5f01b2fSopenharmony_cibeginning of input. Does not support changing the underlying std::streambuf 78c5f01b2fSopenharmony_ciin mid-input. Maintains underlying std::istream and std::streambuf to support 79c5f01b2fSopenharmony_cisubsequent use of standard std::istream operations to process any input 80c5f01b2fSopenharmony_cicharacters following those used in parsing the JSON input. Clears the 81c5f01b2fSopenharmony_cistd::istream flags; any input errors (e.g., EOF) will be detected by the first 82c5f01b2fSopenharmony_cisubsequent call for input from the std::istream. 83c5f01b2fSopenharmony_ci*/ 84c5f01b2fSopenharmony_ciclass input_stream_adapter 85c5f01b2fSopenharmony_ci{ 86c5f01b2fSopenharmony_ci public: 87c5f01b2fSopenharmony_ci using char_type = char; 88c5f01b2fSopenharmony_ci 89c5f01b2fSopenharmony_ci ~input_stream_adapter() 90c5f01b2fSopenharmony_ci { 91c5f01b2fSopenharmony_ci // clear stream flags; we use underlying streambuf I/O, do not 92c5f01b2fSopenharmony_ci // maintain ifstream flags, except eof 93c5f01b2fSopenharmony_ci if (is != nullptr) 94c5f01b2fSopenharmony_ci { 95c5f01b2fSopenharmony_ci is->clear(is->rdstate() & std::ios::eofbit); 96c5f01b2fSopenharmony_ci } 97c5f01b2fSopenharmony_ci } 98c5f01b2fSopenharmony_ci 99c5f01b2fSopenharmony_ci explicit input_stream_adapter(std::istream& i) 100c5f01b2fSopenharmony_ci : is(&i), sb(i.rdbuf()) 101c5f01b2fSopenharmony_ci {} 102c5f01b2fSopenharmony_ci 103c5f01b2fSopenharmony_ci // delete because of pointer members 104c5f01b2fSopenharmony_ci input_stream_adapter(const input_stream_adapter&) = delete; 105c5f01b2fSopenharmony_ci input_stream_adapter& operator=(input_stream_adapter&) = delete; 106c5f01b2fSopenharmony_ci input_stream_adapter& operator=(input_stream_adapter&&) = delete; 107c5f01b2fSopenharmony_ci 108c5f01b2fSopenharmony_ci input_stream_adapter(input_stream_adapter&& rhs) noexcept 109c5f01b2fSopenharmony_ci : is(rhs.is), sb(rhs.sb) 110c5f01b2fSopenharmony_ci { 111c5f01b2fSopenharmony_ci rhs.is = nullptr; 112c5f01b2fSopenharmony_ci rhs.sb = nullptr; 113c5f01b2fSopenharmony_ci } 114c5f01b2fSopenharmony_ci 115c5f01b2fSopenharmony_ci // std::istream/std::streambuf use std::char_traits<char>::to_int_type, to 116c5f01b2fSopenharmony_ci // ensure that std::char_traits<char>::eof() and the character 0xFF do not 117c5f01b2fSopenharmony_ci // end up as the same value, e.g. 0xFFFFFFFF. 118c5f01b2fSopenharmony_ci std::char_traits<char>::int_type get_character() 119c5f01b2fSopenharmony_ci { 120c5f01b2fSopenharmony_ci auto res = sb->sbumpc(); 121c5f01b2fSopenharmony_ci // set eof manually, as we don't use the istream interface. 122c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(res == std::char_traits<char>::eof())) 123c5f01b2fSopenharmony_ci { 124c5f01b2fSopenharmony_ci is->clear(is->rdstate() | std::ios::eofbit); 125c5f01b2fSopenharmony_ci } 126c5f01b2fSopenharmony_ci return res; 127c5f01b2fSopenharmony_ci } 128c5f01b2fSopenharmony_ci 129c5f01b2fSopenharmony_ci private: 130c5f01b2fSopenharmony_ci /// the associated input stream 131c5f01b2fSopenharmony_ci std::istream* is = nullptr; 132c5f01b2fSopenharmony_ci std::streambuf* sb = nullptr; 133c5f01b2fSopenharmony_ci}; 134c5f01b2fSopenharmony_ci#endif // JSON_NO_IO 135c5f01b2fSopenharmony_ci 136c5f01b2fSopenharmony_ci// General-purpose iterator-based adapter. It might not be as fast as 137c5f01b2fSopenharmony_ci// theoretically possible for some containers, but it is extremely versatile. 138c5f01b2fSopenharmony_citemplate<typename IteratorType> 139c5f01b2fSopenharmony_ciclass iterator_input_adapter 140c5f01b2fSopenharmony_ci{ 141c5f01b2fSopenharmony_ci public: 142c5f01b2fSopenharmony_ci using char_type = typename std::iterator_traits<IteratorType>::value_type; 143c5f01b2fSopenharmony_ci 144c5f01b2fSopenharmony_ci iterator_input_adapter(IteratorType first, IteratorType last) 145c5f01b2fSopenharmony_ci : current(std::move(first)), end(std::move(last)) 146c5f01b2fSopenharmony_ci {} 147c5f01b2fSopenharmony_ci 148c5f01b2fSopenharmony_ci typename std::char_traits<char_type>::int_type get_character() 149c5f01b2fSopenharmony_ci { 150c5f01b2fSopenharmony_ci if (JSON_HEDLEY_LIKELY(current != end)) 151c5f01b2fSopenharmony_ci { 152c5f01b2fSopenharmony_ci auto result = std::char_traits<char_type>::to_int_type(*current); 153c5f01b2fSopenharmony_ci std::advance(current, 1); 154c5f01b2fSopenharmony_ci return result; 155c5f01b2fSopenharmony_ci } 156c5f01b2fSopenharmony_ci 157c5f01b2fSopenharmony_ci return std::char_traits<char_type>::eof(); 158c5f01b2fSopenharmony_ci } 159c5f01b2fSopenharmony_ci 160c5f01b2fSopenharmony_ci private: 161c5f01b2fSopenharmony_ci IteratorType current; 162c5f01b2fSopenharmony_ci IteratorType end; 163c5f01b2fSopenharmony_ci 164c5f01b2fSopenharmony_ci template<typename BaseInputAdapter, size_t T> 165c5f01b2fSopenharmony_ci friend struct wide_string_input_helper; 166c5f01b2fSopenharmony_ci 167c5f01b2fSopenharmony_ci bool empty() const 168c5f01b2fSopenharmony_ci { 169c5f01b2fSopenharmony_ci return current == end; 170c5f01b2fSopenharmony_ci } 171c5f01b2fSopenharmony_ci}; 172c5f01b2fSopenharmony_ci 173c5f01b2fSopenharmony_ci 174c5f01b2fSopenharmony_citemplate<typename BaseInputAdapter, size_t T> 175c5f01b2fSopenharmony_cistruct wide_string_input_helper; 176c5f01b2fSopenharmony_ci 177c5f01b2fSopenharmony_citemplate<typename BaseInputAdapter> 178c5f01b2fSopenharmony_cistruct wide_string_input_helper<BaseInputAdapter, 4> 179c5f01b2fSopenharmony_ci{ 180c5f01b2fSopenharmony_ci // UTF-32 181c5f01b2fSopenharmony_ci static void fill_buffer(BaseInputAdapter& input, 182c5f01b2fSopenharmony_ci std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, 183c5f01b2fSopenharmony_ci size_t& utf8_bytes_index, 184c5f01b2fSopenharmony_ci size_t& utf8_bytes_filled) 185c5f01b2fSopenharmony_ci { 186c5f01b2fSopenharmony_ci utf8_bytes_index = 0; 187c5f01b2fSopenharmony_ci 188c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(input.empty())) 189c5f01b2fSopenharmony_ci { 190c5f01b2fSopenharmony_ci utf8_bytes[0] = std::char_traits<char>::eof(); 191c5f01b2fSopenharmony_ci utf8_bytes_filled = 1; 192c5f01b2fSopenharmony_ci } 193c5f01b2fSopenharmony_ci else 194c5f01b2fSopenharmony_ci { 195c5f01b2fSopenharmony_ci // get the current character 196c5f01b2fSopenharmony_ci const auto wc = input.get_character(); 197c5f01b2fSopenharmony_ci 198c5f01b2fSopenharmony_ci // UTF-32 to UTF-8 encoding 199c5f01b2fSopenharmony_ci if (wc < 0x80) 200c5f01b2fSopenharmony_ci { 201c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); 202c5f01b2fSopenharmony_ci utf8_bytes_filled = 1; 203c5f01b2fSopenharmony_ci } 204c5f01b2fSopenharmony_ci else if (wc <= 0x7FF) 205c5f01b2fSopenharmony_ci { 206c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u) & 0x1Fu)); 207c5f01b2fSopenharmony_ci utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); 208c5f01b2fSopenharmony_ci utf8_bytes_filled = 2; 209c5f01b2fSopenharmony_ci } 210c5f01b2fSopenharmony_ci else if (wc <= 0xFFFF) 211c5f01b2fSopenharmony_ci { 212c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u) & 0x0Fu)); 213c5f01b2fSopenharmony_ci utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); 214c5f01b2fSopenharmony_ci utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); 215c5f01b2fSopenharmony_ci utf8_bytes_filled = 3; 216c5f01b2fSopenharmony_ci } 217c5f01b2fSopenharmony_ci else if (wc <= 0x10FFFF) 218c5f01b2fSopenharmony_ci { 219c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | ((static_cast<unsigned int>(wc) >> 18u) & 0x07u)); 220c5f01b2fSopenharmony_ci utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 12u) & 0x3Fu)); 221c5f01b2fSopenharmony_ci utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); 222c5f01b2fSopenharmony_ci utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); 223c5f01b2fSopenharmony_ci utf8_bytes_filled = 4; 224c5f01b2fSopenharmony_ci } 225c5f01b2fSopenharmony_ci else 226c5f01b2fSopenharmony_ci { 227c5f01b2fSopenharmony_ci // unknown character 228c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); 229c5f01b2fSopenharmony_ci utf8_bytes_filled = 1; 230c5f01b2fSopenharmony_ci } 231c5f01b2fSopenharmony_ci } 232c5f01b2fSopenharmony_ci } 233c5f01b2fSopenharmony_ci}; 234c5f01b2fSopenharmony_ci 235c5f01b2fSopenharmony_citemplate<typename BaseInputAdapter> 236c5f01b2fSopenharmony_cistruct wide_string_input_helper<BaseInputAdapter, 2> 237c5f01b2fSopenharmony_ci{ 238c5f01b2fSopenharmony_ci // UTF-16 239c5f01b2fSopenharmony_ci static void fill_buffer(BaseInputAdapter& input, 240c5f01b2fSopenharmony_ci std::array<std::char_traits<char>::int_type, 4>& utf8_bytes, 241c5f01b2fSopenharmony_ci size_t& utf8_bytes_index, 242c5f01b2fSopenharmony_ci size_t& utf8_bytes_filled) 243c5f01b2fSopenharmony_ci { 244c5f01b2fSopenharmony_ci utf8_bytes_index = 0; 245c5f01b2fSopenharmony_ci 246c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(input.empty())) 247c5f01b2fSopenharmony_ci { 248c5f01b2fSopenharmony_ci utf8_bytes[0] = std::char_traits<char>::eof(); 249c5f01b2fSopenharmony_ci utf8_bytes_filled = 1; 250c5f01b2fSopenharmony_ci } 251c5f01b2fSopenharmony_ci else 252c5f01b2fSopenharmony_ci { 253c5f01b2fSopenharmony_ci // get the current character 254c5f01b2fSopenharmony_ci const auto wc = input.get_character(); 255c5f01b2fSopenharmony_ci 256c5f01b2fSopenharmony_ci // UTF-16 to UTF-8 encoding 257c5f01b2fSopenharmony_ci if (wc < 0x80) 258c5f01b2fSopenharmony_ci { 259c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); 260c5f01b2fSopenharmony_ci utf8_bytes_filled = 1; 261c5f01b2fSopenharmony_ci } 262c5f01b2fSopenharmony_ci else if (wc <= 0x7FF) 263c5f01b2fSopenharmony_ci { 264c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xC0u | ((static_cast<unsigned int>(wc) >> 6u))); 265c5f01b2fSopenharmony_ci utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); 266c5f01b2fSopenharmony_ci utf8_bytes_filled = 2; 267c5f01b2fSopenharmony_ci } 268c5f01b2fSopenharmony_ci else if (0xD800 > wc || wc >= 0xE000) 269c5f01b2fSopenharmony_ci { 270c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xE0u | ((static_cast<unsigned int>(wc) >> 12u))); 271c5f01b2fSopenharmony_ci utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((static_cast<unsigned int>(wc) >> 6u) & 0x3Fu)); 272c5f01b2fSopenharmony_ci utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | (static_cast<unsigned int>(wc) & 0x3Fu)); 273c5f01b2fSopenharmony_ci utf8_bytes_filled = 3; 274c5f01b2fSopenharmony_ci } 275c5f01b2fSopenharmony_ci else 276c5f01b2fSopenharmony_ci { 277c5f01b2fSopenharmony_ci if (JSON_HEDLEY_UNLIKELY(!input.empty())) 278c5f01b2fSopenharmony_ci { 279c5f01b2fSopenharmony_ci const auto wc2 = static_cast<unsigned int>(input.get_character()); 280c5f01b2fSopenharmony_ci const auto charcode = 0x10000u + (((static_cast<unsigned int>(wc) & 0x3FFu) << 10u) | (wc2 & 0x3FFu)); 281c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(0xF0u | (charcode >> 18u)); 282c5f01b2fSopenharmony_ci utf8_bytes[1] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 12u) & 0x3Fu)); 283c5f01b2fSopenharmony_ci utf8_bytes[2] = static_cast<std::char_traits<char>::int_type>(0x80u | ((charcode >> 6u) & 0x3Fu)); 284c5f01b2fSopenharmony_ci utf8_bytes[3] = static_cast<std::char_traits<char>::int_type>(0x80u | (charcode & 0x3Fu)); 285c5f01b2fSopenharmony_ci utf8_bytes_filled = 4; 286c5f01b2fSopenharmony_ci } 287c5f01b2fSopenharmony_ci else 288c5f01b2fSopenharmony_ci { 289c5f01b2fSopenharmony_ci utf8_bytes[0] = static_cast<std::char_traits<char>::int_type>(wc); 290c5f01b2fSopenharmony_ci utf8_bytes_filled = 1; 291c5f01b2fSopenharmony_ci } 292c5f01b2fSopenharmony_ci } 293c5f01b2fSopenharmony_ci } 294c5f01b2fSopenharmony_ci } 295c5f01b2fSopenharmony_ci}; 296c5f01b2fSopenharmony_ci 297c5f01b2fSopenharmony_ci// Wraps another input apdater to convert wide character types into individual bytes. 298c5f01b2fSopenharmony_citemplate<typename BaseInputAdapter, typename WideCharType> 299c5f01b2fSopenharmony_ciclass wide_string_input_adapter 300c5f01b2fSopenharmony_ci{ 301c5f01b2fSopenharmony_ci public: 302c5f01b2fSopenharmony_ci using char_type = char; 303c5f01b2fSopenharmony_ci 304c5f01b2fSopenharmony_ci wide_string_input_adapter(BaseInputAdapter base) 305c5f01b2fSopenharmony_ci : base_adapter(base) {} 306c5f01b2fSopenharmony_ci 307c5f01b2fSopenharmony_ci typename std::char_traits<char>::int_type get_character() noexcept 308c5f01b2fSopenharmony_ci { 309c5f01b2fSopenharmony_ci // check if buffer needs to be filled 310c5f01b2fSopenharmony_ci if (utf8_bytes_index == utf8_bytes_filled) 311c5f01b2fSopenharmony_ci { 312c5f01b2fSopenharmony_ci fill_buffer<sizeof(WideCharType)>(); 313c5f01b2fSopenharmony_ci 314c5f01b2fSopenharmony_ci JSON_ASSERT(utf8_bytes_filled > 0); 315c5f01b2fSopenharmony_ci JSON_ASSERT(utf8_bytes_index == 0); 316c5f01b2fSopenharmony_ci } 317c5f01b2fSopenharmony_ci 318c5f01b2fSopenharmony_ci // use buffer 319c5f01b2fSopenharmony_ci JSON_ASSERT(utf8_bytes_filled > 0); 320c5f01b2fSopenharmony_ci JSON_ASSERT(utf8_bytes_index < utf8_bytes_filled); 321c5f01b2fSopenharmony_ci return utf8_bytes[utf8_bytes_index++]; 322c5f01b2fSopenharmony_ci } 323c5f01b2fSopenharmony_ci 324c5f01b2fSopenharmony_ci private: 325c5f01b2fSopenharmony_ci BaseInputAdapter base_adapter; 326c5f01b2fSopenharmony_ci 327c5f01b2fSopenharmony_ci template<size_t T> 328c5f01b2fSopenharmony_ci void fill_buffer() 329c5f01b2fSopenharmony_ci { 330c5f01b2fSopenharmony_ci wide_string_input_helper<BaseInputAdapter, T>::fill_buffer(base_adapter, utf8_bytes, utf8_bytes_index, utf8_bytes_filled); 331c5f01b2fSopenharmony_ci } 332c5f01b2fSopenharmony_ci 333c5f01b2fSopenharmony_ci /// a buffer for UTF-8 bytes 334c5f01b2fSopenharmony_ci std::array<std::char_traits<char>::int_type, 4> utf8_bytes = {{0, 0, 0, 0}}; 335c5f01b2fSopenharmony_ci 336c5f01b2fSopenharmony_ci /// index to the utf8_codes array for the next valid byte 337c5f01b2fSopenharmony_ci std::size_t utf8_bytes_index = 0; 338c5f01b2fSopenharmony_ci /// number of valid bytes in the utf8_codes array 339c5f01b2fSopenharmony_ci std::size_t utf8_bytes_filled = 0; 340c5f01b2fSopenharmony_ci}; 341c5f01b2fSopenharmony_ci 342c5f01b2fSopenharmony_ci 343c5f01b2fSopenharmony_citemplate<typename IteratorType, typename Enable = void> 344c5f01b2fSopenharmony_cistruct iterator_input_adapter_factory 345c5f01b2fSopenharmony_ci{ 346c5f01b2fSopenharmony_ci using iterator_type = IteratorType; 347c5f01b2fSopenharmony_ci using char_type = typename std::iterator_traits<iterator_type>::value_type; 348c5f01b2fSopenharmony_ci using adapter_type = iterator_input_adapter<iterator_type>; 349c5f01b2fSopenharmony_ci 350c5f01b2fSopenharmony_ci static adapter_type create(IteratorType first, IteratorType last) 351c5f01b2fSopenharmony_ci { 352c5f01b2fSopenharmony_ci return adapter_type(std::move(first), std::move(last)); 353c5f01b2fSopenharmony_ci } 354c5f01b2fSopenharmony_ci}; 355c5f01b2fSopenharmony_ci 356c5f01b2fSopenharmony_citemplate<typename T> 357c5f01b2fSopenharmony_cistruct is_iterator_of_multibyte 358c5f01b2fSopenharmony_ci{ 359c5f01b2fSopenharmony_ci using value_type = typename std::iterator_traits<T>::value_type; 360c5f01b2fSopenharmony_ci enum 361c5f01b2fSopenharmony_ci { 362c5f01b2fSopenharmony_ci value = sizeof(value_type) > 1 363c5f01b2fSopenharmony_ci }; 364c5f01b2fSopenharmony_ci}; 365c5f01b2fSopenharmony_ci 366c5f01b2fSopenharmony_citemplate<typename IteratorType> 367c5f01b2fSopenharmony_cistruct iterator_input_adapter_factory<IteratorType, enable_if_t<is_iterator_of_multibyte<IteratorType>::value>> 368c5f01b2fSopenharmony_ci{ 369c5f01b2fSopenharmony_ci using iterator_type = IteratorType; 370c5f01b2fSopenharmony_ci using char_type = typename std::iterator_traits<iterator_type>::value_type; 371c5f01b2fSopenharmony_ci using base_adapter_type = iterator_input_adapter<iterator_type>; 372c5f01b2fSopenharmony_ci using adapter_type = wide_string_input_adapter<base_adapter_type, char_type>; 373c5f01b2fSopenharmony_ci 374c5f01b2fSopenharmony_ci static adapter_type create(IteratorType first, IteratorType last) 375c5f01b2fSopenharmony_ci { 376c5f01b2fSopenharmony_ci return adapter_type(base_adapter_type(std::move(first), std::move(last))); 377c5f01b2fSopenharmony_ci } 378c5f01b2fSopenharmony_ci}; 379c5f01b2fSopenharmony_ci 380c5f01b2fSopenharmony_ci// General purpose iterator-based input 381c5f01b2fSopenharmony_citemplate<typename IteratorType> 382c5f01b2fSopenharmony_citypename iterator_input_adapter_factory<IteratorType>::adapter_type input_adapter(IteratorType first, IteratorType last) 383c5f01b2fSopenharmony_ci{ 384c5f01b2fSopenharmony_ci using factory_type = iterator_input_adapter_factory<IteratorType>; 385c5f01b2fSopenharmony_ci return factory_type::create(first, last); 386c5f01b2fSopenharmony_ci} 387c5f01b2fSopenharmony_ci 388c5f01b2fSopenharmony_ci// Convenience shorthand from container to iterator 389c5f01b2fSopenharmony_ci// Enables ADL on begin(container) and end(container) 390c5f01b2fSopenharmony_ci// Encloses the using declarations in namespace for not to leak them to outside scope 391c5f01b2fSopenharmony_ci 392c5f01b2fSopenharmony_cinamespace container_input_adapter_factory_impl 393c5f01b2fSopenharmony_ci{ 394c5f01b2fSopenharmony_ci 395c5f01b2fSopenharmony_ciusing std::begin; 396c5f01b2fSopenharmony_ciusing std::end; 397c5f01b2fSopenharmony_ci 398c5f01b2fSopenharmony_citemplate<typename ContainerType, typename Enable = void> 399c5f01b2fSopenharmony_cistruct container_input_adapter_factory {}; 400c5f01b2fSopenharmony_ci 401c5f01b2fSopenharmony_citemplate<typename ContainerType> 402c5f01b2fSopenharmony_cistruct container_input_adapter_factory< ContainerType, 403c5f01b2fSopenharmony_ci void_t<decltype(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))>> 404c5f01b2fSopenharmony_ci { 405c5f01b2fSopenharmony_ci using adapter_type = decltype(input_adapter(begin(std::declval<ContainerType>()), end(std::declval<ContainerType>()))); 406c5f01b2fSopenharmony_ci 407c5f01b2fSopenharmony_ci static adapter_type create(const ContainerType& container) 408c5f01b2fSopenharmony_ci{ 409c5f01b2fSopenharmony_ci return input_adapter(begin(container), end(container)); 410c5f01b2fSopenharmony_ci} 411c5f01b2fSopenharmony_ci }; 412c5f01b2fSopenharmony_ci 413c5f01b2fSopenharmony_ci} // namespace container_input_adapter_factory_impl 414c5f01b2fSopenharmony_ci 415c5f01b2fSopenharmony_citemplate<typename ContainerType> 416c5f01b2fSopenharmony_citypename container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::adapter_type input_adapter(const ContainerType& container) 417c5f01b2fSopenharmony_ci{ 418c5f01b2fSopenharmony_ci return container_input_adapter_factory_impl::container_input_adapter_factory<ContainerType>::create(container); 419c5f01b2fSopenharmony_ci} 420c5f01b2fSopenharmony_ci 421c5f01b2fSopenharmony_ci#ifndef JSON_NO_IO 422c5f01b2fSopenharmony_ci// Special cases with fast paths 423c5f01b2fSopenharmony_ciinline file_input_adapter input_adapter(std::FILE* file) 424c5f01b2fSopenharmony_ci{ 425c5f01b2fSopenharmony_ci return file_input_adapter(file); 426c5f01b2fSopenharmony_ci} 427c5f01b2fSopenharmony_ci 428c5f01b2fSopenharmony_ciinline input_stream_adapter input_adapter(std::istream& stream) 429c5f01b2fSopenharmony_ci{ 430c5f01b2fSopenharmony_ci return input_stream_adapter(stream); 431c5f01b2fSopenharmony_ci} 432c5f01b2fSopenharmony_ci 433c5f01b2fSopenharmony_ciinline input_stream_adapter input_adapter(std::istream&& stream) 434c5f01b2fSopenharmony_ci{ 435c5f01b2fSopenharmony_ci return input_stream_adapter(stream); 436c5f01b2fSopenharmony_ci} 437c5f01b2fSopenharmony_ci#endif // JSON_NO_IO 438c5f01b2fSopenharmony_ci 439c5f01b2fSopenharmony_ciusing contiguous_bytes_input_adapter = decltype(input_adapter(std::declval<const char*>(), std::declval<const char*>())); 440c5f01b2fSopenharmony_ci 441c5f01b2fSopenharmony_ci// Null-delimited strings, and the like. 442c5f01b2fSopenharmony_citemplate < typename CharT, 443c5f01b2fSopenharmony_ci typename std::enable_if < 444c5f01b2fSopenharmony_ci std::is_pointer<CharT>::value&& 445c5f01b2fSopenharmony_ci !std::is_array<CharT>::value&& 446c5f01b2fSopenharmony_ci std::is_integral<typename std::remove_pointer<CharT>::type>::value&& 447c5f01b2fSopenharmony_ci sizeof(typename std::remove_pointer<CharT>::type) == 1, 448c5f01b2fSopenharmony_ci int >::type = 0 > 449c5f01b2fSopenharmony_cicontiguous_bytes_input_adapter input_adapter(CharT b) 450c5f01b2fSopenharmony_ci{ 451c5f01b2fSopenharmony_ci auto length = std::strlen(reinterpret_cast<const char*>(b)); 452c5f01b2fSopenharmony_ci const auto* ptr = reinterpret_cast<const char*>(b); 453c5f01b2fSopenharmony_ci return input_adapter(ptr, ptr + length); 454c5f01b2fSopenharmony_ci} 455c5f01b2fSopenharmony_ci 456c5f01b2fSopenharmony_citemplate<typename T, std::size_t N> 457c5f01b2fSopenharmony_ciauto input_adapter(T (&array)[N]) -> decltype(input_adapter(array, array + N)) // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays) 458c5f01b2fSopenharmony_ci{ 459c5f01b2fSopenharmony_ci return input_adapter(array, array + N); 460c5f01b2fSopenharmony_ci} 461c5f01b2fSopenharmony_ci 462c5f01b2fSopenharmony_ci// This class only handles inputs of input_buffer_adapter type. 463c5f01b2fSopenharmony_ci// It's required so that expressions like {ptr, len} can be implicitly cast 464c5f01b2fSopenharmony_ci// to the correct adapter. 465c5f01b2fSopenharmony_ciclass span_input_adapter 466c5f01b2fSopenharmony_ci{ 467c5f01b2fSopenharmony_ci public: 468c5f01b2fSopenharmony_ci template < typename CharT, 469c5f01b2fSopenharmony_ci typename std::enable_if < 470c5f01b2fSopenharmony_ci std::is_pointer<CharT>::value&& 471c5f01b2fSopenharmony_ci std::is_integral<typename std::remove_pointer<CharT>::type>::value&& 472c5f01b2fSopenharmony_ci sizeof(typename std::remove_pointer<CharT>::type) == 1, 473c5f01b2fSopenharmony_ci int >::type = 0 > 474c5f01b2fSopenharmony_ci span_input_adapter(CharT b, std::size_t l) 475c5f01b2fSopenharmony_ci : ia(reinterpret_cast<const char*>(b), reinterpret_cast<const char*>(b) + l) {} 476c5f01b2fSopenharmony_ci 477c5f01b2fSopenharmony_ci template<class IteratorType, 478c5f01b2fSopenharmony_ci typename std::enable_if< 479c5f01b2fSopenharmony_ci std::is_same<typename iterator_traits<IteratorType>::iterator_category, std::random_access_iterator_tag>::value, 480c5f01b2fSopenharmony_ci int>::type = 0> 481c5f01b2fSopenharmony_ci span_input_adapter(IteratorType first, IteratorType last) 482c5f01b2fSopenharmony_ci : ia(input_adapter(first, last)) {} 483c5f01b2fSopenharmony_ci 484c5f01b2fSopenharmony_ci contiguous_bytes_input_adapter&& get() 485c5f01b2fSopenharmony_ci { 486c5f01b2fSopenharmony_ci return std::move(ia); // NOLINT(hicpp-move-const-arg,performance-move-const-arg) 487c5f01b2fSopenharmony_ci } 488c5f01b2fSopenharmony_ci 489c5f01b2fSopenharmony_ci private: 490c5f01b2fSopenharmony_ci contiguous_bytes_input_adapter ia; 491c5f01b2fSopenharmony_ci}; 492c5f01b2fSopenharmony_ci 493c5f01b2fSopenharmony_ci} // namespace detail 494c5f01b2fSopenharmony_ciNLOHMANN_JSON_NAMESPACE_END 495