15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/internal_api/public/base/node_ordinal.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace syncer {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NodeOrdinal Int64ToNodeOrdinal(int64 x) {
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 y = static_cast<uint64>(x);
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  y ^= 0x8000000000000000ULL;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string bytes(NodeOrdinal::kMinLength, '\x00');
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (y == 0) {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // 0 is a special case since |bytes| must not be all zeros.
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bytes.push_back('\x80');
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 7; i >= 0; --i) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      bytes[i] = static_cast<uint8>(y);
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      y >>= 8;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NodeOrdinal ordinal(bytes);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(ordinal.IsValid());
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ordinal;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int64 NodeOrdinalToInt64(const NodeOrdinal& ordinal) {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 y = 0;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string& s = ordinal.ToInternalValue();
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t l = NodeOrdinal::kMinLength;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (s.length() < l) {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTREACHED();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    l = s.length();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < l; ++i) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const uint8 byte = s[l - i - 1];
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    y |= static_cast<uint64>(byte) << (i * 8);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  y ^= 0x8000000000000000ULL;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is technically implementation-defined if y > INT64_MAX, so
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we're assuming that we're on a twos-complement machine.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<int64>(y);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace syncer
48