diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-05-17 17:24:03 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-06-22 07:51:41 +0000 |
commit | 774f54339e5db91f785733232d3950366db65d07 (patch) | |
tree | 068e1b47bd1af94d77094ed12b604a6b83d9c22a /chromium/components/sync | |
parent | f7eaed5286974984ba5f9e3189d8f49d03e99f81 (diff) | |
download | qtwebengine-chromium-774f54339e5db91f785733232d3950366db65d07.tar.gz |
BASELINE: Update Chromium to 102.0.5005.57
Change-Id: I885f714bb40ee724c28f94ca6bd8dbdb39915158
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/components/sync')
-rw-r--r-- | chromium/components/sync/BUILD.gn | 9 | ||||
-rw-r--r-- | chromium/components/sync/android/BUILD.gn | 1 | ||||
-rw-r--r-- | chromium/components/sync/base/BUILD.gn | 3 | ||||
-rw-r--r-- | chromium/components/sync/base/ordinal.h | 512 | ||||
-rw-r--r-- | chromium/components/sync/chromeos/BUILD.gn | 12 | ||||
-rw-r--r-- | chromium/components/sync/model/BUILD.gn | 1 | ||||
-rw-r--r-- | chromium/components/sync/model/string_ordinal.h | 185 | ||||
-rw-r--r-- | chromium/components/sync/protocol/protocol_sources.gni | 147 |
8 files changed, 266 insertions, 604 deletions
diff --git a/chromium/components/sync/BUILD.gn b/chromium/components/sync/BUILD.gn index 2acdb0cc5fc..60cf1de55a6 100644 --- a/chromium/components/sync/BUILD.gn +++ b/chromium/components/sync/BUILD.gn @@ -16,6 +16,9 @@ group("sync") { if (!is_android) { public_deps += [ "//components/sync/trusted_vault" ] } + if (is_chromeos) { + public_deps += [ "//components/sync/chromeos" ] + } } group("test_support") { @@ -129,7 +132,6 @@ source_set("unit_tests") { sources = [ "base/client_tag_hash_unittest.cc", "base/model_type_unittest.cc", - "base/ordinal_unittest.cc", "base/protobuf_unittest.cc", "base/sync_prefs_unittest.cc", "base/sync_util_unittest.cc", @@ -190,6 +192,7 @@ source_set("unit_tests") { "model/mutable_data_batch_unittest.cc", "model/processor_entity_tracker_unittest.cc", "model/processor_entity_unittest.cc", + "model/string_ordinal_unittest.cc", "model/sync_change_unittest.cc", "model/sync_data_unittest.cc", "model/sync_error_unittest.cc", @@ -219,6 +222,10 @@ source_set("unit_tests") { ] } + if (is_chromeos) { + sources += [ "chromeos/explicit_passphrase_mojo_utils_unittest.cc" ] + } + configs += [ "//build/config:precompiled_headers" ] data = [ diff --git a/chromium/components/sync/android/BUILD.gn b/chromium/components/sync/android/BUILD.gn index 47e91cf8091..0c1a5d70e7e 100644 --- a/chromium/components/sync/android/BUILD.gn +++ b/chromium/components/sync/android/BUILD.gn @@ -24,5 +24,6 @@ java_cpp_enum("java_enums") { "//components/sync/base/model_type.h", "//components/sync/base/passphrase_enums.h", "//components/sync/driver/sync_service_utils.h", + "//components/sync/driver/sync_user_settings.h", ] } diff --git a/chromium/components/sync/base/BUILD.gn b/chromium/components/sync/base/BUILD.gn index f7539be4907..b97d4084ff7 100644 --- a/chromium/components/sync/base/BUILD.gn +++ b/chromium/components/sync/base/BUILD.gn @@ -31,11 +31,8 @@ static_library("base") { "invalidation_helper.h", "legacy_directory_deletion.cc", "legacy_directory_deletion.h", - "logging.cc", - "logging.h", "model_type.cc", "model_type.h", - "ordinal.h", "passphrase_enums.cc", "passphrase_enums.h", "pref_names.h", diff --git a/chromium/components/sync/base/ordinal.h b/chromium/components/sync/base/ordinal.h deleted file mode 100644 index 7314f1fee19..00000000000 --- a/chromium/components/sync/base/ordinal.h +++ /dev/null @@ -1,512 +0,0 @@ -// 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. - -#ifndef COMPONENTS_SYNC_BASE_ORDINAL_H_ -#define COMPONENTS_SYNC_BASE_ORDINAL_H_ - -#include <stdint.h> - -#include <algorithm> -#include <string> - -#include "base/check_op.h" -#include "base/json/string_escape.h" - -namespace mojo { -template <typename DataViewType, typename T> -struct StructTraits; -} - -namespace syncer { - -namespace mojom { -class StringOrdinalDataView; -} - -// An Ordinal<T> is an object that can be used for ordering. The -// Ordinal<T> class has an unbounded dense strict total order, which -// mean for any Ordinal<T>s a, b and c: -// -// - a < b and b < c implies a < c (transitivity); -// - exactly one of a < b, b < a and a = b holds (trichotomy); -// - if a < b, there is a Ordinal<T> x such that a < x < b (density); -// - there are Ordinals<T> x and y such that x < a < y (unboundedness). -// -// This means that when Ordinal<T> is used for sorting a list, if any -// item changes its position in the list, only its Ordinal<T> value -// has to change to represent the new order, and all the other values -// can stay the same. -// -// An Ordinal<T> is internally represented as an array of bytes, so it -// can be serialized to and deserialized from disk. -// -// The Traits class should look like the following: -// -// // Don't forget to #include <stdint.h> and <stddef.h>. -// struct MyOrdinalTraits { -// // There must be at least two distinct values greater than kZeroDigit -// // and less than kMaxDigit. -// static const uint8_t kZeroDigit = '0'; -// static const uint8_t kMaxDigit = '9'; -// // kMinLength must be positive. -// static const size_t kMinLength = 1; -// }; -// -// An Ordinal<T> is valid iff its corresponding string has at least -// kMinLength characters, does not contain any characters less than -// kZeroDigit or greater than kMaxDigit, is not all zero digits, and -// does not have any unnecessary trailing zero digits. -// -// Note that even if the native char type is signed, strings still -// compare as if their they are unsigned. (This is explicitly in -// C++11 but not in C++98, even though all implementations do so -// anyway in practice.) Thus, it is safe to use any byte range for -// Ordinal<T>s. -template <typename Traits> -class Ordinal { - public: - // Functors for use with STL algorithms and containers. - class LessThanFn { - public: - LessThanFn(); - - bool operator()(const Ordinal<Traits>& lhs, - const Ordinal<Traits>& rhs) const; - }; - - class EqualsFn { - public: - EqualsFn(); - - bool operator()(const Ordinal<Traits>& lhs, - const Ordinal<Traits>& rhs) const; - }; - - // Creates an Ordinal from the given string of bytes. The Ordinal - // may be valid or invalid. - explicit Ordinal(const std::string& bytes); - - // Creates an invalid Ordinal. - Ordinal(); - - // Creates a valid initial Ordinal. This is called to create the first - // element of Ordinal list (i.e. before we have any other values we can - // generate from). - static Ordinal CreateInitialOrdinal(); - - // Returns true iff this Ordinal is valid. This takes constant - // time. - bool IsValid() const; - - // Returns true iff |*this| == |other| or |*this| and |other| - // are both invalid. - bool EqualsOrBothInvalid(const Ordinal& other) const; - - // Returns a printable string representation of the Ordinal suitable - // for logging. - std::string ToDebugString() const; - - // All remaining functions can only be called if IsValid() holds. - // It is an error to call them if IsValid() is false. - - // Order-related functions. - - // Returns true iff |*this| < |other|. - bool LessThan(const Ordinal& other) const; - - // Returns true iff |*this| > |other|. - bool GreaterThan(const Ordinal& other) const; - - // Returns true iff |*this| == |other| (i.e. |*this| < |other| and - // |other| < |*this| are both false). - bool Equals(const Ordinal& other) const; - - // Given |*this| != |other|, returns a Ordinal x such that - // min(|*this|, |other|) < x < max(|*this|, |other|). It is an error - // to call this function when |*this| == |other|. - Ordinal CreateBetween(const Ordinal& other) const; - - // Returns a Ordinal |x| such that |x| < |*this|. - Ordinal CreateBefore() const; - - // Returns a Ordinal |x| such that |*this| < |x|. - Ordinal CreateAfter() const; - - // Returns the string of bytes representing the Ordinal. It is - // guaranteed that an Ordinal constructed from the returned string - // will be valid. - std::string ToInternalValue() const; - - // Use of copy constructor and default assignment for this class is allowed. - - // Constants for Ordinal digits. - static const uint8_t kZeroDigit = Traits::kZeroDigit; - static const uint8_t kMaxDigit = Traits::kMaxDigit; - static const size_t kMinLength = Traits::kMinLength; - static const uint8_t kOneDigit = kZeroDigit + 1; - static const uint8_t kMidDigit = kOneDigit + (kMaxDigit - kOneDigit) / 2; - static const unsigned int kMidDigitValue = kMidDigit - kZeroDigit; - static const unsigned int kMaxDigitValue = kMaxDigit - kZeroDigit; - static const unsigned int kRadix = kMaxDigitValue + 1; - - static_assert(kOneDigit > kZeroDigit, "incorrect ordinal one digit"); - static_assert(kMidDigit > kOneDigit, "incorrect ordinal mid digit"); - static_assert(kMaxDigit > kMidDigit, "incorrect ordinal max digit"); - static_assert(kMinLength > 0, "incorrect ordinal min length"); - static_assert(kMidDigitValue > 1, "incorrect ordinal mid digit"); - static_assert(kMaxDigitValue > kMidDigitValue, "incorrect ordinal max digit"); - static_assert(kRadix == kMaxDigitValue + 1, "incorrect ordinal radix"); - - private: - friend struct mojo::StructTraits<syncer::mojom::StringOrdinalDataView, - Ordinal<Traits>>; - - // Returns true iff the given byte string satisfies the criteria for - // a valid Ordinal. - static bool IsValidOrdinalBytes(const std::string& bytes); - - // Returns the length that bytes.substr(0, length) would be with - // trailing zero digits removed. - static size_t GetLengthWithoutTrailingZeroDigits(const std::string& bytes, - size_t length); - - // Returns the digit at position i, padding with zero digits if - // required. - static uint8_t GetDigit(const std::string& bytes, size_t i); - - // Returns the digit value at position i, padding with 0 if required. - static int GetDigitValue(const std::string& bytes, size_t i); - - // Adds the given value to |bytes| at position i, carrying when - // necessary. Returns the left-most carry. - static int AddDigitValue(std::string* bytes, size_t i, int digit_value); - - // Returns the proper length |bytes| should be resized to, i.e. the - // smallest length such that |bytes| is still greater than - // |lower_bound| and is still valid. |bytes| should be greater than - // |lower_bound|. - static size_t GetProperLength(const std::string& lower_bound, - const std::string& bytes); - - // Compute the midpoint ordinal byte string that is between |start| - // and |end|. - static std::string ComputeMidpoint(const std::string& start, - const std::string& end); - - // Create a Ordinal that is lexigraphically greater than |start| and - // lexigraphically less than |end|. The returned Ordinal will be roughly - // between |start| and |end|. - static Ordinal<Traits> CreateOrdinalBetween(const Ordinal<Traits>& start, - const Ordinal<Traits>& end); - - // The internal byte string representation of the Ordinal. Never - // changes after construction except for assignment. - std::string bytes_; - - // A cache of the result of IsValidOrdinalBytes(bytes_). - bool is_valid_; -}; - -template <typename Traits> -const uint8_t Ordinal<Traits>::kZeroDigit; -template <typename Traits> -const uint8_t Ordinal<Traits>::kMaxDigit; -template <typename Traits> -const size_t Ordinal<Traits>::kMinLength; -template <typename Traits> -const uint8_t Ordinal<Traits>::kOneDigit; -template <typename Traits> -const uint8_t Ordinal<Traits>::kMidDigit; -template <typename Traits> -const unsigned int Ordinal<Traits>::kMidDigitValue; -template <typename Traits> -const unsigned int Ordinal<Traits>::kMaxDigitValue; -template <typename Traits> -const unsigned int Ordinal<Traits>::kRadix; - -template <typename Traits> -Ordinal<Traits>::LessThanFn::LessThanFn() = default; - -template <typename Traits> -bool Ordinal<Traits>::LessThanFn::operator()(const Ordinal<Traits>& lhs, - const Ordinal<Traits>& rhs) const { - return lhs.LessThan(rhs); -} - -template <typename Traits> -Ordinal<Traits>::EqualsFn::EqualsFn() = default; - -template <typename Traits> -bool Ordinal<Traits>::EqualsFn::operator()(const Ordinal<Traits>& lhs, - const Ordinal<Traits>& rhs) const { - return lhs.Equals(rhs); -} - -template <typename Traits> -bool operator==(const Ordinal<Traits>& lhs, const Ordinal<Traits>& rhs) { - return lhs.EqualsOrBothInvalid(rhs); -} - -template <typename Traits> -bool operator!=(const Ordinal<Traits>& lhs, const Ordinal<Traits>& rhs) { - return !(lhs == rhs); -} - -template <typename Traits> -Ordinal<Traits>::Ordinal(const std::string& bytes) - : bytes_(bytes), is_valid_(IsValidOrdinalBytes(bytes_)) {} - -template <typename Traits> -Ordinal<Traits>::Ordinal() : is_valid_(false) {} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateInitialOrdinal() { - std::string bytes(Traits::kMinLength, kZeroDigit); - bytes[0] = kMidDigit; - return Ordinal(bytes); -} - -template <typename Traits> -bool Ordinal<Traits>::IsValid() const { - DCHECK_EQ(IsValidOrdinalBytes(bytes_), is_valid_); - return is_valid_; -} - -template <typename Traits> -bool Ordinal<Traits>::EqualsOrBothInvalid(const Ordinal& other) const { - if (!IsValid() && !other.IsValid()) - return true; - - if (!IsValid() || !other.IsValid()) - return false; - - return Equals(other); -} - -template <typename Traits> -std::string Ordinal<Traits>::ToDebugString() const { - std::string debug_string = - base::EscapeBytesAsInvalidJSONString(bytes_, false /* put_in_quotes */); - if (!is_valid_) { - debug_string = "INVALID[" + debug_string + "]"; - } - return debug_string; -} - -template <typename Traits> -bool Ordinal<Traits>::LessThan(const Ordinal& other) const { - CHECK(IsValid()); - CHECK(other.IsValid()); - return bytes_ < other.bytes_; -} - -template <typename Traits> -bool Ordinal<Traits>::GreaterThan(const Ordinal& other) const { - CHECK(IsValid()); - CHECK(other.IsValid()); - return bytes_ > other.bytes_; -} - -template <typename Traits> -bool Ordinal<Traits>::Equals(const Ordinal& other) const { - CHECK(IsValid()); - CHECK(other.IsValid()); - return bytes_ == other.bytes_; -} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateBetween(const Ordinal& other) const { - CHECK(IsValid()); - CHECK(other.IsValid()); - CHECK(!Equals(other)); - - if (LessThan(other)) { - return CreateOrdinalBetween(*this, other); - } else { - return CreateOrdinalBetween(other, *this); - } -} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateBefore() const { - CHECK(IsValid()); - // Create the smallest valid Ordinal of the appropriate length - // to be the minimum boundary. - const size_t length = bytes_.length(); - std::string start(length, kZeroDigit); - start[length - 1] = kOneDigit; - if (start == bytes_) { - start[length - 1] = kZeroDigit; - start += kOneDigit; - } - - // Even though |start| is already a valid Ordinal that is less - // than |*this|, we don't return it because we wouldn't have much space in - // front of it to insert potential future values. - return CreateBetween(Ordinal(start)); -} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateAfter() const { - CHECK(IsValid()); - // Create the largest valid Ordinal of the appropriate length to be - // the maximum boundary. - std::string end(bytes_.length(), kMaxDigit); - if (end == bytes_) - end += kMaxDigit; - - // Even though |end| is already a valid Ordinal that is greater than - // |*this|, we don't return it because we wouldn't have much space after - // it to insert potential future values. - return CreateBetween(Ordinal(end)); -} - -template <typename Traits> -std::string Ordinal<Traits>::ToInternalValue() const { - CHECK(IsValid()); - return bytes_; -} - -template <typename Traits> -bool Ordinal<Traits>::IsValidOrdinalBytes(const std::string& bytes) { - const size_t length = bytes.length(); - if (length < kMinLength) - return false; - - bool found_non_zero = false; - for (size_t i = 0; i < length; ++i) { - const uint8_t byte = bytes[i]; - if (byte < kZeroDigit || byte > kMaxDigit) - return false; - if (byte > kZeroDigit) - found_non_zero = true; - } - if (!found_non_zero) - return false; - - if (length > kMinLength) { - const uint8_t last_byte = bytes[length - 1]; - if (last_byte == kZeroDigit) - return false; - } - - return true; -} - -template <typename Traits> -size_t Ordinal<Traits>::GetLengthWithoutTrailingZeroDigits( - const std::string& bytes, - size_t length) { - DCHECK(!bytes.empty()); - DCHECK_GT(length, 0U); - - size_t end_position = - bytes.find_last_not_of(static_cast<char>(kZeroDigit), length - 1); - - // If no non kZeroDigit is found then the string is a string of all zeros - // digits so we return 0 as the correct length. - if (end_position == std::string::npos) - return 0; - - return end_position + 1; -} - -template <typename Traits> -uint8_t Ordinal<Traits>::GetDigit(const std::string& bytes, size_t i) { - return (i < bytes.length()) ? bytes[i] : kZeroDigit; -} - -template <typename Traits> -int Ordinal<Traits>::GetDigitValue(const std::string& bytes, size_t i) { - return GetDigit(bytes, i) - kZeroDigit; -} - -template <typename Traits> -int Ordinal<Traits>::AddDigitValue(std::string* bytes, - size_t i, - int digit_value) { - DCHECK_LT(i, bytes->length()); - - for (int j = static_cast<int>(i); j >= 0 && digit_value > 0; --j) { - int byte_j_value = GetDigitValue(*bytes, j) + digit_value; - digit_value = byte_j_value / kRadix; - DCHECK_LE(digit_value, 1); - byte_j_value %= kRadix; - (*bytes)[j] = static_cast<char>(kZeroDigit + byte_j_value); - } - return digit_value; -} - -template <typename Traits> -size_t Ordinal<Traits>::GetProperLength(const std::string& lower_bound, - const std::string& bytes) { - CHECK_GT(bytes, lower_bound); - - size_t drop_length = - GetLengthWithoutTrailingZeroDigits(bytes, bytes.length()); - // See if the |ordinal| can be truncated after its last non-zero - // digit without affecting the ordering. - if (drop_length > kMinLength) { - size_t truncated_length = - GetLengthWithoutTrailingZeroDigits(bytes, drop_length - 1); - - if (truncated_length > 0 && - bytes.compare(0, truncated_length, lower_bound) > 0) - drop_length = truncated_length; - } - return std::max(drop_length, kMinLength); -} - -template <typename Traits> -std::string Ordinal<Traits>::ComputeMidpoint(const std::string& start, - const std::string& end) { - size_t max_size = std::max(start.length(), end.length()) + 1; - std::string midpoint(max_size, kZeroDigit); - - // Perform the operation (start + end) / 2 left-to-right by - // maintaining a "forward carry" which is either 0 or - // kMidDigitValue. AddDigitValue() is in general O(n), but this - // operation is still O(n) despite that; calls to AddDigitValue() - // will overflow at most to the last position where AddDigitValue() - // last overflowed. - int forward_carry = 0; - for (size_t i = 0; i < max_size; ++i) { - const int sum_value = GetDigitValue(start, i) + GetDigitValue(end, i); - const int digit_value = sum_value / 2 + forward_carry; - // AddDigitValue returning a non-zero carry would imply that - // midpoint[0] >= kMaxDigit, which one can show is impossible. - CHECK_EQ(AddDigitValue(&midpoint, i, digit_value), 0); - forward_carry = (sum_value % 2 == 1) ? kMidDigitValue : 0; - } - DCHECK_EQ(forward_carry, 0); - - return midpoint; -} - -template <typename Traits> -Ordinal<Traits> Ordinal<Traits>::CreateOrdinalBetween( - const Ordinal<Traits>& start, - const Ordinal<Traits>& end) { - CHECK(start.IsValid()); - CHECK(end.IsValid()); - CHECK(start.LessThan(end)); - const std::string& start_bytes = start.ToInternalValue(); - const std::string& end_bytes = end.ToInternalValue(); - DCHECK_LT(start_bytes, end_bytes); - - std::string midpoint = ComputeMidpoint(start_bytes, end_bytes); - const size_t proper_length = GetProperLength(start_bytes, midpoint); - midpoint.resize(proper_length, kZeroDigit); - - DCHECK_GT(midpoint, start_bytes); - DCHECK_LT(midpoint, end_bytes); - - Ordinal<Traits> midpoint_ordinal(midpoint); - DCHECK(midpoint_ordinal.IsValid()); - return midpoint_ordinal; -} - -} // namespace syncer - -#endif // COMPONENTS_SYNC_BASE_ORDINAL_H_ diff --git a/chromium/components/sync/chromeos/BUILD.gn b/chromium/components/sync/chromeos/BUILD.gn new file mode 100644 index 00000000000..57863b50ca1 --- /dev/null +++ b/chromium/components/sync/chromeos/BUILD.gn @@ -0,0 +1,12 @@ +# Copyright 2022 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. + +static_library("chromeos") { + sources = [ + "explicit_passphrase_mojo_utils.cc", + "explicit_passphrase_mojo_utils.h", + ] + public_deps = [ "//chromeos/crosapi/mojom" ] + deps = [ "//components/sync/engine" ] +} diff --git a/chromium/components/sync/model/BUILD.gn b/chromium/components/sync/model/BUILD.gn index 7f0d2fb23c4..64134bce07e 100644 --- a/chromium/components/sync/model/BUILD.gn +++ b/chromium/components/sync/model/BUILD.gn @@ -52,6 +52,7 @@ static_library("model") { "processor_entity_tracker.h", "proxy_model_type_controller_delegate.cc", "proxy_model_type_controller_delegate.h", + "string_ordinal.cc", "string_ordinal.h", "sync_change.cc", "sync_change.h", diff --git a/chromium/components/sync/model/string_ordinal.h b/chromium/components/sync/model/string_ordinal.h index e375759bb6c..8e38e243fc9 100644 --- a/chromium/components/sync/model/string_ordinal.h +++ b/chromium/components/sync/model/string_ordinal.h @@ -5,29 +5,194 @@ #ifndef COMPONENTS_SYNC_MODEL_STRING_ORDINAL_H_ #define COMPONENTS_SYNC_MODEL_STRING_ORDINAL_H_ -#include <stddef.h> -#include <stdint.h> +#include <cstddef> +#include <cstdint> +#include <string> -#include "components/sync/base/ordinal.h" +namespace mojo { +template <typename DataViewType, typename T> +struct StructTraits; +} namespace syncer { -// A StringOrdinal is an Ordinal with range 'a'-'z' for printability -// of its internal byte string representation. (Think of -// StringOrdinal as being short for PrintableStringOrdinal.) It -// should be used for data types that want to maintain one or more -// orderings for nodes. +namespace mojom { +class StringOrdinalDataView; +} + +// WARNING, DO NOT USE! Use UniquePosition instead. +// +// +// A StringOrdinal is an object that can be used for ordering. The +// StringOrdinal class has an unbounded dense strict total order, which +// mean for any StringOrdinals a, b and c: +// +// - a < b and b < c implies a < c (transitivity); +// - exactly one of a < b, b < a and a = b holds (trichotomy); +// - if a < b, there is a StringOrdinal x such that a < x < b (density); +// - there are Ordinals<T> x and y such that x < a < y (unboundedness). +// +// This means that when StringOrdinal is used for sorting a list, if any +// item changes its position in the list, only its StringOrdinal value +// has to change to represent the new order, and all the other values +// can stay the same. +// +// A StringOrdinal is internally represented as an array of bytes, so it +// can be serialized to and deserialized from disk. +// +// A StringOrdinal is valid iff its corresponding string has at least +// kMinLength characters, does not contain any characters less than +// kZeroDigit or greater than kMaxDigit, is not all zero digits, and +// does not have any unnecessary trailing zero digits. // // Since StringOrdinals contain only printable characters, it is safe // to store as a string in a protobuf. +class StringOrdinal { + public: + // Functors for use with STL algorithms and containers. + class LessThanFn { + public: + LessThanFn(); + + bool operator()(const StringOrdinal& lhs, const StringOrdinal& rhs) const; + }; + + class EqualsFn { + public: + EqualsFn(); + + bool operator()(const StringOrdinal& lhs, const StringOrdinal& rhs) const; + }; + + // Creates an StringOrdinal from the given string of bytes. The StringOrdinal + // may be valid or invalid. + explicit StringOrdinal(const std::string& bytes); + + // Creates an invalid StringOrdinal. + StringOrdinal(); + + // Creates a valid initial StringOrdinal. This is called to create the first + // element of StringOrdinal list (i.e. before we have any other values we can + // generate from). + static StringOrdinal CreateInitialOrdinal(); + + // Returns true iff this StringOrdinal is valid. This takes constant + // time. + bool IsValid() const; + + // Returns true iff |*this| == |other| or |*this| and |other| + // are both invalid. + bool EqualsOrBothInvalid(const StringOrdinal& other) const; + + // Returns a printable string representation of the StringOrdinal suitable + // for logging. + std::string ToDebugString() const; + + // All remaining functions can only be called if IsValid() holds. + // It is an error to call them if IsValid() is false. + + // Order-related functions. + + // Returns true iff |*this| < |other|. + bool LessThan(const StringOrdinal& other) const; + + // Returns true iff |*this| > |other|. + bool GreaterThan(const StringOrdinal& other) const; -struct StringOrdinalTraits { + // Returns true iff |*this| == |other| (i.e. |*this| < |other| and + // |other| < |*this| are both false). + bool Equals(const StringOrdinal& other) const; + + // Given |*this| != |other|, returns a StringOrdinal x such that + // min(|*this|, |other|) < x < max(|*this|, |other|). It is an error + // to call this function when |*this| == |other|. + StringOrdinal CreateBetween(const StringOrdinal& other) const; + + // Returns a StringOrdinal |x| such that |x| < |*this|. + StringOrdinal CreateBefore() const; + + // Returns a StringOrdinal |x| such that |*this| < |x|. + StringOrdinal CreateAfter() const; + + // Returns the string of bytes representing the StringOrdinal. It is + // guaranteed that an StringOrdinal constructed from the returned string + // will be valid. + std::string ToInternalValue() const; + + // Use of copy constructor and default assignment for this class is allowed. + + // Constants for StringOrdinal digits. static const uint8_t kZeroDigit = 'a'; static const uint8_t kMaxDigit = 'z'; static const size_t kMinLength = 1; + static const uint8_t kOneDigit = kZeroDigit + 1; + static const uint8_t kMidDigit = kOneDigit + (kMaxDigit - kOneDigit) / 2; + static const unsigned int kMidDigitValue = kMidDigit - kZeroDigit; + static const unsigned int kMaxDigitValue = kMaxDigit - kZeroDigit; + static const unsigned int kRadix = kMaxDigitValue + 1; + + static_assert(kOneDigit > kZeroDigit, "incorrect StringOrdinal one digit"); + static_assert(kMidDigit > kOneDigit, "incorrect StringOrdinal mid digit"); + static_assert(kMaxDigit > kMidDigit, "incorrect StringOrdinal max digit"); + static_assert(kMinLength > 0, "incorrect StringOrdinal min length"); + static_assert(kMidDigitValue > 1, "incorrect StringOrdinal mid digit"); + static_assert(kMaxDigitValue > kMidDigitValue, + "incorrect StringOrdinal max digit"); + static_assert(kRadix == kMaxDigitValue + 1, "incorrect StringOrdinal radix"); + + private: + friend struct mojo::StructTraits<syncer::mojom::StringOrdinalDataView, + StringOrdinal>; + + // Returns true iff the given byte string satisfies the criteria for + // a valid StringOrdinal. + static bool IsValidOrdinalBytes(const std::string& bytes); + + // Returns the length that bytes.substr(0, length) would be with + // trailing zero digits removed. + static size_t GetLengthWithoutTrailingZeroDigits(const std::string& bytes, + size_t length); + + // Returns the digit at position i, padding with zero digits if + // required. + static uint8_t GetDigit(const std::string& bytes, size_t i); + + // Returns the digit value at position i, padding with 0 if required. + static int GetDigitValue(const std::string& bytes, size_t i); + + // Adds the given value to |bytes| at position i, carrying when + // necessary. Returns the left-most carry. + static int AddDigitValue(std::string* bytes, size_t i, int digit_value); + + // Returns the proper length |bytes| should be resized to, i.e. the + // smallest length such that |bytes| is still greater than + // |lower_bound| and is still valid. |bytes| should be greater than + // |lower_bound|. + static size_t GetProperLength(const std::string& lower_bound, + const std::string& bytes); + + // Compute the midpoint StringOrdinal byte string that is between |start| + // and |end|. + static std::string ComputeMidpoint(const std::string& start, + const std::string& end); + + // Create a StringOrdinal that is lexigraphically greater than |start| and + // lexigraphically less than |end|. The returned StringOrdinal will be roughly + // between |start| and |end|. + static StringOrdinal CreateOrdinalBetween(const StringOrdinal& start, + const StringOrdinal& end); + + // The internal byte string representation of the StringOrdinal. Never + // changes after construction except for assignment. + std::string bytes_; + + // A cache of the result of IsValidOrdinalBytes(bytes_). + bool is_valid_; }; -using StringOrdinal = Ordinal<StringOrdinalTraits>; +bool operator==(const StringOrdinal& lhs, const StringOrdinal& rhs); + +bool operator!=(const StringOrdinal& lhs, const StringOrdinal& rhs); static_assert(StringOrdinal::kZeroDigit == 'a', "StringOrdinal has incorrect zero digit"); diff --git a/chromium/components/sync/protocol/protocol_sources.gni b/chromium/components/sync/protocol/protocol_sources.gni index 5e136c9efcf..000d0ff8cf2 100644 --- a/chromium/components/sync/protocol/protocol_sources.gni +++ b/chromium/components/sync/protocol/protocol_sources.gni @@ -2,82 +2,73 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -sync_protocol_bases = [ - "app_notification_specifics", - "app_setting_specifics", - "app_specifics", - "app_list_specifics", - "arc_package_specifics", - "autofill_offer_specifics", - "autofill_specifics", - "bookmark_model_metadata", - "bookmark_specifics", - "client_commands", - "client_debug_info", - "data_type_progress_marker", - "device_info_specifics", - "dictionary_specifics", - "encryption", - "entity_metadata", - "entity_specifics", - "experiments_specifics", - "extension_setting_specifics", - "extension_specifics", - "favicon_image_specifics", - "favicon_tracking_specifics", - "gaia_password_reuse", - "get_updates_caller_info", - "history_delete_directive_specifics", - "history_status", - "list_passwords_result", - "local_trusted_vault", - "loopback_server", - "managed_user_setting_specifics", - "managed_user_shared_setting_specifics", - "managed_user_specifics", - "model_type_state", - "model_type_store_schema_descriptor", - "nigori_local_data", - "nigori_specifics", - "os_preference_specifics", - "os_priority_preference_specifics", - "password_specifics", - "password_with_local_data", - "persisted_entity_data", - "preference_specifics", - "printer_specifics", - "priority_preference_specifics", - "reading_list_specifics", - "search_engine_specifics", - "security_event_specifics", - "send_tab_to_self_specifics", - "session_specifics", - "sharing_message_specifics", - "sync", - "sync_entity", - "sync_enums", - "sync_invalidations_payload", - "synced_notification_app_info_specifics", - "synced_notification_specifics", - "test", - "theme_specifics", - "typed_url_specifics", - "unique_position", - "user_consent_specifics", - "user_consent_types", - "user_event_specifics", - "vault", - "web_app_specifics", - "webauthn_credential_specifics", - "wifi_configuration_specifics", - "workspace_desk_specifics", +sync_protocol_sources = [ + "app_notification_specifics.proto", + "app_setting_specifics.proto", + "app_specifics.proto", + "app_list_specifics.proto", + "arc_package_specifics.proto", + "autofill_offer_specifics.proto", + "autofill_specifics.proto", + "bookmark_model_metadata.proto", + "bookmark_specifics.proto", + "client_commands.proto", + "client_debug_info.proto", + "data_type_progress_marker.proto", + "device_info_specifics.proto", + "dictionary_specifics.proto", + "encryption.proto", + "entity_metadata.proto", + "entity_specifics.proto", + "experiments_specifics.proto", + "extension_setting_specifics.proto", + "extension_specifics.proto", + "favicon_image_specifics.proto", + "favicon_tracking_specifics.proto", + "gaia_password_reuse.proto", + "get_updates_caller_info.proto", + "history_delete_directive_specifics.proto", + "history_status.proto", + "list_passwords_result.proto", + "local_trusted_vault.proto", + "loopback_server.proto", + "managed_user_setting_specifics.proto", + "managed_user_shared_setting_specifics.proto", + "managed_user_specifics.proto", + "model_type_state.proto", + "model_type_store_schema_descriptor.proto", + "nigori_local_data.proto", + "nigori_specifics.proto", + "os_preference_specifics.proto", + "os_priority_preference_specifics.proto", + "password_specifics.proto", + "password_with_local_data.proto", + "persisted_entity_data.proto", + "preference_specifics.proto", + "printer_specifics.proto", + "priority_preference_specifics.proto", + "reading_list_specifics.proto", + "search_engine_specifics.proto", + "security_event_specifics.proto", + "send_tab_to_self_specifics.proto", + "session_specifics.proto", + "sharing_message_specifics.proto", + "sync.proto", + "sync_entity.proto", + "sync_enums.proto", + "sync_invalidations_payload.proto", + "synced_notification_app_info_specifics.proto", + "synced_notification_specifics.proto", + "test.proto", + "theme_specifics.proto", + "typed_url_specifics.proto", + "unique_position.proto", + "user_consent_specifics.proto", + "user_consent_types.proto", + "user_event_specifics.proto", + "vault.proto", + "web_app_specifics.proto", + "webauthn_credential_specifics.proto", + "wifi_configuration_specifics.proto", + "workspace_desk_specifics.proto", ] - -sync_protocol_sources = [] -sync_protocol_pyprotos = [] - -foreach(base, sync_protocol_bases) { - sync_protocol_sources += [ "//components/sync/protocol/${base}.proto" ] - sync_protocol_pyprotos += - [ "$root_out_dir/pyproto/components/sync/protocol/${base}_pb2.py" ] -} |