xref: /aosp_15_r20/external/cronet/base/json/values_util.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2019 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/json/values_util.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <optional>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/unguessable_token.h"
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker // Warning: The Values involved could be stored on persistent storage like files
15*6777b538SAndroid Build Coastguard Worker // on disks. Therefore, changes in implementation could lead to data corruption
16*6777b538SAndroid Build Coastguard Worker // and must be done with caution.
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker namespace base {
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker namespace {
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker // Helper to serialize/deserialize an UnguessableToken.
23*6777b538SAndroid Build Coastguard Worker //
24*6777b538SAndroid Build Coastguard Worker // It assumes a little-endian CPU, which is arguably a bug.
25*6777b538SAndroid Build Coastguard Worker union UnguessableTokenRepresentation {
26*6777b538SAndroid Build Coastguard Worker   struct Field {
27*6777b538SAndroid Build Coastguard Worker     uint64_t high;
28*6777b538SAndroid Build Coastguard Worker     uint64_t low;
29*6777b538SAndroid Build Coastguard Worker   } field;
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker   uint8_t buffer[sizeof(Field)];
32*6777b538SAndroid Build Coastguard Worker };
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker }  // namespace
35*6777b538SAndroid Build Coastguard Worker 
Int64ToValue(int64_t integer)36*6777b538SAndroid Build Coastguard Worker Value Int64ToValue(int64_t integer) {
37*6777b538SAndroid Build Coastguard Worker   return Value(NumberToString(integer));
38*6777b538SAndroid Build Coastguard Worker }
39*6777b538SAndroid Build Coastguard Worker 
ValueToInt64(const Value * value)40*6777b538SAndroid Build Coastguard Worker std::optional<int64_t> ValueToInt64(const Value* value) {
41*6777b538SAndroid Build Coastguard Worker   return value ? ValueToInt64(*value) : std::nullopt;
42*6777b538SAndroid Build Coastguard Worker }
43*6777b538SAndroid Build Coastguard Worker 
ValueToInt64(const Value & value)44*6777b538SAndroid Build Coastguard Worker std::optional<int64_t> ValueToInt64(const Value& value) {
45*6777b538SAndroid Build Coastguard Worker   if (!value.is_string())
46*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
47*6777b538SAndroid Build Coastguard Worker 
48*6777b538SAndroid Build Coastguard Worker   int64_t integer;
49*6777b538SAndroid Build Coastguard Worker   if (!StringToInt64(value.GetString(), &integer))
50*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
51*6777b538SAndroid Build Coastguard Worker 
52*6777b538SAndroid Build Coastguard Worker   return integer;
53*6777b538SAndroid Build Coastguard Worker }
54*6777b538SAndroid Build Coastguard Worker 
TimeDeltaToValue(TimeDelta time_delta)55*6777b538SAndroid Build Coastguard Worker Value TimeDeltaToValue(TimeDelta time_delta) {
56*6777b538SAndroid Build Coastguard Worker   return Int64ToValue(time_delta.InMicroseconds());
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker 
ValueToTimeDelta(const Value * value)59*6777b538SAndroid Build Coastguard Worker std::optional<TimeDelta> ValueToTimeDelta(const Value* value) {
60*6777b538SAndroid Build Coastguard Worker   return value ? ValueToTimeDelta(*value) : std::nullopt;
61*6777b538SAndroid Build Coastguard Worker }
62*6777b538SAndroid Build Coastguard Worker 
ValueToTimeDelta(const Value & value)63*6777b538SAndroid Build Coastguard Worker std::optional<TimeDelta> ValueToTimeDelta(const Value& value) {
64*6777b538SAndroid Build Coastguard Worker   std::optional<int64_t> integer = ValueToInt64(value);
65*6777b538SAndroid Build Coastguard Worker   if (!integer)
66*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
67*6777b538SAndroid Build Coastguard Worker   return Microseconds(*integer);
68*6777b538SAndroid Build Coastguard Worker }
69*6777b538SAndroid Build Coastguard Worker 
TimeToValue(Time time)70*6777b538SAndroid Build Coastguard Worker Value TimeToValue(Time time) {
71*6777b538SAndroid Build Coastguard Worker   return TimeDeltaToValue(time.ToDeltaSinceWindowsEpoch());
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker 
ValueToTime(const Value * value)74*6777b538SAndroid Build Coastguard Worker std::optional<Time> ValueToTime(const Value* value) {
75*6777b538SAndroid Build Coastguard Worker   return value ? ValueToTime(*value) : std::nullopt;
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker 
ValueToTime(const Value & value)78*6777b538SAndroid Build Coastguard Worker std::optional<Time> ValueToTime(const Value& value) {
79*6777b538SAndroid Build Coastguard Worker   std::optional<TimeDelta> time_delta = ValueToTimeDelta(value);
80*6777b538SAndroid Build Coastguard Worker   if (!time_delta)
81*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
82*6777b538SAndroid Build Coastguard Worker   return Time::FromDeltaSinceWindowsEpoch(*time_delta);
83*6777b538SAndroid Build Coastguard Worker }
84*6777b538SAndroid Build Coastguard Worker 
FilePathToValue(FilePath file_path)85*6777b538SAndroid Build Coastguard Worker Value FilePathToValue(FilePath file_path) {
86*6777b538SAndroid Build Coastguard Worker   return Value(file_path.AsUTF8Unsafe());
87*6777b538SAndroid Build Coastguard Worker }
88*6777b538SAndroid Build Coastguard Worker 
ValueToFilePath(const Value * value)89*6777b538SAndroid Build Coastguard Worker std::optional<FilePath> ValueToFilePath(const Value* value) {
90*6777b538SAndroid Build Coastguard Worker   return value ? ValueToFilePath(*value) : std::nullopt;
91*6777b538SAndroid Build Coastguard Worker }
92*6777b538SAndroid Build Coastguard Worker 
ValueToFilePath(const Value & value)93*6777b538SAndroid Build Coastguard Worker std::optional<FilePath> ValueToFilePath(const Value& value) {
94*6777b538SAndroid Build Coastguard Worker   if (!value.is_string())
95*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
96*6777b538SAndroid Build Coastguard Worker   return FilePath::FromUTF8Unsafe(value.GetString());
97*6777b538SAndroid Build Coastguard Worker }
98*6777b538SAndroid Build Coastguard Worker 
UnguessableTokenToValue(UnguessableToken token)99*6777b538SAndroid Build Coastguard Worker Value UnguessableTokenToValue(UnguessableToken token) {
100*6777b538SAndroid Build Coastguard Worker   UnguessableTokenRepresentation repr;
101*6777b538SAndroid Build Coastguard Worker   repr.field.high = token.GetHighForSerialization();
102*6777b538SAndroid Build Coastguard Worker   repr.field.low = token.GetLowForSerialization();
103*6777b538SAndroid Build Coastguard Worker   return Value(HexEncode(repr.buffer, sizeof(repr.buffer)));
104*6777b538SAndroid Build Coastguard Worker }
105*6777b538SAndroid Build Coastguard Worker 
ValueToUnguessableToken(const Value * value)106*6777b538SAndroid Build Coastguard Worker std::optional<UnguessableToken> ValueToUnguessableToken(const Value* value) {
107*6777b538SAndroid Build Coastguard Worker   return value ? ValueToUnguessableToken(*value) : std::nullopt;
108*6777b538SAndroid Build Coastguard Worker }
109*6777b538SAndroid Build Coastguard Worker 
ValueToUnguessableToken(const Value & value)110*6777b538SAndroid Build Coastguard Worker std::optional<UnguessableToken> ValueToUnguessableToken(const Value& value) {
111*6777b538SAndroid Build Coastguard Worker   if (!value.is_string())
112*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
113*6777b538SAndroid Build Coastguard Worker   UnguessableTokenRepresentation repr;
114*6777b538SAndroid Build Coastguard Worker   if (!HexStringToSpan(value.GetString(), repr.buffer))
115*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
116*6777b538SAndroid Build Coastguard Worker   std::optional<base::UnguessableToken> token =
117*6777b538SAndroid Build Coastguard Worker       UnguessableToken::Deserialize(repr.field.high, repr.field.low);
118*6777b538SAndroid Build Coastguard Worker   if (!token.has_value()) {
119*6777b538SAndroid Build Coastguard Worker     return std::nullopt;
120*6777b538SAndroid Build Coastguard Worker   }
121*6777b538SAndroid Build Coastguard Worker   return token;
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker 
124*6777b538SAndroid Build Coastguard Worker }  // namespace base
125