| 5980 | */ |
| 5981 | template<typename BasicJsonType, typename InputAdapterType> |
| 5982 | class lexer : public lexer_base<BasicJsonType> |
| 5983 | { |
| 5984 | using number_integer_t = typename BasicJsonType::number_integer_t; |
| 5985 | using number_unsigned_t = typename BasicJsonType::number_unsigned_t; |
| 5986 | using number_float_t = typename BasicJsonType::number_float_t; |
| 5987 | using string_t = typename BasicJsonType::string_t; |
| 5988 | using char_type = typename InputAdapterType::char_type; |
| 5989 | using char_int_type = typename std::char_traits<char_type>::int_type; |
| 5990 | |
| 5991 | public: |
| 5992 | using token_type = typename lexer_base<BasicJsonType>::token_type; |
| 5993 | |
| 5994 | explicit lexer(InputAdapterType&& adapter, bool ignore_comments_ = false) |
| 5995 | : ia(std::move(adapter)) |
| 5996 | , ignore_comments(ignore_comments_) |
| 5997 | , decimal_point_char(static_cast<char_int_type>(get_decimal_point())) |
| 5998 | {} |
| 5999 | |
| 6000 | // delete because of pointer members |
| 6001 | lexer(const lexer&) = delete; |
| 6002 | lexer(lexer&&) = default; |
| 6003 | lexer& operator=(lexer&) = delete; |
| 6004 | lexer& operator=(lexer&&) = default; |
| 6005 | ~lexer() = default; |
| 6006 | |
| 6007 | private: |
| 6008 | ///////////////////// |
| 6009 | // locales |
| 6010 | ///////////////////// |
| 6011 | |
| 6012 | /// return the locale-dependent decimal point |
| 6013 | JSON_HEDLEY_PURE |
| 6014 | static char get_decimal_point() noexcept |
| 6015 | { |
| 6016 | const auto* loc = localeconv(); |
| 6017 | JSON_ASSERT(loc != nullptr); |
| 6018 | return (loc->decimal_point == nullptr) ? '.' : *(loc->decimal_point); |
| 6019 | } |
| 6020 | |
| 6021 | ///////////////////// |
| 6022 | // scan functions |
| 6023 | ///////////////////// |
| 6024 | |
| 6025 | /*! |
| 6026 | @brief get codepoint from 4 hex characters following `\u` |
| 6027 | |
| 6028 | For input "\u c1 c2 c3 c4" the codepoint is: |
| 6029 | (c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4 |
| 6030 | = (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0) |
| 6031 | |
| 6032 | Furthermore, the possible characters '0'..'9', 'A'..'F', and 'a'..'f' |
| 6033 | must be converted to the integers 0x0..0x9, 0xA..0xF, 0xA..0xF, resp. The |
| 6034 | conversion is done by subtracting the offset (0x30, 0x37, and 0x57) |
| 6035 | between the ASCII value of the character and the desired integer value. |
| 6036 | |
| 6037 | @return codepoint (0x0000..0xFFFF) or -1 in case of an error (e.g. EOF or |
| 6038 | non-hex character) |
| 6039 | */ |