Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 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 | |
| 5 #include "chrome/common/string_index.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 | |
| 9 // Constants | |
| 10 static const std::string kInvalidStringIndex = ""; | |
|
akalin
2011/10/14 10:16:29
static non-POD types are a no-no. use 'static con
| |
| 11 static const char kZeroDigit = 'A'; | |
|
akalin
2011/10/14 10:16:29
prefer anon namespace
| |
| 12 static const char kMinDigit = 'B'; | |
| 13 static const char kMidDigit = 'N'; | |
| 14 static const char kMaxDigit = 'Z'; | |
| 15 static const int kMaxDigitValue = kMaxDigit - kZeroDigit; | |
| 16 static const int kMidDigitValue = kMidDigit - kZeroDigit; | |
| 17 static const int kFullDigitValue = (kMaxDigit + 1) - kZeroDigit; | |
| 18 | |
| 19 | |
| 20 StringIndex::StringIndex(const std::string& str) : string_index_(str) { | |
| 21 | |
| 22 } | |
| 23 | |
| 24 StringIndex::StringIndex() : string_index_(kInvalidStringIndex) { | |
| 25 } | |
| 26 | |
| 27 bool StringIndex::IsValid() const { | |
| 28 if (string_index_ == kInvalidStringIndex) { | |
|
akalin
2011/10/14 10:16:29
simply check for empty
| |
| 29 return false; | |
| 30 } | |
| 31 | |
| 32 for (size_t i = 0; i < string_index_.length(); ++i) { | |
|
akalin
2011/10/14 10:16:29
better to do this computation in the constructor a
| |
| 33 if (string_index_[i] < kZeroDigit || string_index_[i] > kMaxDigit) { | |
| 34 return false; | |
| 35 } | |
| 36 } | |
| 37 | |
| 38 return (string_index_[string_index_.length() - 1] > kZeroDigit); | |
|
akalin
2011/10/14 10:16:29
and it must also be <= maxdigit
csharp1
2011/10/14 16:52:36
This is already checked in the above for loop. We
| |
| 39 } | |
| 40 | |
| 41 bool StringIndex::LessThan(const StringIndex& other) const { | |
| 42 return string_index_ < other.string_index_; | |
|
akalin
2011/10/14 10:16:29
CHECK that both strings are valid (this goes for a
| |
| 43 } | |
| 44 | |
| 45 StringIndex StringIndex::CreateBetween(const StringIndex& other) const { | |
| 46 DCHECK(LessThan(other)); | |
| 47 | |
| 48 return CreateStringIndexBetween(*this, other); | |
| 49 } | |
| 50 | |
| 51 StringIndex StringIndex::CreateBefore() const { | |
| 52 StringIndex start = StringIndex(std::string(string_index_.length(), | |
| 53 kZeroDigit)); | |
| 54 | |
| 55 return CreateStringIndexBetween(start, *this); | |
| 56 } | |
| 57 | |
| 58 StringIndex StringIndex::CreateAfter() const { | |
| 59 std::string end = std::string(string_index_.length(), kMaxDigit); | |
| 60 if (end == string_index_) { | |
| 61 end += kMaxDigit; | |
| 62 } | |
| 63 StringIndex end_index = StringIndex(end); | |
| 64 | |
| 65 return CreateStringIndexBetween(*this, end_index); | |
| 66 } | |
| 67 | |
| 68 std::string StringIndex::ToString() const { | |
| 69 return string_index_; | |
| 70 } | |
| 71 | |
| 72 int StringIndex::GetPositionValue(size_t i) const { | |
| 73 return i < string_index_.length() ? string_index_[i] - kZeroDigit : 0; | |
|
akalin
2011/10/14 10:16:29
use parenthesis to the clauses of the ternary oper
| |
| 74 } | |
| 75 | |
| 76 StringIndex StringIndex::CreateStringIndexBetween(const StringIndex& start, | |
| 77 const StringIndex& end) { | |
| 78 DCHECK(start.LessThan(end)); | |
| 79 | |
| 80 std::string middle_string = ComputeMidpoint(start, end); | |
| 81 middle_string = RemoveTrailingZeros(middle_string); | |
| 82 DCHECK_GT(middle_string, start.ToString()); | |
| 83 DCHECK_LT(middle_string, end.ToString()); | |
| 84 | |
| 85 return StringIndex(middle_string); | |
| 86 } | |
| 87 | |
| 88 std::string StringIndex::ComputeMidpoint(const StringIndex& start, | |
|
akalin
2011/10/14 10:16:29
so when i asked you to decomp this function out, I
| |
| 89 const StringIndex& end) { | |
| 90 size_t max_size = std::max(start.ToString().length(), | |
|
akalin
2011/10/14 10:16:29
#include <algorithm> for max
akalin
2011/10/14 10:16:29
CHECK that both start and end are valid
akalin
2011/10/14 10:16:29
rather than calling ToString() multiple times, set
| |
| 91 end.ToString().length()); | |
| 92 std::string middle_string(max_size, kZeroDigit); | |
| 93 | |
| 94 bool add_half = false; | |
| 95 for (size_t i = 0; i < max_size; ++i) { | |
| 96 int char_value = start.GetPositionValue(i); | |
| 97 char_value += end.GetPositionValue(i); | |
| 98 | |
| 99 middle_string[i] += (char_value / 2); | |
| 100 if (add_half) { | |
| 101 AddHalf(i, middle_string); | |
| 102 } | |
| 103 add_half = (char_value % 2 == 1); | |
| 104 } | |
| 105 | |
| 106 // We only add an extra digit if it is required for uniqueness, otherwise | |
| 107 // we accept a close to middle placement | |
| 108 if (add_half && EqualValueIndexs(middle_string,start.ToString())) { | |
|
csharp1
2011/10/13 16:07:08
Note that if middle_string.length() > max_size it
akalin
2011/10/14 10:16:29
if start is valid (which it should be if you check
| |
| 109 middle_string += kMidDigit; | |
| 110 } | |
| 111 | |
| 112 return middle_string; | |
| 113 } | |
| 114 | |
| 115 bool StringIndex::EqualValueIndexs(const std::string& rhs, | |
| 116 const std::string& lhs) { | |
| 117 return RemoveTrailingZeros(rhs) == RemoveTrailingZeros(lhs); | |
| 118 } | |
| 119 | |
| 120 void StringIndex::AddHalf(size_t position, std::string& value) { | |
| 121 DCHECK_GT(position, static_cast<size_t>(0)); | |
| 122 value[position] += kMidDigitValue; | |
| 123 | |
| 124 for (size_t i = position; value[i] > kMaxDigit; --i) { | |
| 125 DCHECK(i > 0); | |
|
akalin
2011/10/14 10:16:29
DCHECK_GT
akalin
2011/10/14 10:16:29
better to CHECK -- if this fails, you'll do an out
| |
| 126 value[i] -= kFullDigitValue; | |
| 127 ++value[i - 1]; | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 std::string StringIndex::RemoveTrailingZeros(const std::string& value) { | |
| 132 DCHECK(!value.empty()); | |
| 133 | |
| 134 int end_position = value.length() - 1; | |
| 135 while (value[end_position] == kZeroDigit) { | |
| 136 --end_position; | |
| 137 } | |
| 138 | |
| 139 return value.substr(0, end_position + 1); | |
| 140 } | |
| OLD | NEW |