1// Copyright (c) 2011 The LevelDB 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. See the AUTHORS file for names of contributors.
4
5#include "util/logging.h"
6
7#include <errno.h>
8#include <stdarg.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include "leveldb/env.h"
12#include "leveldb/slice.h"
13
14namespace leveldb {
15
16void AppendNumberTo(std::string* str, uint64_t num) {
17  char buf[30];
18  snprintf(buf, sizeof(buf), "%llu", (unsigned long long) num);
19  str->append(buf);
20}
21
22void AppendEscapedStringTo(std::string* str, const Slice& value) {
23  for (size_t i = 0; i < value.size(); i++) {
24    char c = value[i];
25    if (c >= ' ' && c <= '~') {
26      str->push_back(c);
27    } else {
28      char buf[10];
29      snprintf(buf, sizeof(buf), "\\x%02x",
30               static_cast<unsigned int>(c) & 0xff);
31      str->append(buf);
32    }
33  }
34}
35
36std::string NumberToString(uint64_t num) {
37  std::string r;
38  AppendNumberTo(&r, num);
39  return r;
40}
41
42std::string EscapeString(const Slice& value) {
43  std::string r;
44  AppendEscapedStringTo(&r, value);
45  return r;
46}
47
48bool ConsumeChar(Slice* in, char c) {
49  if (!in->empty() && (*in)[0] == c) {
50    in->remove_prefix(1);
51    return true;
52  } else {
53    return false;
54  }
55}
56
57bool ConsumeDecimalNumber(Slice* in, uint64_t* val) {
58  uint64_t v = 0;
59  int digits = 0;
60  while (!in->empty()) {
61    char c = (*in)[0];
62    if (c >= '0' && c <= '9') {
63      ++digits;
64      const int delta = (c - '0');
65      static const uint64_t kMaxUint64 = ~static_cast<uint64_t>(0);
66      if (v > kMaxUint64/10 ||
67          (v == kMaxUint64/10 && delta > kMaxUint64%10)) {
68        // Overflow
69        return false;
70      }
71      v = (v * 10) + delta;
72      in->remove_prefix(1);
73    } else {
74      break;
75    }
76  }
77  *val = v;
78  return (digits > 0);
79}
80
81}  // namespace leveldb
82