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