瀏覽代碼

AK: Allow JsonValue to store 64-bit integers internally

Add dedicated internal types for Int64 and UnsignedInt64. This makes it
a bit more straightforward to work with 64-bit numbers (instead of just
implicitly storing them as doubles.)
Andreas Kling 5 年之前
父節點
當前提交
014f8ca8c4
共有 6 個文件被更改,包括 119 次插入86 次删除
  1. 10 4
      AK/JsonObject.h
  2. 15 8
      AK/JsonValue.cpp
  3. 64 56
      AK/JsonValue.h
  4. 10 10
      Kernel/FileSystem/ProcFS.cpp
  5. 2 4
      Libraries/LibGUI/GJsonArrayModel.cpp
  6. 18 4
      Libraries/LibGUI/GVariant.cpp

+ 10 - 4
AK/JsonObject.h

@@ -120,11 +120,17 @@ void JsonValue::serialize(Builder& builder) const
         builder.appendf("%g", m_value.as_double);
         builder.appendf("%g", m_value.as_double);
         break;
         break;
 #endif
 #endif
-    case Type::Int:
-        builder.appendf("%d", m_value.as_int);
+    case Type::Int32:
+        builder.appendf("%d", as_i32());
         break;
         break;
-    case Type::UnsignedInt:
-        builder.appendf("%u", m_value.as_uint);
+    case Type::Int64:
+        builder.appendf("%lld", as_i64());
+        break;
+    case Type::UnsignedInt32:
+        builder.appendf("%u", as_u32());
+        break;
+    case Type::UnsignedInt64:
+        builder.appendf("%llu", as_u64());
         break;
         break;
     case Type::Undefined:
     case Type::Undefined:
         builder.append("undefined");
         builder.append("undefined");

+ 15 - 8
AK/JsonValue.cpp

@@ -63,21 +63,28 @@ JsonValue& JsonValue::operator=(JsonValue&& other)
     return *this;
     return *this;
 }
 }
 
 
-JsonValue::JsonValue(int value)
-    : m_type(Type::Int)
+JsonValue::JsonValue(i32 value)
+    : m_type(Type::Int32)
 {
 {
-    m_value.as_int = value;
+    m_value.as_i32 = value;
 }
 }
 
 
-JsonValue::JsonValue(long unsigned value)
-    : JsonValue((unsigned)value)
+JsonValue::JsonValue(u32 value)
+    : m_type(Type::UnsignedInt32)
 {
 {
+    m_value.as_u32 = value;
 }
 }
 
 
-JsonValue::JsonValue(unsigned value)
-    : m_type(Type::UnsignedInt)
+JsonValue::JsonValue(i64 value)
+    : m_type(Type::Int64)
 {
 {
-    m_value.as_uint = value;
+    m_value.as_i64 = value;
+}
+
+JsonValue::JsonValue(u64 value)
+    : m_type(Type::UnsignedInt64)
+{
+    m_value.as_u64 = value;
 }
 }
 
 
 JsonValue::JsonValue(const char* cstring)
 JsonValue::JsonValue(const char* cstring)

+ 64 - 56
AK/JsonValue.h

@@ -1,8 +1,8 @@
 #pragma once
 #pragma once
 
 
-#include <AK/String.h>
 #include <AK/IPv4Address.h>
 #include <AK/IPv4Address.h>
 #include <AK/Optional.h>
 #include <AK/Optional.h>
