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