// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/value_conversions.h" #include #include #include #include #include "base/files/file_path.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/time/time.h" #include "base/unguessable_token.h" #include "base/values.h" namespace base { namespace { // Helper for serialize/deserialize UnguessableToken. union UnguessableTokenRepresentation { struct Field { uint64_t high; uint64_t low; } field; uint8_t buffer[sizeof(Field)]; }; } // namespace // |Value| internally stores strings in UTF-8, so we have to convert from the // system native code to UTF-8 and back. std::unique_ptr CreateFilePathValue(const FilePath& in_value) { return std::make_unique(in_value.AsUTF8Unsafe()); } bool GetValueAsFilePath(const Value& value, FilePath* file_path) { std::string str; if (!value.GetAsString(&str)) return false; if (file_path) *file_path = FilePath::FromUTF8Unsafe(str); return true; } // |Value| does not support 64-bit integers, and doubles do not have enough // precision, so we store the 64-bit time value as a string instead. std::unique_ptr CreateTimeDeltaValue(const TimeDelta& time) { std::string string_value = base::Int64ToString(time.ToInternalValue()); return std::make_unique(string_value); } bool GetValueAsTimeDelta(const Value& value, TimeDelta* time) { std::string str; int64_t int_value; if (!value.GetAsString(&str) || !base::StringToInt64(str, &int_value)) return false; if (time) *time = TimeDelta::FromInternalValue(int_value); return true; } std::unique_ptr CreateUnguessableTokenValue( const UnguessableToken& token) { UnguessableTokenRepresentation representation; representation.field.high = token.GetHighForSerialization(); representation.field.low = token.GetLowForSerialization(); return std::make_unique( HexEncode(representation.buffer, sizeof(representation.buffer))); } bool GetValueAsUnguessableToken(const Value& value, UnguessableToken* token) { if (!value.is_string()) { return false; } // TODO(dcheng|yucliu): Make a function that accepts non vector variant and // reads a fixed number of bytes. std::vector high_low_bytes; if (!HexStringToBytes(value.GetString(), &high_low_bytes)) { return false; } UnguessableTokenRepresentation representation; if (high_low_bytes.size() != sizeof(representation.buffer)) { return false; } std::copy(high_low_bytes.begin(), high_low_bytes.end(), std::begin(representation.buffer)); *token = UnguessableToken::Deserialize(representation.field.high, representation.field.low); return true; } } // namespace base