+#include <AK/String.h>
 #include <AK/StringBuilder.h>
 #include <AK/StringBuilder.h>
 
 
 namespace AK {
 namespace AK {
@@ -16,8 +16,10 @@ public:
     enum class Type {
     enum class Type {
         Undefined,
         Undefined,
         Null,
         Null,
-        Int,
-        UnsignedInt,
+        Int32,
+        UnsignedInt32,
+        Int64,
+        UnsignedInt64,
 #ifndef KERNEL
 #ifndef KERNEL
         Double,
         Double,
 #endif
 #endif
@@ -38,9 +40,11 @@ public:
     JsonValue& operator=(const JsonValue&);
     JsonValue& operator=(const JsonValue&);
     JsonValue& operator=(JsonValue&&);
     JsonValue& operator=(JsonValue&&);
 
 
-    JsonValue(int);
-    JsonValue(unsigned);
-    JsonValue(long unsigned);
+    JsonValue(i32);
+    JsonValue(u32);
+    JsonValue(i64);
+    JsonValue(u64);
+
 #ifndef KERNEL
 #ifndef KERNEL
     JsonValue(double);
     JsonValue(double);
 #endif
 #endif
@@ -84,49 +88,41 @@ public:
         return IPv4Address::from_string(as_string());
         return IPv4Address::from_string(as_string());
     }
     }
 
 
-    int to_int(int default_value = 0) const
+    int to_int(int default_value = 0) const { return to_i32(default_value); }
+    i32 to_i32(i32 default_value = 0) const { return to_number<i32>(default_value); }
+
+    unsigned to_uint(unsigned default_value = 0) const { return to_u32(default_value); }
+    u32 to_u32(u32 default_value = 0) const { return to_number<u32>(default_value); }
+
+    bool to_bool(bool default_value = false) const
     {
     {
-        if (!is_number())
+        if (!is_bool())
             return default_value;
             return default_value;
-#ifndef KERNEL
-        if (is_double())
-            return (int)as_double();
-#endif
-        if (is_uint())
-            return (int)as_uint();
-        return as_int();
+        return as_bool();
     }
     }
 
 
-    unsigned to_uint(unsigned default_value = 0) const
+    int as_i32() const
     {
     {
-        if (!is_number())
-            return default_value;
-#ifndef KERNEL
-        if (is_double())
-            return (unsigned)as_double();
-#endif
-        if (is_int())
-            return (unsigned)as_int();
-        return as_uint();
+        ASSERT(is_i32());
+        return m_value.as_i32;
     }
     }
 
 
-    bool to_bool(bool default_value = false) const
+    int as_u32() const
     {
     {
-        if (!is_bool())
-            return default_value;
-        return as_bool();
+        ASSERT(is_u32());
+        return m_value.as_u32;
     }
     }
 
 
-    int as_int() const
+    int as_i64() const
     {
     {
-        ASSERT(is_int());
-        return m_value.as_int;
+        ASSERT(is_i64());
+        return m_value.as_i64;
     }
     }
 
 
-    int as_uint() const
+    int as_u64() const
     {
     {
-        ASSERT(is_uint());
-        return m_value.as_uint;
+        ASSERT(is_u64());
+        return m_value.as_u64;
     }
     }
 
 
     int as_bool() const
     int as_bool() const
@@ -170,8 +166,10 @@ public:
     bool is_undefined() const { return m_type == Type::Undefined; }
     bool is_undefined() const { return m_type == Type::Undefined; }
     bool is_bool() const { return m_type == Type::Bool; }
     bool is_bool() const { return m_type == Type::Bool; }
     bool is_string() const { return m_type == Type::String; }
     bool is_string() const { return m_type == Type::String; }
-    bool is_int() const { return m_type == Type::Int; }
-    bool is_uint() const { return m_type == Type::UnsignedInt; }
+    bool is_i32() const { return m_type == Type::Int32; }
+    bool is_u32() const { return m_type == Type::UnsignedInt32; }
+    bool is_i64() const { return m_type == Type::Int64; }
+    bool is_u64() const { return m_type == Type::UnsignedInt64; }
 #ifndef KERNEL
 #ifndef KERNEL
     bool is_double() const
     bool is_double() const
     {
     {
@@ -185,28 +183,36 @@ public:
     bool is_object() const { return m_type == Type::Object; }
     bool is_object() const { return m_type == Type::Object; }
     bool is_number() const
     bool is_number() const
     {
     {
-        if (m_type == Type::Int || m_type == Type::UnsignedInt)
-            return true;
-#ifdef KERNEL
-        return false;
-#else
-        return m_type == Type::Double;
+        switch (m_type) {
+        case Type::Int32:
+        case Type::UnsignedInt32:
+        case Type::Int64:
+        case Type::UnsignedInt64:
+#ifndef KERNEL
+        case Type::Double:
 #endif
 #endif
+            return true;
+        default:
+            return false;
+        }
     }
     }
 
 
-    u32 to_u32(u32 default_value = 0) const
+    template<typename T>
+    T to_number(T default_value = 0) const
     {
     {
-        if (!is_number())
-            return default_value;
-#ifdef KERNEL
-        return (u32)m_value.as_int;
-#else
-        if (type() == Type::Int)
-            return (u32)m_value.as_int;
-        if (type() == Type::UnsignedInt)
-            return m_value.as_uint;
-        return (u32)m_value.as_double;
+#ifndef KERNEL
+        if (is_double())
+            return (T)as_double();
 #endif
 #endif
+        if (type() == Type::Int32)
+            return (T)as_i32();
+        if (type() == Type::UnsignedInt32)
+            return (T)as_u32();
+        if (type() == Type::Int64)
+            return (T)as_i64();
+        if (type() == Type::UnsignedInt64)
+            return (T)as_u64();
+        return default_value;
     }
     }
 
 
 private:
 private:
@@ -222,8 +228,10 @@ private:
 #ifndef KERNEL
 #ifndef KERNEL
         double as_double;
         double as_double;
 #endif
 #endif
-        int as_int;
-        unsigned int as_uint;
+        i32 as_i32;
+        u32 as_u32;
+        i64 as_i64;
+        u64 as_u64;
         bool as_bool;
         bool as_bool;
     } m_value;
     } m_value;
 };
 };

