logging.cc raw

   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  
  12  #include <limits>
  13  
  14  #include "leveldb/env.h"
  15  #include "leveldb/slice.h"
  16  
  17  namespace leveldb {
  18  
  19  void AppendNumberTo(std::string* str, uint64_t num) {
  20    char buf[30];
  21    snprintf(buf, sizeof(buf), "%llu", (unsigned long long)num);
  22    str->append(buf);
  23  }
  24  
  25  void AppendEscapedStringTo(std::string* str, const Slice& value) {
  26    for (size_t i = 0; i < value.size(); i++) {
  27      char c = value[i];
  28      if (c >= ' ' && c <= '~') {
  29        str->push_back(c);
  30      } else {
  31        char buf[10];
  32        snprintf(buf, sizeof(buf), "\\x%02x",
  33                 static_cast<unsigned int>(c) & 0xff);
  34        str->append(buf);
  35      }
  36    }
  37  }
  38  
  39  std::string NumberToString(uint64_t num) {
  40    std::string r;
  41    AppendNumberTo(&r, num);
  42    return r;
  43  }
  44  
  45  std::string EscapeString(const Slice& value) {
  46    std::string r;
  47    AppendEscapedStringTo(&r, value);
  48    return r;
  49  }
  50  
  51  bool ConsumeDecimalNumber(Slice* in, uint64_t* val) {
  52    // Constants that will be optimized away.
  53    constexpr const uint64_t kMaxUint64 = std::numeric_limits<uint64_t>::max();
  54    constexpr const char kLastDigitOfMaxUint64 =
  55        '0' + static_cast<char>(kMaxUint64 % 10);
  56  
  57    uint64_t value = 0;
  58  
  59    // reinterpret_cast-ing from char* to uint8_t* to avoid signedness.
  60    const uint8_t* start = reinterpret_cast<const uint8_t*>(in->data());
  61  
  62    const uint8_t* end = start + in->size();
  63    const uint8_t* current = start;
  64    for (; current != end; ++current) {
  65      const uint8_t ch = *current;
  66      if (ch < '0' || ch > '9') break;
  67  
  68      // Overflow check.
  69      // kMaxUint64 / 10 is also constant and will be optimized away.
  70      if (value > kMaxUint64 / 10 ||
  71          (value == kMaxUint64 / 10 && ch > kLastDigitOfMaxUint64)) {
  72        return false;
  73      }
  74  
  75      value = (value * 10) + (ch - '0');
  76    }
  77  
  78    *val = value;
  79    const size_t digits_consumed = current - start;
  80    in->remove_prefix(digits_consumed);
  81    return digits_consumed != 0;
  82  }
  83  
  84  }  // namespace leveldb
  85