base::Value (de)serialization for some basic net types
Working on some HostCache::Entry replacement work, which requires going
to/from base::Value for these types. This essentially duplicates some of
the (de)serialization logic, which will hopefully eventually be deleted,
in host_cache.cc.
Change-Id: Ib28b4d4b5b1da29824f64fae3bc7d83f602269a3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3964882
Commit-Queue: Eric Orth <[email protected]>
Reviewed-by: Tsuyoshi Horo <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1062892}
diff --git a/net/base/ip_endpoint.cc b/net/base/ip_endpoint.cc
index 05466120..7947b58 100644
--- a/net/base/ip_endpoint.cc
+++ b/net/base/ip_endpoint.cc
@@ -8,15 +8,19 @@
#include <string.h>
#include <tuple>
+#include <utility>
#include "base/check.h"
#include "base/check_op.h"
#include "base/notreached.h"
+#include "base/numerics/safe_conversions.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_byteorder.h"
+#include "base/values.h"
#include "build/build_config.h"
#include "net/base/ip_address.h"
#include "net/base/sys_addrinfo.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#if BUILDFLAG(IS_WIN)
#include <winsock2.h>
@@ -27,6 +31,39 @@
namespace net {
+namespace {
+
+// Value dictionary keys
+constexpr base::StringPiece kValueAddressKey = "address";
+constexpr base::StringPiece kValuePortKey = "port";
+
+} // namespace
+
+// static
+absl::optional<IPEndPoint> IPEndPoint::FromValue(const base::Value& value) {
+ const base::Value::Dict* dict = value.GetIfDict();
+ if (!dict)
+ return absl::nullopt;
+
+ const base::Value* address_value = dict->Find(kValueAddressKey);
+ if (!address_value)
+ return absl::nullopt;
+ absl::optional<IPAddress> address = IPAddress::FromValue(*address_value);
+ if (!address.has_value())
+ return absl::nullopt;
+ // Expect IPAddress to only allow deserializing valid addresses.
+ DCHECK(address.value().IsValid());
+
+ absl::optional<int> port = dict->FindInt(kValuePortKey);
+ if (!port.has_value() ||
+ !base::IsValueInRangeForNumericType<uint16_t>(port.value())) {
+ return absl::nullopt;
+ }
+
+ return IPEndPoint(address.value(),
+ base::checked_cast<uint16_t>(port.value()));
+}
+
IPEndPoint::IPEndPoint() = default;
IPEndPoint::~IPEndPoint() = default;
@@ -182,6 +219,16 @@
return !(*this == that);
}
+base::Value IPEndPoint::ToValue() const {
+ base::Value::Dict dict;
+
+ DCHECK(address_.IsValid());
+ dict.Set(kValueAddressKey, address_.ToValue());
+ dict.Set(kValuePortKey, port_);
+
+ return base::Value(std::move(dict));
+}
+
std::ostream& operator<<(std::ostream& os, const IPEndPoint& ip_endpoint) {
return os << ip_endpoint.ToString();
}