[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 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/value_conversions.h" |
| 6 | |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 7 | #include <stdint.h> |
| 8 | |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 9 | #include <algorithm> |
[email protected] | c014f2b3 | 2013-09-03 23:29:12 | [diff] [blame] | 10 | #include <string> |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 11 | #include <vector> |
[email protected] | c014f2b3 | 2013-09-03 23:29:12 | [diff] [blame] | 12 | |
[email protected] | 5799981 | 2013-02-24 05:40:52 | [diff] [blame] | 13 | #include "base/files/file_path.h" |
vabr | bce355c | 2017-03-23 18:52:43 | [diff] [blame] | 14 | #include "base/memory/ptr_util.h" |
[email protected] | dfa049e | 2013-02-07 02:57:22 | [diff] [blame] | 15 | #include "base/strings/string_number_conversions.h" |
[email protected] | 8f9a3a5 | 2013-06-28 15:14:18 | [diff] [blame] | 16 | #include "base/time/time.h" |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 17 | #include "base/unguessable_token.h" |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 18 | #include "base/values.h" |
| 19 | |
| 20 | namespace base { |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 21 | namespace { |
| 22 | // Helper for serialize/deserialize UnguessableToken. |
| 23 | union UnguessableTokenRepresentation { |
| 24 | struct Field { |
| 25 | uint64_t high; |
| 26 | uint64_t low; |
| 27 | } field; |
| 28 | |
| 29 | uint8_t buffer[sizeof(Field)]; |
| 30 | }; |
| 31 | } // namespace |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 32 | |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 33 | // |Value| internally stores strings in UTF-8, so we have to convert from the |
| 34 | // system native code to UTF-8 and back. |
Christian Dullweber | 1374008 | 2018-07-26 13:09:09 | [diff] [blame] | 35 | Value CreateFilePathValue(const FilePath& in_value) { |
| 36 | return Value(in_value.AsUTF8Unsafe()); |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | bool GetValueAsFilePath(const Value& value, FilePath* file_path) { |
| 40 | std::string str; |
| 41 | if (!value.GetAsString(&str)) |
| 42 | return false; |
| 43 | if (file_path) |
[email protected] | 4544051 | 2011-11-02 04:55:23 | [diff] [blame] | 44 | *file_path = FilePath::FromUTF8Unsafe(str); |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 45 | return true; |
| 46 | } |
| 47 | |
Xiaohan Wang | ec1c552a | 2019-02-07 18:29:08 | [diff] [blame] | 48 | // It is recommended in time.h to use ToDeltaSinceWindowsEpoch() and |
| 49 | // FromDeltaSinceWindowsEpoch() for opaque serialization and |
| 50 | // deserialization of time values. |
| 51 | Value CreateTimeValue(const Time& time) { |
| 52 | return CreateTimeDeltaValue(time.ToDeltaSinceWindowsEpoch()); |
| 53 | } |
| 54 | |
| 55 | bool GetValueAsTime(const Value& value, Time* time) { |
| 56 | TimeDelta time_delta; |
| 57 | if (!GetValueAsTimeDelta(value, &time_delta)) |
| 58 | return false; |
| 59 | |
| 60 | if (time) |
| 61 | *time = Time::FromDeltaSinceWindowsEpoch(time_delta); |
| 62 | return true; |
| 63 | } |
| 64 | |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 65 | // |Value| does not support 64-bit integers, and doubles do not have enough |
| 66 | // precision, so we store the 64-bit time value as a string instead. |
Xiaohan Wang | ec1c552a | 2019-02-07 18:29:08 | [diff] [blame] | 67 | Value CreateTimeDeltaValue(const TimeDelta& time_delta) { |
| 68 | std::string string_value = base::Int64ToString(time_delta.InMicroseconds()); |
Christian Dullweber | 1374008 | 2018-07-26 13:09:09 | [diff] [blame] | 69 | return Value(string_value); |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 70 | } |
| 71 | |
Xiaohan Wang | ec1c552a | 2019-02-07 18:29:08 | [diff] [blame] | 72 | bool GetValueAsTimeDelta(const Value& value, TimeDelta* time_delta) { |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 73 | std::string str; |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 74 | int64_t int_value; |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 75 | if (!value.GetAsString(&str) || !base::StringToInt64(str, &int_value)) |
| 76 | return false; |
Xiaohan Wang | ec1c552a | 2019-02-07 18:29:08 | [diff] [blame] | 77 | if (time_delta) |
| 78 | *time_delta = TimeDelta::FromMicroseconds(int_value); |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 79 | return true; |
| 80 | } |
| 81 | |
Christian Dullweber | 1374008 | 2018-07-26 13:09:09 | [diff] [blame] | 82 | Value CreateUnguessableTokenValue(const UnguessableToken& token) { |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 83 | UnguessableTokenRepresentation representation; |
| 84 | representation.field.high = token.GetHighForSerialization(); |
| 85 | representation.field.low = token.GetLowForSerialization(); |
| 86 | |
Christian Dullweber | 1374008 | 2018-07-26 13:09:09 | [diff] [blame] | 87 | return Value(HexEncode(representation.buffer, sizeof(representation.buffer))); |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 88 | } |
| 89 | |
| 90 | bool GetValueAsUnguessableToken(const Value& value, UnguessableToken* token) { |
| 91 | if (!value.is_string()) { |
| 92 | return false; |
| 93 | } |
| 94 | |
| 95 | // TODO(dcheng|yucliu): Make a function that accepts non vector variant and |
| 96 | // reads a fixed number of bytes. |
| 97 | std::vector<uint8_t> high_low_bytes; |
| 98 | if (!HexStringToBytes(value.GetString(), &high_low_bytes)) { |
| 99 | return false; |
| 100 | } |
| 101 | |
| 102 | UnguessableTokenRepresentation representation; |
| 103 | if (high_low_bytes.size() != sizeof(representation.buffer)) { |
| 104 | return false; |
| 105 | } |
| 106 | |
| 107 | std::copy(high_low_bytes.begin(), high_low_bytes.end(), |
| 108 | std::begin(representation.buffer)); |
| 109 | *token = UnguessableToken::Deserialize(representation.field.high, |
| 110 | representation.field.low); |
| 111 | return true; |
| 112 | } |
| 113 | |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 114 | } // namespace base |