xref: /aosp_15_r20/external/libchrome/base/value_conversions.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/value_conversions.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include <algorithm>
10*635a8641SAndroid Build Coastguard Worker #include <string>
11*635a8641SAndroid Build Coastguard Worker #include <vector>
12*635a8641SAndroid Build Coastguard Worker 
13*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/unguessable_token.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/values.h"
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker namespace base {
21*635a8641SAndroid Build Coastguard Worker namespace {
22*635a8641SAndroid Build Coastguard Worker // Helper for serialize/deserialize UnguessableToken.
23*635a8641SAndroid Build Coastguard Worker union UnguessableTokenRepresentation {
24*635a8641SAndroid Build Coastguard Worker   struct Field {
25*635a8641SAndroid Build Coastguard Worker     uint64_t high;
26*635a8641SAndroid Build Coastguard Worker     uint64_t low;
27*635a8641SAndroid Build Coastguard Worker   } field;
28*635a8641SAndroid Build Coastguard Worker 
29*635a8641SAndroid Build Coastguard Worker   uint8_t buffer[sizeof(Field)];
30*635a8641SAndroid Build Coastguard Worker };
31*635a8641SAndroid Build Coastguard Worker }  // namespace
32*635a8641SAndroid Build Coastguard Worker 
33*635a8641SAndroid Build Coastguard Worker // |Value| internally stores strings in UTF-8, so we have to convert from the
34*635a8641SAndroid Build Coastguard Worker // system native code to UTF-8 and back.
CreateFilePathValue(const FilePath & in_value)35*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> CreateFilePathValue(const FilePath& in_value) {
36*635a8641SAndroid Build Coastguard Worker   return std::make_unique<Value>(in_value.AsUTF8Unsafe());
37*635a8641SAndroid Build Coastguard Worker }
38*635a8641SAndroid Build Coastguard Worker 
GetValueAsFilePath(const Value & value,FilePath * file_path)39*635a8641SAndroid Build Coastguard Worker bool GetValueAsFilePath(const Value& value, FilePath* file_path) {
40*635a8641SAndroid Build Coastguard Worker   std::string str;
41*635a8641SAndroid Build Coastguard Worker   if (!value.GetAsString(&str))
42*635a8641SAndroid Build Coastguard Worker     return false;
43*635a8641SAndroid Build Coastguard Worker   if (file_path)
44*635a8641SAndroid Build Coastguard Worker     *file_path = FilePath::FromUTF8Unsafe(str);
45*635a8641SAndroid Build Coastguard Worker   return true;
46*635a8641SAndroid Build Coastguard Worker }
47*635a8641SAndroid Build Coastguard Worker 
48*635a8641SAndroid Build Coastguard Worker // |Value| does not support 64-bit integers, and doubles do not have enough
49*635a8641SAndroid Build Coastguard Worker // precision, so we store the 64-bit time value as a string instead.
CreateTimeDeltaValue(const TimeDelta & time)50*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> CreateTimeDeltaValue(const TimeDelta& time) {
51*635a8641SAndroid Build Coastguard Worker   std::string string_value = base::Int64ToString(time.ToInternalValue());
52*635a8641SAndroid Build Coastguard Worker   return std::make_unique<Value>(string_value);
53*635a8641SAndroid Build Coastguard Worker }
54*635a8641SAndroid Build Coastguard Worker 
GetValueAsTimeDelta(const Value & value,TimeDelta * time)55*635a8641SAndroid Build Coastguard Worker bool GetValueAsTimeDelta(const Value& value, TimeDelta* time) {
56*635a8641SAndroid Build Coastguard Worker   std::string str;
57*635a8641SAndroid Build Coastguard Worker   int64_t int_value;
58*635a8641SAndroid Build Coastguard Worker   if (!value.GetAsString(&str) || !base::StringToInt64(str, &int_value))
59*635a8641SAndroid Build Coastguard Worker     return false;
60*635a8641SAndroid Build Coastguard Worker   if (time)
61*635a8641SAndroid Build Coastguard Worker     *time = TimeDelta::FromInternalValue(int_value);
62*635a8641SAndroid Build Coastguard Worker   return true;
63*635a8641SAndroid Build Coastguard Worker }
64*635a8641SAndroid Build Coastguard Worker 
CreateUnguessableTokenValue(const UnguessableToken & token)65*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Value> CreateUnguessableTokenValue(
66*635a8641SAndroid Build Coastguard Worker     const UnguessableToken& token) {
67*635a8641SAndroid Build Coastguard Worker   UnguessableTokenRepresentation representation;
68*635a8641SAndroid Build Coastguard Worker   representation.field.high = token.GetHighForSerialization();
69*635a8641SAndroid Build Coastguard Worker   representation.field.low = token.GetLowForSerialization();
70*635a8641SAndroid Build Coastguard Worker 
71*635a8641SAndroid Build Coastguard Worker   return std::make_unique<Value>(
72*635a8641SAndroid Build Coastguard Worker       HexEncode(representation.buffer, sizeof(representation.buffer)));
73*635a8641SAndroid Build Coastguard Worker }
74*635a8641SAndroid Build Coastguard Worker 
GetValueAsUnguessableToken(const Value & value,UnguessableToken * token)75*635a8641SAndroid Build Coastguard Worker bool GetValueAsUnguessableToken(const Value& value, UnguessableToken* token) {
76*635a8641SAndroid Build Coastguard Worker   if (!value.is_string()) {
77*635a8641SAndroid Build Coastguard Worker     return false;
78*635a8641SAndroid Build Coastguard Worker   }
79*635a8641SAndroid Build Coastguard Worker 
80*635a8641SAndroid Build Coastguard Worker   // TODO(dcheng|yucliu): Make a function that accepts non vector variant and
81*635a8641SAndroid Build Coastguard Worker   // reads a fixed number of bytes.
82*635a8641SAndroid Build Coastguard Worker   std::vector<uint8_t> high_low_bytes;
83*635a8641SAndroid Build Coastguard Worker   if (!HexStringToBytes(value.GetString(), &high_low_bytes)) {
84*635a8641SAndroid Build Coastguard Worker     return false;
85*635a8641SAndroid Build Coastguard Worker   }
86*635a8641SAndroid Build Coastguard Worker 
87*635a8641SAndroid Build Coastguard Worker   UnguessableTokenRepresentation representation;
88*635a8641SAndroid Build Coastguard Worker   if (high_low_bytes.size() != sizeof(representation.buffer)) {
89*635a8641SAndroid Build Coastguard Worker     return false;
90*635a8641SAndroid Build Coastguard Worker   }
91*635a8641SAndroid Build Coastguard Worker 
92*635a8641SAndroid Build Coastguard Worker   std::copy(high_low_bytes.begin(), high_low_bytes.end(),
93*635a8641SAndroid Build Coastguard Worker             std::begin(representation.buffer));
94*635a8641SAndroid Build Coastguard Worker   *token = UnguessableToken::Deserialize(representation.field.high,
95*635a8641SAndroid Build Coastguard Worker                                          representation.field.low);
96*635a8641SAndroid Build Coastguard Worker   return true;
97*635a8641SAndroid Build Coastguard Worker }
98*635a8641SAndroid Build Coastguard Worker 
99*635a8641SAndroid Build Coastguard Worker }  // namespace base
100