+ 10 - 10
Kernel/FileSystem/ProcFS.cpp

@@ -257,8 +257,8 @@ Optional<KBuffer> procfs$pid_vm(InodeIdentifier identifier)
         region_object.add("readable", region.is_readable());
         region_object.add("readable", region.is_readable());
         region_object.add("writable", region.is_writable());
         region_object.add("writable", region.is_writable());
         region_object.add("address", region.vaddr().get());
         region_object.add("address", region.vaddr().get());
-        region_object.add("size", region.size());
-        region_object.add("amount_resident", region.amount_resident());
+        region_object.add("size", (u32)region.size());
+        region_object.add("amount_resident", (u32)region.amount_resident());
         region_object.add("name", region.name());
         region_object.add("name", region.name());
     }
     }
     array.finish();
     array.finish();
@@ -644,9 +644,9 @@ Optional<KBuffer> procfs$memstat(InodeIdentifier)
     InterruptDisabler disabler;
     InterruptDisabler disabler;
     KBufferBuilder builder;
     KBufferBuilder builder;
     JsonObjectSerializer json { builder };
     JsonObjectSerializer json { builder };
-    json.add("kmalloc_allocated", sum_alloc);
-    json.add("kmalloc_available", sum_free);
-    json.add("kmalloc_eternal_allocated", kmalloc_sum_eternal);
+    json.add("kmalloc_allocated", (u32)sum_alloc);
+    json.add("kmalloc_available", (u32)sum_free);
+    json.add("kmalloc_eternal_allocated", (u32)kmalloc_sum_eternal);
     json.add("user_physical_allocated", MM.user_physical_pages_used());
     json.add("user_physical_allocated", MM.user_physical_pages_used());
     json.add("user_physical_available", MM.user_physical_pages());
     json.add("user_physical_available", MM.user_physical_pages());
     json.add("super_physical_allocated", MM.super_physical_pages_used());
     json.add("super_physical_allocated", MM.super_physical_pages_used());
