values_util.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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. #include "base/json/values_util.h"
  5. #include "base/files/file_path.h"
  6. #include "base/strings/string_number_conversions.h"
  7. #include "base/time/time.h"
  8. #include "base/unguessable_token.h"
  9. #include "third_party/abseil-cpp/absl/types/optional.h"
  10. // Warning: The Values involved could be stored on persistent storage like files
  11. // on disks. Therefore, changes in implementation could lead to data corruption
  12. // and must be done with caution.
  13. namespace base {
  14. namespace {
  15. // Helper to serialize/deserialize an UnguessableToken.
  16. //
  17. // It assumes a little-endian CPU, which is arguably a bug.
  18. union UnguessableTokenRepresentation {
  19. struct Field {
  20. uint64_t high;
  21. uint64_t low;
  22. } field;
  23. uint8_t buffer[sizeof(Field)];
  24. };
  25. } // namespace
  26. Value Int64ToValue(int64_t integer) {
  27. return Value(NumberToString(integer));
  28. }
  29. absl::optional<int64_t> ValueToInt64(const Value* value) {
  30. return value ? ValueToInt64(*value) : absl::nullopt;
  31. }
  32. absl::optional<int64_t> ValueToInt64(const Value& value) {
  33. if (!value.is_string())
  34. return absl::nullopt;
  35. int64_t integer;
  36. if (!StringToInt64(value.GetString(), &integer))
  37. return absl::nullopt;
  38. return integer;
  39. }
  40. Value TimeDeltaToValue(TimeDelta time_delta) {
  41. return Int64ToValue(time_delta.InMicroseconds());
  42. }
  43. absl::optional<TimeDelta> ValueToTimeDelta(const Value* value) {
  44. return value ? ValueToTimeDelta(*value) : absl::nullopt;
  45. }
  46. absl::optional<TimeDelta> ValueToTimeDelta(const Value& value) {
  47. absl::optional<int64_t> integer = ValueToInt64(value);
  48. if (!integer)
  49. return absl::nullopt;
  50. return Microseconds(*integer);
  51. }
  52. Value TimeToValue(Time time) {
  53. return TimeDeltaToValue(time.ToDeltaSinceWindowsEpoch());
  54. }
  55. absl::optional<Time> ValueToTime(const Value* value) {
  56. return value ? ValueToTime(*value) : absl::nullopt;
  57. }
  58. absl::optional<Time> ValueToTime(const Value& value) {
  59. absl::optional<TimeDelta> time_delta = ValueToTimeDelta(value);
  60. if (!time_delta)
  61. return absl::nullopt;
  62. return Time::FromDeltaSinceWindowsEpoch(*time_delta);
  63. }
  64. Value FilePathToValue(FilePath file_path) {
  65. return Value(file_path.AsUTF8Unsafe());
  66. }
  67. absl::optional<FilePath> ValueToFilePath(const Value* value) {
  68. return value ? ValueToFilePath(*value) : absl::nullopt;
  69. }
  70. absl::optional<FilePath> ValueToFilePath(const Value& value) {
  71. if (!value.is_string())
  72. return absl::nullopt;
  73. return FilePath::FromUTF8Unsafe(value.GetString());
  74. }
  75. Value UnguessableTokenToValue(UnguessableToken token) {
  76. UnguessableTokenRepresentation repr;
  77. repr.field.high = token.GetHighForSerialization();
  78. repr.field.low = token.GetLowForSerialization();
  79. return Value(HexEncode(repr.buffer, sizeof(repr.buffer)));
  80. }
  81. absl::optional<UnguessableToken> ValueToUnguessableToken(const Value* value) {
  82. return value ? ValueToUnguessableToken(*value) : absl::nullopt;
  83. }
  84. absl::optional<UnguessableToken> ValueToUnguessableToken(const Value& value) {
  85. if (!value.is_string())
  86. return absl::nullopt;
  87. UnguessableTokenRepresentation repr;
  88. if (!HexStringToSpan(value.GetString(), repr.buffer))
  89. return absl::nullopt;
  90. return UnguessableToken::Deserialize(repr.field.high, repr.field.low);
  91. }
  92. } // namespace base