1// Copyright (c) 2012 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 "sync/internal_api/public/base/node_ordinal.h"
6
7#include <algorithm>
8
9namespace syncer {
10
11NodeOrdinal Int64ToNodeOrdinal(int64 x) {
12  uint64 y = static_cast<uint64>(x);
13  y ^= 0x8000000000000000ULL;
14  std::string bytes(NodeOrdinal::kMinLength, '\x00');
15  if (y == 0) {
16    // 0 is a special case since |bytes| must not be all zeros.
17    bytes.push_back('\x80');
18  } else {
19    for (int i = 7; i >= 0; --i) {
20      bytes[i] = static_cast<uint8>(y);
21      y >>= 8;
22    }
23  }
24  NodeOrdinal ordinal(bytes);
25  DCHECK(ordinal.IsValid());
26  return ordinal;
27}
28
29int64 NodeOrdinalToInt64(const NodeOrdinal& ordinal) {
30  uint64 y = 0;
31  const std::string& s = ordinal.ToInternalValue();
32  size_t l = NodeOrdinal::kMinLength;
33  if (s.length() < l) {
34    NOTREACHED();
35    l = s.length();
36  }
37  for (size_t i = 0; i < l; ++i) {
38    const uint8 byte = s[l - i - 1];
39    y |= static_cast<uint64>(byte) << (i * 8);
40  }
41  y ^= 0x8000000000000000ULL;
42  // This is technically implementation-defined if y > INT64_MAX, so
43  // we're assuming that we're on a twos-complement machine.
44  return static_cast<int64>(y);
45}
46
47}  // namespace syncer
48