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 : : } 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 : : }
36 : : }
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 : 3010 : bool ConsumeDecimalNumber(Slice* in, uint64_t* val) {
52 : : // Constants that will be optimized away.
53 : 3010 : constexpr const uint64_t kMaxUint64 = std::numeric_limits<uint64_t>::max();
54 : 3010 : constexpr const char kLastDigitOfMaxUint64 =
55 : : '0' + static_cast<char>(kMaxUint64 % 10);
56 : :
57 : 3010 : uint64_t value = 0;
58 : :
59 : : // reinterpret_cast-ing from char* to uint8_t* to avoid signedness.
60 : 3010 : const uint8_t* start = reinterpret_cast<const uint8_t*>(in->data());
61 : :
62 : 3010 : const uint8_t* end = start + in->size();
63 : 3010 : const uint8_t* current = start;
64 [ + + ]: 17800 : for (; current != end; ++current) {
65 : 16303 : const uint8_t ch = *current;
66 [ + + ]: 16303 : if (ch < '0' || ch > '9') break;
67 : :
68 : : // Overflow check.
69 : : // kMaxUint64 / 10 is also constant and will be optimized away.
70 [ + - ]: 14790 : if (value > kMaxUint64 / 10 ||
71 [ + - ]: 14790 : (value == kMaxUint64 / 10 && ch > kLastDigitOfMaxUint64)) {
72 : : return false;
73 : : }
74 : :
75 : 14790 : value = (value * 10) + (ch - '0');
76 : : }
77 : :
78 : 3010 : *val = value;
79 : 3010 : const size_t digits_consumed = current - start;
80 : 3010 : in->remove_prefix(digits_consumed);
81 : 3010 : return digits_consumed != 0;
82 : : }
83 : :
84 : : } // namespace leveldb
|