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 |