Chromium Code Reviews| Index: sync/internal_api/public/base/node_ordinal.cc |
| diff --git a/sync/internal_api/public/base/node_ordinal.cc b/sync/internal_api/public/base/node_ordinal.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..59d21ab16c879f7aa43cc119a7acfd57be51b171 |
| --- /dev/null |
| +++ b/sync/internal_api/public/base/node_ordinal.cc |
| @@ -0,0 +1,42 @@ |
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
rlarocque
2012/09/05 21:43:46
I'm not convinced the functions in this file are e
akalin
2012/09/06 19:25:14
I asked, and I don't think we have access to big-e
rlarocque
2012/09/06 21:25:55
Sounds good. I was mainly concerned about the bit
|
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "sync/internal_api/public/base/node_ordinal.h" |
| + |
| +#include <algorithm> |
| + |
| +namespace syncer { |
| + |
| +NodeOrdinal Int64ToNodeOrdinal(int64 x) { |
| + uint64 y = static_cast<uint64>(x); |
| + y ^= 0x8000000000000000ULL; |
|
rlarocque
2012/09/05 21:43:46
What is the intent of this statement?
akalin
2012/09/06 19:25:14
The ordering of an int differs depending on its si
rlarocque
2012/09/06 21:25:55
IIRC, uint64 addition is defined to be correct mod
akalin
2012/09/06 22:55:25
Yeah, I think it's somewhat clearer to just twiddl
|
| + std::string ordinal_string(NodeOrdinal::kMinLength, '\x00'); |
| + if (y == 0) { |
| + // 0 is a special case since |ordinal_string| must not be all |
| + // zeros. |
| + ordinal_string.push_back('\x80'); |
|
rlarocque
2012/09/05 21:43:46
This is not symmetric, right?
Because of this,
N
akalin
2012/09/06 19:25:14
It's not symmetric, but it's still reversible, sin
rlarocque
2012/09/06 21:25:55
Now I understand. I overlooked the fact that the
|
| + } else { |
| + for (int i = 7; i >= 0; --i) { |
| + ordinal_string[i] = static_cast<uint8>(y); |
|
rlarocque
2012/09/05 21:43:46
I looked up the spec because I wasn't sure the res
akalin
2012/09/06 19:25:14
Yeap, most of the pitfalls lie with signed ints.
|
| + y >>= 8; |
| + } |
| + } |
| + NodeOrdinal ordinal(ordinal_string); |
| + DCHECK(ordinal.IsValid()); |
| + return ordinal; |
| +} |
| + |
| +int64 NodeOrdinalToInt64(const NodeOrdinal& ordinal) { |
| + uint64 y = 0; |
| + const std::string& s = ordinal.ToString(); |
|
rlarocque
2012/09/05 21:43:46
Huh. I did not expect ToString() to be used this
akalin
2012/09/06 19:25:14
As discussed in the other comment, fixed.
|
| + const size_t l = std::min(NodeOrdinal::kMinLength, s.length()); |
|
rlarocque
2012/09/05 21:43:46
Won't this always equal kMinLength? I think that
akalin
2012/09/06 19:25:14
You're right. I still want to avoid out-of-bound
|
| + for (size_t i = 0; i < l; ++i) { |
| + const uint8 byte = s[l - i - 1]; |
| + y |= static_cast<uint64>(byte) << (i * 8); |
| + } |
| + y ^= 0x8000000000000000ULL; |
| + return static_cast<int64>(y); |
|
rlarocque
2012/09/05 21:43:46
Now this I think actually is undefined if y > INT6
akalin
2012/09/06 19:25:14
Implementation-defined, actually, so I think it's
|
| +} |
| + |
| +} // namespace syncer |