diff --git a/json11.cpp b/json11.cpp index e3dc119..ac9d727 100644 --- a/json11.cpp +++ b/json11.cpp @@ -61,6 +61,12 @@ static void dump(int value, string &out) { out += buf; } +static void dump(int64_ value, string &out) { + char buf[64]; + snprintf(buf, sizeof buf, "%ld", value); + out += buf; +} + static void dump(bool value, string &out) { out += value ? "true" : "false"; } @@ -164,6 +170,7 @@ protected: class JsonDouble final : public Value { double number_value() const override { return m_value; } int int_value() const override { return static_cast(m_value); } + int64_ int64_value() const override { return static_cast(m_value); } bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } bool less(const JsonValue * other) const override { return m_value < other->number_value(); } public: @@ -173,12 +180,23 @@ public: class JsonInt final : public Value { double number_value() const override { return m_value; } int int_value() const override { return m_value; } + int64_ int64_value() const override { return m_value; } bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } bool less(const JsonValue * other) const override { return m_value < other->number_value(); } public: explicit JsonInt(int value) : Value(value) {} }; +class JsonInt64 final : public Value { + double number_value() const override { return m_value; } + int int_value() const override { return m_value; } + int64_ int64_value() const override { return m_value; } + bool equals(const JsonValue * other) const override { return m_value == other->number_value(); } + bool less(const JsonValue * other) const override { return m_value < other->number_value(); } +public: + explicit JsonInt64(int64_ value) : Value(value) {} +}; + class JsonBoolean final : public Value { bool bool_value() const override { return m_value; } public: @@ -244,7 +262,8 @@ static const Json & static_null() { Json::Json() noexcept : m_ptr(statics().null) {} Json::Json(std::nullptr_t) noexcept : m_ptr(statics().null) {} Json::Json(double value) : m_ptr(make_shared(value)) {} -Json::Json(int value) : m_ptr(make_shared(value)) {} +Json::Json(int value) : m_ptr(make_shared(value)) {} +Json::Json(int64_ value) : m_ptr(make_shared(value)) {} Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {} Json::Json(const string &value) : m_ptr(make_shared(value)) {} Json::Json(string &&value) : m_ptr(make_shared(move(value))) {} @@ -260,7 +279,8 @@ Json::Json(Json::object &&values) : m_ptr(make_shared(move(valu Json::Type Json::type() const { return m_ptr->type(); } double Json::number_value() const { return m_ptr->number_value(); } -int Json::int_value() const { return m_ptr->int_value(); } +int Json::int_value() const { return m_ptr->int_value(); } +int64_ Json::int64_value() const { return m_ptr->int64_value(); } bool Json::bool_value() const { return m_ptr->bool_value(); } const string & Json::string_value() const { return m_ptr->string_value(); } const vector & Json::array_items() const { return m_ptr->array_items(); } @@ -269,7 +289,8 @@ const Json & Json::operator[] (size_t i) const { return (*m_ptr)[i]; const Json & Json::operator[] (const string &key) const { return (*m_ptr)[key]; } double JsonValue::number_value() const { return 0; } -int JsonValue::int_value() const { return 0; } +int JsonValue::int_value() const { return 0; } +int64_ JsonValue::int64_value() const { return 0; } bool JsonValue::bool_value() const { return false; } const string & JsonValue::string_value() const { return statics().empty_string; } const vector & JsonValue::array_items() const { return statics().empty_vector; } @@ -581,9 +602,12 @@ struct JsonParser final { return fail("invalid " + esc(str[i]) + " in number"); } - if (str[i] != '.' && str[i] != 'e' && str[i] != 'E' - && (i - start_pos) <= static_cast(std::numeric_limits::digits10)) { - return std::atoi(str.c_str() + start_pos); + if (str[i] != '.' && str[i] != 'e' && str[i] != 'E') + { + if ((i - start_pos) <= static_cast(std::numeric_limits::digits10)) + return (int)(std::atoll(str.c_str() + start_pos)); + if ((i - start_pos) <= static_cast(std::numeric_limits::digits10)) + return (int64_)(std::atoll(str.c_str() + start_pos)); } // Decimal part diff --git a/json11.hpp b/json11.hpp index 5202ef9..f26d4f2 100644 --- a/json11.hpp +++ b/json11.hpp @@ -55,6 +55,7 @@ #include #include #include +#include #ifdef _MSC_VER #if _MSC_VER <= 1800 // VS 2013 @@ -76,6 +77,8 @@ enum JsonParse { class JsonValue; +using int64_ = int64_t; + class Json final { public: // Types @@ -91,7 +94,8 @@ public: Json() noexcept; // NUL Json(std::nullptr_t) noexcept; // NUL Json(double value); // NUMBER - Json(int value); // NUMBER + Json(int value); // NUMBER + Json(int64_ value); // NUMBER Json(bool value); // BOOL Json(const std::string &value); // STRING Json(std::string &&value); // STRING @@ -133,10 +137,11 @@ public: bool is_object() const { return type() == OBJECT; } // Return the enclosed value if this is a number, 0 otherwise. Note that json11 does not - // distinguish between integer and non-integer numbers - number_value() and int_value() + // distinguish between integer and non-integer numbers - number_value() and int64_value() // can both be applied to a NUMBER-typed object. double number_value() const; int int_value() const; + int64_ int64_value() const; // Return the enclosed value if this is a boolean, false otherwise. bool bool_value() const; @@ -213,6 +218,7 @@ class JsonValue { protected: friend class Json; friend class JsonInt; + friend class JsonInt64; friend class JsonDouble; virtual Json::Type type() const = 0; virtual bool equals(const JsonValue * other) const = 0; @@ -220,6 +226,7 @@ protected: virtual void dump(std::string &out) const = 0; virtual double number_value() const; virtual int int_value() const; + virtual int64_ int64_value() const; virtual bool bool_value() const; virtual const std::string &string_value() const; virtual const Json::array &array_items() const; diff --git a/test.cpp b/test.cpp index cf9a46f..fee132c 100644 --- a/test.cpp +++ b/test.cpp @@ -59,6 +59,28 @@ CHECK_TRAIT(is_nothrow_move_assignable); CHECK_TRAIT(is_nothrow_destructible); JSON11_TEST_CASE(json11_test) { + + std::cout << "int int64 test" << std::endl; + + const string str_it = R"({"message_id":105308320612483198,"msg_type":3,"order":0, + "ques_id":0,"session_id":105308187502051928,"site_id":122062, + "timestamp":1471140271, + "visitor_id":9941658010949867158,"worker_id":133746})"; + string err_it; + auto json_it = Json::parse(str_it, err_it); + + assert(json_it["message_id"].int64_value() == 105308320612483198); + assert(json_it["message_id"].int_value() != 105308320612483198); + assert(json_it["msg_type"].int64_value() == 3); + assert(json_it["msg_type"].int_value() == 3); + assert(json_it["order"].int64_value() == 0); + assert(json_it["session_id"].int64_value() == 105308187502051928); + assert(json_it["site_id"].int_value() == 122062); + assert(json_it["site_id"].int64_value() == 122062); + std::cout << (unsigned long long)json_it["visitor_id"].int64_value() << std::endl; + assert((unsigned long long)(json_it["visitor_id"].int64_value()) == 9941658010949867158); + std::cout << "int int64 test passed!" << std::endl; + const string simple_test = R"({"k1":"v1", "k2":42, "k3":["a",123,true,false,null]})";