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