@@ -655,8 +655,8 @@ Optional<KBuffer> procfs$memstat(InodeIdentifier)
     json.add("kfree_call_count", g_kfree_call_count);
     json.add("kfree_call_count", g_kfree_call_count);
     slab_alloc_stats([&json](size_t slab_size, size_t num_allocated, size_t num_free) {
     slab_alloc_stats([&json](size_t slab_size, size_t num_allocated, size_t num_free) {
         auto prefix = String::format("slab_%zu", slab_size);
         auto prefix = String::format("slab_%zu", slab_size);
-        json.add(String::format("%s_num_allocated", prefix.characters()), num_allocated);
-        json.add(String::format("%s_num_free", prefix.characters()), num_free);
+        json.add(String::format("%s_num_allocated", prefix.characters()), (u32)num_allocated);
+        json.add(String::format("%s_num_free", prefix.characters()), (u32)num_free);
     });
     });
     json.finish();
     json.finish();
     return builder.build();
     return builder.build();
@@ -684,9 +684,9 @@ Optional<KBuffer> procfs$all(InodeIdentifier)
         process_object.add("nfds", process.number_of_open_file_descriptors());
         process_object.add("nfds", process.number_of_open_file_descriptors());
         process_object.add("name", process.name());
         process_object.add("name", process.name());
         process_object.add("tty", process.tty() ? process.tty()->tty_name() : "notty");
         process_object.add("tty", process.tty() ? process.tty()->tty_name() : "notty");
-        process_object.add("amount_virtual", process.amount_virtual());
-        process_object.add("amount_resident", process.amount_resident());
-        process_object.add("amount_shared", process.amount_shared());
+        process_object.add("amount_virtual", (u32)process.amount_virtual());
+        process_object.add("amount_resident", (u32)process.amount_resident());
+        process_object.add("amount_shared", (u32)process.amount_shared());
         process_object.add("ticks", process.main_thread().ticks());
         process_object.add("ticks", process.main_thread().ticks());
         process_object.add("priority", to_string(process.priority()));
         process_object.add("priority", to_string(process.priority()));
         process_object.add("syscall_count", process.syscall_count());
         process_object.add("syscall_count", process.syscall_count());

+ 2 - 4
Libraries/LibGUI/GJsonArrayModel.cpp

@@ -34,10 +34,8 @@ GVariant GJsonArrayModel::data(const GModelIndex& index, Role role) const
         auto data = object.get(json_field_name);
         auto data = object.get(json_field_name);
         if (field_spec.massage_for_display)
         if (field_spec.massage_for_display)
             return field_spec.massage_for_display(object);
             return field_spec.massage_for_display(object);
-        if (data.is_int())
-            return data.as_int();
-        if (data.is_uint())
-            return data.as_uint();
+        if (data.is_number())
+            return data.to_i32();
         return object.get(json_field_name).to_string();
         return object.get(json_field_name).to_string();
     }
     }
 
 

+ 18 - 4
Libraries/LibGUI/GVariant.cpp

@@ -93,15 +93,29 @@ GVariant::GVariant(const JsonValue& value)
         return;
         return;
     }
     }
 
 
-    if (value.is_int()) {
+    if (value.is_i32()) {
         m_type = Type::Int;
         m_type = Type::Int;
-        m_value.as_int = value.as_int();
+        m_value.as_int = value.as_i32();
         return;
         return;
     }
     }
 
 
-    if (value.is_uint()) {
+    if (value.is_u32()) {
         m_type = Type::UnsignedInt;
         m_type = Type::UnsignedInt;
-        m_value.as_uint = value.as_uint();
+        m_value.as_uint = value.as_u32();
+        return;
+    }
+
+    if (value.is_i64()) {
+        // FIXME: GVariant should have a 64-bit internal type.
+        m_type = Type::Int;
+        m_value.as_int = value.to_i32();
+        return;
+    }
+
+    if (value.is_u64()) {
+        // FIXME: GVariant should have a 64-bit internal type.
+        m_type = Type::UnsignedInt;
+        m_value.as_uint = value.to_u32();
         return;
         return;
     }
     }