12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. See the AUTHORS file for names of contributors.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "util/logging.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <errno.h>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdarg.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdio.h>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdlib.h>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "leveldb/env.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "leveldb/slice.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace leveldb {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppendNumberTo(std::string* str, uint64_t num) {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  char buf[30];
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  snprintf(buf, sizeof(buf), "%llu", (unsigned long long) num);
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  str->append(buf);
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppendEscapedStringTo(std::string* str, const Slice& value) {
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < value.size(); i++) {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    char c = value[i];
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (c >= ' ' && c <= '~') {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      str->push_back(c);
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      char buf[10];
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      snprintf(buf, sizeof(buf), "\\x%02x",
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               static_cast<unsigned int>(c) & 0xff);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      str->append(buf);
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string NumberToString(uint64_t num) {
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string r;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendNumberTo(&r, num);
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return r;
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string EscapeString(const Slice& value) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string r;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AppendEscapedStringTo(&r, value);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return r;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ConsumeChar(Slice* in, char c) {
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!in->empty() && (*in)[0] == c) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    in->remove_prefix(1);
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    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