Coverage Report

Created: 2025-03-12 11:55

/root/doris/be/src/gutil/strings/numbers.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2010 Google Inc. All Rights Reserved.
2
// Refactored from contributions of various authors in strings/strutil.cc
3
//
4
// This file contains string processing functions related to
5
// numeric values.
6
7
#include "gutil/strings/numbers.h"
8
9
#include <assert.h>
10
#include <ctype.h>
11
#include <errno.h>
12
#include <float.h> // for DBL_DIG and FLT_DIG
13
#include <math.h>  // for HUGE_VAL
14
#include <stdio.h>
15
#include <stdlib.h>
16
#include <string.h>
17
#include <inttypes.h>
18
#include <sys/types.h>
19
#include <limits>
20
#include <ostream>
21
22
#include "common/exception.h"
23
24
using std::numeric_limits;
25
#include <string>
26
27
using std::string;
28
29
#include <fmt/compile.h>
30
#include <fmt/format.h>
31
32
#include "common/logging.h"
33
34
#include "gutil/gscoped_ptr.h"
35
#include "gutil/integral_types.h"
36
#include "gutil/stringprintf.h"
37
#include "gutil/strings/ascii_ctype.h"
38
#include "gutil/strtoint.h"
39
40
// Reads a <double> in *text, which may not be whitespace-initiated.
41
// *len is the length, or -1 if text is '\0'-terminated, which is more
42
// efficient.  Sets *text to the end of the double, and val to the
43
// converted value, and the length of the double is subtracted from
44
// *len. <double> may also be a '?', in which case val will be
45
// unchanged. Returns true upon success.  If initial_minus is
46
// non-NULL, then *initial_minus will indicate whether the first
47
// symbol seen was a '-', which will be ignored. Similarly, if
48
// final_period is non-NULL, then *final_period will indicate whether
49
// the last symbol seen was a '.', which will be ignored. This is
50
// useful in case that an initial '-' or final '.' would have another
51
// meaning (as a separator, e.g.).
52
static inline bool EatADouble(const char** text, int* len, bool allow_question, double* val,
53
0
                              bool* initial_minus, bool* final_period) {
54
0
    const char* pos = *text;
55
0
    int rem = *len; // remaining length, or -1 if null-terminated
56
57
0
    if (pos == nullptr || rem == 0) return false;
58
59
0
    if (allow_question && (*pos == '?')) {
60
0
        *text = pos + 1;
61
0
        if (rem != -1) *len = rem - 1;
62
0
        return true;
63
0
    }
64
65
0
    if (initial_minus) {
66
0
        if ((*initial_minus = (*pos == '-'))) { // Yes, we want assignment.
67
0
            if (rem == 1) return false;
68
0
            ++pos;
69
0
            if (rem != -1) --rem;
70
0
        }
71
0
    }
72
73
    // a double has to begin one of these (we don't allow 'inf' or whitespace)
74
    // this also serves as an optimization.
75
0
    if (!strchr("-+.0123456789", *pos)) return false;
76
77
    // strtod is evil in that the second param is a non-const char**
78
0
    char* end_nonconst;
79
0
    double retval;
80
0
    if (rem == -1) {
81
0
        retval = strtod(pos, &end_nonconst);
82
0
    } else {
83
        // not '\0'-terminated & no obvious terminator found. must copy.
84
0
        gscoped_array<char> buf(new char[rem + 1]);
85
0
        memcpy(buf.get(), pos, rem);
86
0
        buf[rem] = '\0';
87
0
        retval = strtod(buf.get(), &end_nonconst);
88
0
        end_nonconst = const_cast<char*>(pos) + (end_nonconst - buf.get());
89
0
    }
90
91
0
    if (pos == end_nonconst) return false;
92
93
0
    if (final_period) {
94
0
        *final_period = (end_nonconst[-1] == '.');
95
0
        if (*final_period) {
96
0
            --end_nonconst;
97
0
        }
98
0
    }
99
100
0
    *text = end_nonconst;
101
0
    *val = retval;
102
0
    if (rem != -1) *len = rem - (end_nonconst - pos);
103
0
    return true;
104
0
}
105
106
// If update, consume one of acceptable_chars from string *text of
107
// length len and return that char, or '\0' otherwise. If len is -1,
108
// *text is null-terminated. If update is false, don't alter *text and
109
// *len. If null_ok, then update must be false, and, if text has no
110
// more chars, then return '\1' (arbitrary nonzero).
111
static inline char EatAChar(const char** text, int* len, const char* acceptable_chars, bool update,
112
0
                            bool null_ok) {
113
0
    assert(!(update && null_ok));
114
0
    if ((*len == 0) || (**text == '\0'))
115
0
        return (null_ok ? '\1' : '\0'); // if null_ok, we're in predicate mode.
116
117
0
    if (strchr(acceptable_chars, **text)) {
118
0
        char result = **text;
119
0
        if (update) {
120
0
            ++(*text);
121
0
            if (*len != -1) --(*len);
122
0
        }
123
0
        return result;
124
0
    }
125
126
0
    return '\0'; // no match; no update
127
0
}
128
129
// Parse an expression in 'text' of the form: <comparator><double> or
130
// <double><sep><double> See full comments in header file.
131
bool ParseDoubleRange(const char* text, int len, const char** end, double* from, double* to,
132
0
                      bool* is_currency, const DoubleRangeOptions& opts) {
133
0
    const double from_default = opts.dont_modify_unbounded ? *from : -HUGE_VAL;
134
135
0
    if (!opts.dont_modify_unbounded) {
136
0
        *from = -HUGE_VAL;
137
0
        *to = HUGE_VAL;
138
0
    }
139
0
    if (opts.allow_currency && (is_currency != nullptr)) *is_currency = false;
140
141
0
    assert(len >= -1);
142
0
    assert(opts.separators && (*opts.separators != '\0'));
143
    // these aren't valid separators
144
0
    assert(strlen(opts.separators) == strcspn(opts.separators, "+0123456789eE$"));
145
0
    assert(opts.num_required_bounds <= 2);
146
147
    // Handle easier cases of comparators (<, >) first
148
0
    if (opts.allow_comparators) {
149
0
        char comparator = EatAChar(&text, &len, "<>", true, false);
150
0
        if (comparator) {
151
0
            double* dest = (comparator == '>') ? from : to;
152
0
            EatAChar(&text, &len, "=", true, false);
153
0
            if (opts.allow_currency && EatAChar(&text, &len, "$", true, false))
154
0
                if (is_currency != nullptr) *is_currency = true;
155
0
            if (!EatADouble(&text, &len, opts.allow_unbounded_markers, dest, nullptr, nullptr))
156
0
                return false;
157
0
            *end = text;
158
0
            return EatAChar(&text, &len, opts.acceptable_terminators, false,
159
0
                            opts.null_terminator_ok);
160
0
        }
161
0
    }
162
163
0
    bool seen_dollar = (opts.allow_currency && EatAChar(&text, &len, "$", true, false));
164
165
    // If we see a '-', two things could be happening: -<to> or
166
    // <from>... where <from> is negative. Treat initial minus sign as a
167
    // separator if '-' is a valid separator.
168
    // Similarly, we prepare for the possibility of seeing a '.' at the
169
    // end of the number, in case '.' (which really means '..') is a
170
    // separator.
171
0
    bool initial_minus_sign = false;
172
0
    bool final_period = false;
173
0
    bool* check_initial_minus =
174
0
            (strchr(opts.separators, '-') && !seen_dollar && (opts.num_required_bounds < 2))
175
0
                    ? (&initial_minus_sign)
176
0
                    : nullptr;
177
0
    bool* check_final_period = strchr(opts.separators, '.') ? (&final_period) : nullptr;
178
0
    bool double_seen = EatADouble(&text, &len, opts.allow_unbounded_markers, from,
179
0
                                  check_initial_minus, check_final_period);
180
181
    // if 2 bounds required, must see a double (or '?' if allowed)
182
0
    if ((opts.num_required_bounds == 2) && !double_seen) return false;
183
184
0
    if (seen_dollar && !double_seen) {
185
0
        --text;
186
0
        if (len != -1) ++len;
187
0
        seen_dollar = false;
188
0
    }
189
    // If we're here, we've read the first double and now expect a
190
    // separator and another <double>.
191
0
    char separator = EatAChar(&text, &len, opts.separators, true, false);
192
0
    if (separator == '.') {
193
        // seen one '.' as separator; must check for another; perhaps set seplen=2
194
0
        if (EatAChar(&text, &len, ".", true, false)) {
195
0
            if (final_period) {
196
                // We may have three periods in a row. The first is part of the
197
                // first number, the others are a separator. Policy: 234...567
198
                // is "234." to "567", not "234" to ".567".
199
0
                EatAChar(&text, &len, ".", true, false);
200
0
            }
201
0
        } else if (!EatAChar(&text, &len, opts.separators, true, false)) {
202
            // just one '.' and no other separator; uneat the first '.' we saw
203
0
            --text;
204
0
            if (len != -1) ++len;
205
0
            separator = '\0';
206
0
        }
207
0
    }
208
    // By now, we've consumed whatever separator there may have been,
209
    // and separator is true iff there was one.
210
0
    if (!separator) {
211
0
        if (final_period) // final period now considered part of first double
212
0
            EatAChar(&text, &len, ".", true, false);
213
0
        if (initial_minus_sign && double_seen) {
214
0
            *to = *from;
215
0
            *from = from_default;
216
0
        } else if (opts.require_separator || (opts.num_required_bounds > 0 && !double_seen) ||
217
0
                   (opts.num_required_bounds > 1)) {
218
0
            return false;
219
0
        }
220
0
    } else {
221
0
        if (initial_minus_sign && double_seen) *from = -(*from);
222
        // read second <double>
223
0
        bool second_dollar_seen = (seen_dollar || (opts.allow_currency && !double_seen)) &&
224
0
                                  EatAChar(&text, &len, "$", true, false);
225
0
        bool second_double_seen =
226
0
                EatADouble(&text, &len, opts.allow_unbounded_markers, to, nullptr, nullptr);
227
0
        if (opts.num_required_bounds > double_seen + second_double_seen) return false;
228
0
        if (second_dollar_seen && !second_double_seen) {
229
0
            --text;
230
0
            if (len != -1) ++len;
231
0
            second_dollar_seen = false;
232
0
        }
233
0
        seen_dollar = seen_dollar || second_dollar_seen;
234
0
    }
235
236
0
    if (seen_dollar && (is_currency != nullptr)) *is_currency = true;
237
    // We're done. But we have to check that the next char is a proper
238
    // terminator.
239
0
    *end = text;
240
0
    char terminator =
241
0
            EatAChar(&text, &len, opts.acceptable_terminators, false, opts.null_terminator_ok);
242
0
    if (terminator == '.') --(*end);
243
0
    return terminator;
244
0
}
245
246
// ----------------------------------------------------------------------
247
// ConsumeStrayLeadingZeroes
248
//    Eliminates all leading zeroes (unless the string itself is composed
249
//    of nothing but zeroes, in which case one is kept: 0...0 becomes 0).
250
// --------------------------------------------------------------------
251
252
0
void ConsumeStrayLeadingZeroes(string* const str) {
253
0
    const string::size_type len(str->size());
254
0
    if (len > 1 && (*str)[0] == '0') {
255
0
        const char *const begin(str->c_str()), *const end(begin + len), *ptr(begin + 1);
256
0
        while (ptr != end && *ptr == '0') {
257
0
            ++ptr;
258
0
        }
259
0
        string::size_type remove(ptr - begin);
260
0
        DCHECK_GT(ptr, begin);
261
0
        if (remove == len) {
262
0
            --remove; // if they are all zero, leave one...
263
0
        }
264
0
        str->erase(0, remove);
265
0
    }
266
0
}
267
268
// ----------------------------------------------------------------------
269
// ParseLeadingInt32Value()
270
// ParseLeadingUInt32Value()
271
//    A simple parser for [u]int32 values. Returns the parsed value
272
//    if a valid value is found; else returns deflt
273
//    This cannot handle decimal numbers with leading 0s.
274
// --------------------------------------------------------------------
275
276
0
int32 ParseLeadingInt32Value(const char* str, int32 deflt) {
277
0
    char* error = nullptr;
278
0
    long value = strtol(str, &error, 0);
279
    // Limit long values to int32 min/max.  Needed for lp64; no-op on 32 bits.
280
0
    if (value > numeric_limits<int32>::max()) {
281
0
        value = numeric_limits<int32>::max();
282
0
    } else if (value < numeric_limits<int32>::min()) {
283
0
        value = numeric_limits<int32>::min();
284
0
    }
285
0
    return (error == str) ? deflt : value;
286
0
}
287
288
0
uint32 ParseLeadingUInt32Value(const char* str, uint32 deflt) {
289
0
    if (numeric_limits<unsigned long>::max() == numeric_limits<uint32>::max()) {
290
        // When long is 32 bits, we can use strtoul.
291
0
        char* error = nullptr;
292
0
        const uint32 value = strtoul(str, &error, 0);
293
0
        return (error == str) ? deflt : value;
294
0
    } else {
295
        // When long is 64 bits, we must use strto64 and handle limits
296
        // by hand.  The reason we cannot use a 64-bit strtoul is that
297
        // it would be impossible to differentiate "-2" (that should wrap
298
        // around to the value UINT_MAX-1) from a string with ULONG_MAX-1
299
        // (that should be pegged to UINT_MAX due to overflow).
300
0
        char* error = nullptr;
301
0
        int64 value = strto64(str, &error, 0);
302
0
        if (value > numeric_limits<uint32>::max() ||
303
0
            value < -static_cast<int64>(numeric_limits<uint32>::max())) {
304
0
            value = numeric_limits<uint32>::max();
305
0
        }
306
        // Within these limits, truncation to 32 bits handles negatives correctly.
307
0
        return (error == str) ? deflt : value;
308
0
    }
309
0
}
310
311
// ----------------------------------------------------------------------
312
// ParseLeadingDec32Value
313
// ParseLeadingUDec32Value
314
//    A simple parser for [u]int32 values. Returns the parsed value
315
//    if a valid value is found; else returns deflt
316
//    The string passed in is treated as *10 based*.
317
//    This can handle strings with leading 0s.
318
// --------------------------------------------------------------------
319
320
0
int32 ParseLeadingDec32Value(const char* str, int32 deflt) {
321
0
    char* error = nullptr;
322
0
    long value = strtol(str, &error, 10);
323
    // Limit long values to int32 min/max.  Needed for lp64; no-op on 32 bits.
324
0
    if (value > numeric_limits<int32>::max()) {
325
0
        value = numeric_limits<int32>::max();
326
0
    } else if (value < numeric_limits<int32>::min()) {
327
0
        value = numeric_limits<int32>::min();
328
0
    }
329
0
    return (error == str) ? deflt : value;
330
0
}
331
332
0
uint32 ParseLeadingUDec32Value(const char* str, uint32 deflt) {
333
0
    if (numeric_limits<unsigned long>::max() == numeric_limits<uint32>::max()) {
334
        // When long is 32 bits, we can use strtoul.
335
0
        char* error = nullptr;
336
0
        const uint32 value = strtoul(str, &error, 10);
337
0
        return (error == str) ? deflt : value;
338
0
    } else {
339
        // When long is 64 bits, we must use strto64 and handle limits
340
        // by hand.  The reason we cannot use a 64-bit strtoul is that
341
        // it would be impossible to differentiate "-2" (that should wrap
342
        // around to the value UINT_MAX-1) from a string with ULONG_MAX-1
343
        // (that should be pegged to UINT_MAX due to overflow).
344
0
        char* error = nullptr;
345
0
        int64 value = strto64(str, &error, 10);
346
0
        if (value > numeric_limits<uint32>::max() ||
347
0
            value < -static_cast<int64>(numeric_limits<uint32>::max())) {
348
0
            value = numeric_limits<uint32>::max();
349
0
        }
350
        // Within these limits, truncation to 32 bits handles negatives correctly.
351
0
        return (error == str) ? deflt : value;
352
0
    }
353
0
}
354
355
// ----------------------------------------------------------------------
356
// ParseLeadingUInt64Value
357
// ParseLeadingInt64Value
358
// ParseLeadingHex64Value
359
//    A simple parser for 64-bit values. Returns the parsed value if a
360
//    valid integer is found; else returns deflt
361
//    UInt64 and Int64 cannot handle decimal numbers with leading 0s.
362
// --------------------------------------------------------------------
363
0
uint64 ParseLeadingUInt64Value(const char* str, uint64 deflt) {
364
0
    char* error = nullptr;
365
0
    const uint64 value = strtou64(str, &error, 0);
366
0
    return (error == str) ? deflt : value;
367
0
}
368
369
0
int64 ParseLeadingInt64Value(const char* str, int64 deflt) {
370
0
    char* error = nullptr;
371
0
    const int64 value = strto64(str, &error, 0);
372
0
    return (error == str) ? deflt : value;
373
0
}
374
375
0
uint64 ParseLeadingHex64Value(const char* str, uint64 deflt) {
376
0
    char* error = nullptr;
377
0
    const uint64 value = strtou64(str, &error, 16);
378
0
    return (error == str) ? deflt : value;
379
0
}
380
381
// ----------------------------------------------------------------------
382
// ParseLeadingDec64Value
383
// ParseLeadingUDec64Value
384
//    A simple parser for [u]int64 values. Returns the parsed value
385
//    if a valid value is found; else returns deflt
386
//    The string passed in is treated as *10 based*.
387
//    This can handle strings with leading 0s.
388
// --------------------------------------------------------------------
389
390
0
int64 ParseLeadingDec64Value(const char* str, int64 deflt) {
391
0
    char* error = nullptr;
392
0
    const int64 value = strto64(str, &error, 10);
393
0
    return (error == str) ? deflt : value;
394
0
}
395
396
0
uint64 ParseLeadingUDec64Value(const char* str, uint64 deflt) {
397
0
    char* error = nullptr;
398
0
    const uint64 value = strtou64(str, &error, 10);
399
0
    return (error == str) ? deflt : value;
400
0
}
401
402
// ----------------------------------------------------------------------
403
// ParseLeadingDoubleValue()
404
//    A simple parser for double values. Returns the parsed value
405
//    if a valid value is found; else returns deflt
406
// --------------------------------------------------------------------
407
408
0
double ParseLeadingDoubleValue(const char* str, double deflt) {
409
0
    char* error = nullptr;
410
0
    errno = 0;
411
0
    const double value = strtod(str, &error);
412
0
    if (errno != 0 ||   // overflow/underflow happened
413
0
        error == str) { // no valid parse
414
0
        return deflt;
415
0
    } else {
416
0
        return value;
417
0
    }
418
0
}
419
420
// ----------------------------------------------------------------------
421
// ParseLeadingBoolValue()
422
//    A recognizer of boolean string values. Returns the parsed value
423
//    if a valid value is found; else returns deflt.  This skips leading
424
//    whitespace, is case insensitive, and recognizes these forms:
425
//    0/1, false/true, no/yes, n/y
426
// --------------------------------------------------------------------
427
0
bool ParseLeadingBoolValue(const char* str, bool deflt) {
428
0
    static const int kMaxLen = 5;
429
0
    char value[kMaxLen + 1];
430
    // Skip whitespace
431
0
    while (ascii_isspace(*str)) {
432
0
        ++str;
433
0
    }
434
0
    int len = 0;
435
0
    for (; len <= kMaxLen && ascii_isalnum(*str); ++str) value[len++] = ascii_tolower(*str);
436
0
    if (len == 0 || len > kMaxLen) return deflt;
437
0
    value[len] = '\0';
438
0
    switch (len) {
439
0
    case 1:
440
0
        if (value[0] == '0' || value[0] == 'n') return false;
441
0
        if (value[0] == '1' || value[0] == 'y') return true;
442
0
        break;
443
0
    case 2:
444
0
        if (!strcmp(value, "no")) return false;
445
0
        break;
446
0
    case 3:
447
0
        if (!strcmp(value, "yes")) return true;
448
0
        break;
449
0
    case 4:
450
0
        if (!strcmp(value, "true")) return true;
451
0
        break;
452
0
    case 5:
453
0
        if (!strcmp(value, "false")) return false;
454
0
        break;
455
0
    }
456
0
    return deflt;
457
0
}
458
459
// ----------------------------------------------------------------------
460
// Uint64ToString()
461
// FloatToString()
462
// IntToString()
463
//    Convert various types to their string representation, possibly padded
464
//    with spaces, using snprintf format specifiers.
465
// ----------------------------------------------------------------------
466
467
0
string Uint64ToString(uint64 fp) {
468
0
    char buf[17];
469
0
    snprintf(buf, sizeof(buf), "%016" PRIx64, fp);
470
0
    return string(buf);
471
0
}
472
namespace {
473
474
// Represents integer values of digits.
475
// Uses 36 to indicate an invalid character since we support
476
// bases up to 36.
477
static const int8 kAsciiToInt[256] = {
478
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, // 16 36s.
479
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
480
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  36, 36,
481
        36, 36, 36, 36, 36, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
482
        27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, 36, 10, 11, 12, 13, 14, 15, 16,
483
        17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36,
484
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
485
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
486
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
487
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
488
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
489
        36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36};
490
491
// Input format based on POSIX.1-2008 strtol
492
// http://pubs.opengroup.org/onlinepubs/9699919799/functions/strtol.html
493
template <typename IntType>
494
10
bool safe_int_internal(const char* start, const char* end, int base, IntType* value_p) {
495
    // Consume whitespace.
496
11
    while (start < end && ascii_isspace(start[0])) {
497
1
        ++start;
498
1
    }
499
10
    while (start < end && ascii_isspace(end[-1])) {
500
0
        --end;
501
0
    }
502
10
    if (start >= end) {
503
2
        return false;
504
2
    }
505
506
    // Consume sign.
507
8
    const bool negative = (start[0] == '-');
508
8
    if (negative || start[0] == '+') {
509
1
        ++start;
510
1
        if (start >= end) {
511
0
            return false;
512
0
        }
513
1
    }
514
515
    // Consume base-dependent prefix.
516
    //  base 0: "0x" -> base 16, "0" -> base 8, default -> base 10
517
    //  base 16: "0x" -> base 16
518
    // Also validate the base.
519
8
    if (base == 0) {
520
0
        if (end - start >= 2 && start[0] == '0' && (start[1] == 'x' || start[1] == 'X')) {
521
0
            base = 16;
522
0
            start += 2;
523
0
        } else if (end - start >= 1 && start[0] == '0') {
524
0
            base = 8;
525
0
            start += 1;
526
0
        } else {
527
0
            base = 10;
528
0
        }
529
8
    } else if (base == 16) {
530
0
        if (end - start >= 2 && start[0] == '0' && (start[1] == 'x' || start[1] == 'X')) {
531
0
            start += 2;
532
0
        }
533
8
    } else if (base >= 2 && base <= 36) {
534
        // okay
535
8
    } else {
536
0
        return false;
537
0
    }
538
539
    // Consume digits.
540
    //
541
    // The classic loop:
542
    //
543
    //   for each digit
544
    //     value = value * base + digit
545
    //   value *= sign
546
    //
547
    // The classic loop needs overflow checking.  It also fails on the most
548
    // negative integer, -2147483648 in 32-bit two's complement representation.
549
    //
550
    // My improved loop:
551
    //
552
    //  if (!negative)
553
    //    for each digit
554
    //      value = value * base
555
    //      value = value + digit
556
    //  else
557
    //    for each digit
558
    //      value = value * base
559
    //      value = value - digit
560
    //
561
    // Overflow checking becomes simple.
562
    //
563
    // I present the positive code first for easier reading.
564
8
    IntType value = 0;
565
8
    if (!negative) {
566
7
        const IntType vmax = std::numeric_limits<IntType>::max();
567
7
        assert(vmax > 0);
568
0
        assert(vmax >= base);
569
0
        const IntType vmax_over_base = vmax / base;
570
        // loop over digits
571
        // loop body is interleaved for perf, not readability
572
23
        for (; start < end; ++start) {
573
20
            unsigned char c = static_cast<unsigned char>(start[0]);
574
20
            int digit = kAsciiToInt[c];
575
20
            if (value > vmax_over_base) return false;
576
20
            value *= base;
577
20
            if (digit >= base) return false;
578
17
            if (value > vmax - digit) return false;
579
16
            value += digit;
580
16
        }
581
7
    } else {
582
1
        const IntType vmin = std::numeric_limits<IntType>::min();
583
1
        assert(vmin < 0);
584
0
        assert(vmin <= 0 - base);
585
0
        IntType vmin_over_base = vmin / base;
586
        // 2003 c++ standard [expr.mul]
587
        // "... the sign of the remainder is implementation-defined."
588
        // Although (vmin/base)*base + vmin%base is always vmin.
589
        // 2011 c++ standard tightens the spec but we cannot rely on it.
590
1
        if (vmin % base > 0) {
591
0
            vmin_over_base += 1;
592
0
        }
593
        // loop over digits
594
        // loop body is interleaved for perf, not readability
595
2
        for (; start < end; ++start) {
596
1
            unsigned char c = static_cast<unsigned char>(start[0]);
597
1
            int digit = kAsciiToInt[c];
598
1
            if (value < vmin_over_base) return false;
599
1
            value *= base;
600
1
            if (digit >= base) return false;
601
1
            if (value < vmin + digit) return false;
602
1
            value -= digit;
603
1
        }
604
1
    }
605
606
    // Store output.
607
4
    *value_p = value;
608
4
    return true;
609
8
}
numbers.cc:_ZN12_GLOBAL__N_117safe_int_internalIiEEbPKcS2_iPT_
Line
Count
Source
494
3
bool safe_int_internal(const char* start, const char* end, int base, IntType* value_p) {
495
    // Consume whitespace.
496
3
    while (start < end && ascii_isspace(start[0])) {
497
0
        ++start;
498
0
    }
499
3
    while (start < end && ascii_isspace(end[-1])) {
500
0
        --end;
501
0
    }
502
3
    if (start >= end) {
503
0
        return false;
504
0
    }
505
506
    // Consume sign.
507
3
    const bool negative = (start[0] == '-');
508
3
    if (negative || start[0] == '+') {
509
0
        ++start;
510
0
        if (start >= end) {
511
0
            return false;
512
0
        }
513
0
    }
514
515
    // Consume base-dependent prefix.
516
    //  base 0: "0x" -> base 16, "0" -> base 8, default -> base 10
517
    //  base 16: "0x" -> base 16
518
    // Also validate the base.
519
3
    if (base == 0) {
520
0
        if (end - start >= 2 && start[0] == '0' && (start[1] == 'x' || start[1] == 'X')) {
521
0
            base = 16;
522
0
            start += 2;
523
0
        } else if (end - start >= 1 && start[0] == '0') {
524
0
            base = 8;
525
0
            start += 1;
526
0
        } else {
527
0
            base = 10;
528
0
        }
529
3
    } else if (base == 16) {
530
0
        if (end - start >= 2 && start[0] == '0' && (start[1] == 'x' || start[1] == 'X')) {
531
0
            start += 2;
532
0
        }
533
3
    } else if (base >= 2 && base <= 36) {
534
        // okay
535
3
    } else {
536
0
        return false;
537
0
    }
538
539
    // Consume digits.
540
    //
541
    // The classic loop:
542
    //
543
    //   for each digit
544
    //     value = value * base + digit
545
    //   value *= sign
546
    //
547
    // The classic loop needs overflow checking.  It also fails on the most
548
    // negative integer, -2147483648 in 32-bit two's complement representation.
549
    //
550
    // My improved loop:
551
    //
552
    //  if (!negative)
553
    //    for each digit
554
    //      value = value * base
555
    //      value = value + digit
556
    //  else
557
    //    for each digit
558
    //      value = value * base
559
    //      value = value - digit
560
    //
561
    // Overflow checking becomes simple.
562
    //
563
    // I present the positive code first for easier reading.
564
3
    IntType value = 0;
565
3
    if (!negative) {
566
3
        const IntType vmax = std::numeric_limits<IntType>::max();
567
3
        assert(vmax > 0);
568
0
        assert(vmax >= base);
569
0
        const IntType vmax_over_base = vmax / base;
570
        // loop over digits
571
        // loop body is interleaved for perf, not readability
572
14
        for (; start < end; ++start) {
573
13
            unsigned char c = static_cast<unsigned char>(start[0]);
574
13
            int digit = kAsciiToInt[c];
575
13
            if (value > vmax_over_base) return false;
576
13
            value *= base;
577
13
            if (digit >= base) return false;
578
12
            if (value > vmax - digit) return false;
579
11
            value += digit;
580
11
        }
581
3
    } else {
582
0
        const IntType vmin = std::numeric_limits<IntType>::min();
583
0
        assert(vmin < 0);
584
0
        assert(vmin <= 0 - base);
585
0
        IntType vmin_over_base = vmin / base;
586
        // 2003 c++ standard [expr.mul]
587
        // "... the sign of the remainder is implementation-defined."
588
        // Although (vmin/base)*base + vmin%base is always vmin.
589
        // 2011 c++ standard tightens the spec but we cannot rely on it.
590
0
        if (vmin % base > 0) {
591
0
            vmin_over_base += 1;
592
0
        }
593
        // loop over digits
594
        // loop body is interleaved for perf, not readability
595
0
        for (; start < end; ++start) {
596
0
            unsigned char c = static_cast<unsigned char>(start[0]);
597
0
            int digit = kAsciiToInt[c];
598
0
            if (value < vmin_over_base) return false;
599
0
            value *= base;
600
0
            if (digit >= base) return false;
601
0
            if (value < vmin + digit) return false;
602
0
            value -= digit;
603
0
        }
604
0
    }
605
606
    // Store output.
607
1
    *value_p = value;
608
1
    return true;
609
3
}
numbers.cc:_ZN12_GLOBAL__N_117safe_int_internalIlEEbPKcS2_iPT_
Line
Count
Source
494
7
bool safe_int_internal(const char* start, const char* end, int base, IntType* value_p) {
495
    // Consume whitespace.
496
8
    while (start < end && ascii_isspace(start[0])) {
497
1
        ++start;
498
1
    }
499
7
    while (start < end && ascii_isspace(end[-1])) {
500
0
        --end;
501
0
    }
502
7
    if (start >= end) {
503
2
        return false;
504
2
    }
505
506
    // Consume sign.
507
5
    const bool negative = (start[0] == '-');
508
5
    if (negative || start[0] == '+') {
509
1
        ++start;
510
1
        if (start >= end) {
511
0
            return false;
512
0
        }
513
1
    }
514
515
    // Consume base-dependent prefix.
516
    //  base 0: "0x" -> base 16, "0" -> base 8, default -> base 10
517
    //  base 16: "0x" -> base 16
518
    // Also validate the base.
519
5
    if (base == 0) {
520
0
        if (end - start >= 2 && start[0] == '0' && (start[1] == 'x' || start[1] == 'X')) {
521
0
            base = 16;
522
0
            start += 2;
523
0
        } else if (end - start >= 1 && start[0] == '0') {
524
0
            base = 8;
525
0
            start += 1;
526
0
        } else {
527
0
            base = 10;
528
0
        }
529
5
    } else if (base == 16) {
530
0
        if (end - start >= 2 && start[0] == '0' && (start[1] == 'x' || start[1] == 'X')) {
531
0
            start += 2;
532
0
        }
533
5
    } else if (base >= 2 && base <= 36) {
534
        // okay
535
5
    } else {
536
0
        return false;
537
0
    }
538
539
    // Consume digits.
540
    //
541
    // The classic loop:
542
    //
543
    //   for each digit
544
    //     value = value * base + digit
545
    //   value *= sign
546
    //
547
    // The classic loop needs overflow checking.  It also fails on the most
548
    // negative integer, -2147483648 in 32-bit two's complement representation.
549
    //
550
    // My improved loop:
551
    //
552
    //  if (!negative)
553
    //    for each digit
554
    //      value = value * base
555
    //      value = value + digit
556
    //  else
557
    //    for each digit
558
    //      value = value * base
559
    //      value = value - digit
560
    //
561
    // Overflow checking becomes simple.
562
    //
563
    // I present the positive code first for easier reading.
564
5
    IntType value = 0;
565
5
    if (!negative) {
566
4
        const IntType vmax = std::numeric_limits<IntType>::max();
567
4
        assert(vmax > 0);
568
0
        assert(vmax >= base);
569
0
        const IntType vmax_over_base = vmax / base;
570
        // loop over digits
571
        // loop body is interleaved for perf, not readability
572
9
        for (; start < end; ++start) {
573
7
            unsigned char c = static_cast<unsigned char>(start[0]);
574
7
            int digit = kAsciiToInt[c];
575
7
            if (value > vmax_over_base) return false;
576
7
            value *= base;
577
7
            if (digit >= base) return false;
578
5
            if (value > vmax - digit) return false;
579
5
            value += digit;
580
5
        }
581
4
    } else {
582
1
        const IntType vmin = std::numeric_limits<IntType>::min();
583
1
        assert(vmin < 0);
584
0
        assert(vmin <= 0 - base);
585
0
        IntType vmin_over_base = vmin / base;
586
        // 2003 c++ standard [expr.mul]
587
        // "... the sign of the remainder is implementation-defined."
588
        // Although (vmin/base)*base + vmin%base is always vmin.
589
        // 2011 c++ standard tightens the spec but we cannot rely on it.
590
1
        if (vmin % base > 0) {
591
0
            vmin_over_base += 1;
592
0
        }
593
        // loop over digits
594
        // loop body is interleaved for perf, not readability
595
2
        for (; start < end; ++start) {
596
1
            unsigned char c = static_cast<unsigned char>(start[0]);
597
1
            int digit = kAsciiToInt[c];
598
1
            if (value < vmin_over_base) return false;
599
1
            value *= base;
600
1
            if (digit >= base) return false;
601
1
            if (value < vmin + digit) return false;
602
1
            value -= digit;
603
1
        }
604
1
    }
605
606
    // Store output.
607
3
    *value_p = value;
608
3
    return true;
609
5
}
610
611
} // anonymous namespace
612
613
0
bool safe_strto32_base(const char* startptr, const int buffer_size, int32* v, int base) {
614
0
    return safe_int_internal<int32>(startptr, startptr + buffer_size, base, v);
615
0
}
616
617
0
bool safe_strto64_base(const char* startptr, const int buffer_size, int64* v, int base) {
618
0
    return safe_int_internal<int64>(startptr, startptr + buffer_size, base, v);
619
0
}
620
621
3
bool safe_strto32(const char* startptr, const int buffer_size, int32* value) {
622
3
    return safe_int_internal<int32>(startptr, startptr + buffer_size, 10, value);
623
3
}
624
625
7
bool safe_strto64(const char* startptr, const int buffer_size, int64* value) {
626
7
    return safe_int_internal<int64>(startptr, startptr + buffer_size, 10, value);
627
7
}
628
629
0
bool safe_strto32_base(const char* str, int32* value, int base) {
630
0
    char* endptr;
631
0
    errno = 0; // errno only gets set on errors
632
0
    *value = strto32(str, &endptr, base);
633
0
    if (endptr != str) {
634
0
        while (ascii_isspace(*endptr)) ++endptr;
635
0
    }
636
0
    return *str != '\0' && *endptr == '\0' && errno == 0;
637
0
}
638
639
0
bool safe_strto64_base(const char* str, int64* value, int base) {
640
0
    char* endptr;
641
0
    errno = 0; // errno only gets set on errors
642
0
    *value = strto64(str, &endptr, base);
643
0
    if (endptr != str) {
644
0
        while (ascii_isspace(*endptr)) ++endptr;
645
0
    }
646
0
    return *str != '\0' && *endptr == '\0' && errno == 0;
647
0
}
648
649
0
bool safe_strtou32_base(const char* str, uint32* value, int base) {
650
    // strtoul does not give any errors on negative numbers, so we have to
651
    // search the string for '-' manually.
652
0
    while (ascii_isspace(*str)) ++str;
653
0
    if (*str == '-') return false;
654
655
0
    char* endptr;
656
0
    errno = 0; // errno only gets set on errors
657
0
    *value = strtou32(str, &endptr, base);
658
0
    if (endptr != str) {
659
0
        while (ascii_isspace(*endptr)) ++endptr;
660
0
    }
661
0
    return *str != '\0' && *endptr == '\0' && errno == 0;
662
0
}
663
664
0
bool safe_strtou64_base(const char* str, uint64* value, int base) {
665
    // strtou64 does not give any errors on negative numbers, so we have to
666
    // search the string for '-' manually.
667
0
    while (ascii_isspace(*str)) ++str;
668
0
    if (*str == '-') return false;
669
670
0
    char* endptr;
671
0
    errno = 0; // errno only gets set on errors
672
0
    *value = strtou64(str, &endptr, base);
673
0
    if (endptr != str) {
674
0
        while (ascii_isspace(*endptr)) ++endptr;
675
0
    }
676
0
    return *str != '\0' && *endptr == '\0' && errno == 0;
677
0
}
678
679
// ----------------------------------------------------------------------
680
// u64tostr_base36()
681
//    Converts unsigned number to string representation in base-36.
682
// --------------------------------------------------------------------
683
0
size_t u64tostr_base36(uint64 number, size_t buf_size, char* buffer) {
684
0
    CHECK_GT(buf_size, 0);
685
0
    CHECK(buffer);
686
0
    static const char kAlphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";
687
688
0
    buffer[buf_size - 1] = '\0';
689
0
    size_t result_size = 1;
690
691
0
    do {
692
0
        if (buf_size == result_size) { // Ran out of space.
693
0
            return 0;
694
0
        }
695
0
        int remainder = number % 36;
696
0
        number /= 36;
697
0
        buffer[buf_size - result_size - 1] = kAlphabet[remainder];
698
0
        result_size++;
699
0
    } while (number);
700
701
0
    memmove(buffer, buffer + buf_size - result_size, result_size);
702
703
0
    return result_size - 1;
704
0
}
705
706
// Generate functions that wrap safe_strtoXXX_base.
707
#define GEN_SAFE_STRTO(name, type)                                                  \
708
0
    bool name##_base(const string& str, type* value, int base) {                    \
709
0
        return name##_base(str.c_str(), value, base);                               \
710
0
    }                                                                               \
Unexecuted instantiation: _Z17safe_strto32_baseRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPii
Unexecuted instantiation: _Z18safe_strtou32_baseRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPji
Unexecuted instantiation: _Z17safe_strto64_baseRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPli
Unexecuted instantiation: _Z18safe_strtou64_baseRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPmi
711
0
    bool name(const char* str, type* value) { return name##_base(str, value, 10); } \
Unexecuted instantiation: _Z12safe_strto32PKcPi
Unexecuted instantiation: _Z13safe_strtou32PKcPj
Unexecuted instantiation: _Z12safe_strto64PKcPl
Unexecuted instantiation: _Z13safe_strtou64PKcPm
712
0
    bool name(const string& str, type* value) { return name##_base(str.c_str(), value, 10); }
Unexecuted instantiation: _Z12safe_strto32RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPi
Unexecuted instantiation: _Z13safe_strtou32RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPj
Unexecuted instantiation: _Z12safe_strto64RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPl
Unexecuted instantiation: _Z13safe_strtou64RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPm
713
GEN_SAFE_STRTO(safe_strto32, int32);
714
GEN_SAFE_STRTO(safe_strtou32, uint32);
715
GEN_SAFE_STRTO(safe_strto64, int64);
716
GEN_SAFE_STRTO(safe_strtou64, uint64);
717
#undef GEN_SAFE_STRTO
718
719
18.0M
bool safe_strtof(const char* str, float* value) {
720
18.0M
    char* endptr;
721
#ifdef _MSC_VER // has no strtof()
722
    *value = strtod(str, &endptr);
723
#else
724
18.0M
    *value = strtof(str, &endptr);
725
18.0M
#endif
726
18.0M
    if (endptr != str) {
727
18.0M
        while (ascii_isspace(*endptr)) ++endptr;
728
18.0M
    }
729
    // Ignore range errors from strtod/strtof.
730
    // The values it returns on underflow and
731
    // overflow are the right fallback in a
732
    // robust setting.
733
18.0M
    return *str != '\0' && *endptr == '\0';
734
18.0M
}
735
736
0
bool safe_strtod(const char* str, double* value) {
737
0
    char* endptr;
738
0
    *value = strtod(str, &endptr);
739
0
    if (endptr != str) {
740
0
        while (ascii_isspace(*endptr)) ++endptr;
741
0
    }
742
    // Ignore range errors from strtod.  The values it
743
    // returns on underflow and overflow are the right
744
    // fallback in a robust setting.
745
0
    return *str != '\0' && *endptr == '\0';
746
0
}
747
748
11
bool safe_strtof(const string& str, float* value) {
749
11
    return safe_strtof(str.c_str(), value);
750
11
}
751
752
0
bool safe_strtod(const string& str, double* value) {
753
0
    return safe_strtod(str.c_str(), value);
754
0
}
755
756
0
uint64 atoi_kmgt(const char* s) {
757
0
    char* endptr;
758
0
    uint64 n = strtou64(s, &endptr, 10);
759
0
    uint64 scale = 1;
760
0
    char c = *endptr;
761
0
    if (c != '\0') {
762
0
        c = ascii_toupper(c);
763
0
        switch (c) {
764
0
        case 'K':
765
0
            scale = GG_ULONGLONG(1) << 10;
766
0
            break;
767
0
        case 'M':
768
0
            scale = GG_ULONGLONG(1) << 20;
769
0
            break;
770
0
        case 'G':
771
0
            scale = GG_ULONGLONG(1) << 30;
772
0
            break;
773
0
        case 'T':
774
0
            scale = GG_ULONGLONG(1) << 40;
775
0
            break;
776
0
        default:
777
0
            throw doris::Exception(doris::Status::FatalError(
778
0
                    "Invalid mnemonic: `{}'; should be one of `K', `M', `G', and `T'.", c));
779
0
        }
780
0
    }
781
0
    return n * scale;
782
0
}
783
784
// ----------------------------------------------------------------------
785
// FastIntToBuffer()
786
// FastInt64ToBuffer()
787
// FastHexToBuffer()
788
// FastHex64ToBuffer()
789
// FastHex32ToBuffer()
790
// FastTimeToBuffer()
791
//    These are intended for speed.  FastHexToBuffer() assumes the
792
//    integer is non-negative.  FastHexToBuffer() puts output in
793
//    hex rather than decimal.  FastTimeToBuffer() puts the output
794
//    into RFC822 format.  If time is 0, uses the current time.
795
//
796
//    FastHex64ToBuffer() puts a 64-bit unsigned value in hex-format,
797
//    padded to exactly 16 bytes (plus one byte for '\0')
798
//
799
//    FastHex32ToBuffer() puts a 32-bit unsigned value in hex-format,
800
//    padded to exactly 8 bytes (plus one byte for '\0')
801
//
802
//       All functions take the output buffer as an arg.  FastInt()
803
//    uses at most 22 bytes, FastTime() uses exactly 30 bytes.
804
//    They all return a pointer to the beginning of the output,
805
//    which may not be the beginning of the input buffer.  (Though
806
//    for FastTimeToBuffer(), we guarantee that it is.)
807
// ----------------------------------------------------------------------
808
809
0
char* FastInt64ToBuffer(int64 i, char* buffer) {
810
0
    FastInt64ToBufferLeft(i, buffer);
811
0
    return buffer;
812
0
}
813
814
0
char* FastInt32ToBuffer(int32 i, char* buffer) {
815
0
    FastInt32ToBufferLeft(i, buffer);
816
0
    return buffer;
817
0
}
818
819
0
char* FastHexToBuffer(int i, char* buffer) {
820
0
    CHECK_GE(i, 0) << "FastHexToBuffer() wants non-negative integers, not " << i;
821
822
0
    static const char* hexdigits = "0123456789abcdef";
823
0
    char* p = buffer + 21;
824
0
    *p-- = '\0';
825
0
    do {
826
0
        *p-- = hexdigits[i & 15]; // mod by 16
827
0
        i >>= 4;                  // divide by 16
828
0
    } while (i > 0);
829
0
    return p + 1;
830
0
}
831
832
0
char* InternalFastHexToBuffer(uint64 value, char* buffer, int num_byte) {
833
0
    static const char* hexdigits = "0123456789abcdef";
834
0
    buffer[num_byte] = '\0';
835
0
    for (int i = num_byte - 1; i >= 0; i--) {
836
0
        buffer[i] = hexdigits[value & 0xf];
837
0
        value >>= 4;
838
0
    }
839
0
    return buffer;
840
0
}
841
842
0
char* FastHex64ToBuffer(uint64 value, char* buffer) {
843
0
    return InternalFastHexToBuffer(value, buffer, 16);
844
0
}
845
846
0
char* FastHex32ToBuffer(uint32 value, char* buffer) {
847
0
    return InternalFastHexToBuffer(value, buffer, 8);
848
0
}
849
850
// TODO(user): revisit the two_ASCII_digits optimization.
851
//
852
// Several converters use this table to reduce
853
// division and modulo operations.
854
extern const char two_ASCII_digits[100][2]; // from strutil.cc
855
856
// ----------------------------------------------------------------------
857
// FastInt32ToBufferLeft()
858
// FastUInt32ToBufferLeft()
859
// FastInt64ToBufferLeft()
860
// FastUInt64ToBufferLeft()
861
//
862
// Like the Fast*ToBuffer() functions above, these are intended for speed.
863
// Unlike the Fast*ToBuffer() functions, however, these functions write
864
// their output to the beginning of the buffer (hence the name, as the
865
// output is left-aligned).  The caller is responsible for ensuring that
866
// the buffer has enough space to hold the output.
867
//
868
// Returns a pointer to the end of the string (i.e. the null character
869
// terminating the string).
870
// ----------------------------------------------------------------------
871
872
348k
char* FastUInt32ToBufferLeft(uint32 u, char* buffer) {
873
348k
    uint digits;
874
348k
    const char* ASCII_digits = nullptr;
875
    // The idea of this implementation is to trim the number of divides to as few
876
    // as possible by using multiplication and subtraction rather than mod (%),
877
    // and by outputting two digits at a time rather than one.
878
    // The huge-number case is first, in the hopes that the compiler will output
879
    // that case in one branch-free block of code, and only output conditional
880
    // branches into it from below.
881
348k
    if (u >= 1000000000) {      // >= 1,000,000,000
882
0
        digits = u / 100000000; // 100,000,000
883
0
        ASCII_digits = two_ASCII_digits[digits];
884
0
        buffer[0] = ASCII_digits[0];
885
0
        buffer[1] = ASCII_digits[1];
886
0
        buffer += 2;
887
0
    sublt100_000_000:
888
0
        u -= digits * 100000000; // 100,000,000
889
0
    lt100_000_000:
890
0
        digits = u / 1000000; // 1,000,000
891
0
        ASCII_digits = two_ASCII_digits[digits];
892
0
        buffer[0] = ASCII_digits[0];
893
0
        buffer[1] = ASCII_digits[1];
894
0
        buffer += 2;
895
0
    sublt1_000_000:
896
0
        u -= digits * 1000000; // 1,000,000
897
0
    lt1_000_000:
898
0
        digits = u / 10000; // 10,000
899
0
        ASCII_digits = two_ASCII_digits[digits];
900
0
        buffer[0] = ASCII_digits[0];
901
0
        buffer[1] = ASCII_digits[1];
902
0
        buffer += 2;
903
692
    sublt10_000:
904
692
        u -= digits * 10000; // 10,000
905
2.85k
    lt10_000:
906
2.85k
        digits = u / 100;
907
2.85k
        ASCII_digits = two_ASCII_digits[digits];
908
2.85k
        buffer[0] = ASCII_digits[0];
909
2.85k
        buffer[1] = ASCII_digits[1];
910
2.85k
        buffer += 2;
911
22.6k
    sublt100:
912
22.6k
        u -= digits * 100;
913
327k
    lt100:
914
327k
        digits = u;
915
327k
        ASCII_digits = two_ASCII_digits[digits];
916
327k
        buffer[0] = ASCII_digits[0];
917
327k
        buffer[1] = ASCII_digits[1];
918
327k
        buffer += 2;
919
348k
    done:
920
348k
        *buffer = 0;
921
348k
        return buffer;
922
327k
    }
923
924
348k
    if (u < 100) {
925
325k
        digits = u;
926
325k
        if (u >= 10) goto lt100;
927
20.7k
        *buffer++ = '0' + digits;
928
20.7k
        goto done;
929
325k
    }
930
22.6k
    if (u < 10000) { // 10,000
931
21.9k
        if (u >= 1000) goto lt10_000;
932
19.7k
        digits = u / 100;
933
19.7k
        *buffer++ = '0' + digits;
934
19.7k
        goto sublt100;
935
21.9k
    }
936
693
    if (u < 1000000) { // 1,000,000
937
692
        if (u >= 100000) goto lt1_000_000;
938
692
        digits = u / 10000; //    10,000
939
692
        *buffer++ = '0' + digits;
940
692
        goto sublt10_000;
941
692
    }
942
1
    if (u < 100000000) { // 100,000,000
943
0
        if (u >= 10000000) goto lt100_000_000;
944
0
        digits = u / 1000000; //   1,000,000
945
0
        *buffer++ = '0' + digits;
946
0
        goto sublt1_000_000;
947
0
    }
948
    // we already know that u < 1,000,000,000
949
1
    digits = u / 100000000; // 100,000,000
950
1
    *buffer++ = '0' + digits;
951
1
    goto sublt100_000_000;
952
1
}
953
954
345k
char* FastInt32ToBufferLeft(int32 i, char* buffer) {
955
345k
    uint32 u = i;
956
345k
    if (i < 0) {
957
0
        *buffer++ = '-';
958
        // We need to do the negation in modular (i.e., "unsigned")
959
        // arithmetic; MSVC++ apprently warns for plain "-u", so
960
        // we write the equivalent expression "0 - u" instead.
961
0
        u = 0 - u;
962
0
    }
963
345k
    return FastUInt32ToBufferLeft(u, buffer);
964
345k
}
965
966
2.88k
char* FastUInt64ToBufferLeft(uint64 u64, char* buffer) {
967
2.88k
    uint digits;
968
2.88k
    const char* ASCII_digits = nullptr;
969
970
2.88k
    uint32 u = static_cast<uint32>(u64);
971
2.88k
    if (u == u64) return FastUInt32ToBufferLeft(u, buffer);
972
973
0
    uint64 top_11_digits = u64 / 1000000000;
974
0
    buffer = FastUInt64ToBufferLeft(top_11_digits, buffer);
975
0
    u = u64 - (top_11_digits * 1000000000);
976
977
0
    digits = u / 10000000; // 10,000,000
978
0
    DCHECK_LT(digits, 100);
979
0
    ASCII_digits = two_ASCII_digits[digits];
980
0
    buffer[0] = ASCII_digits[0];
981
0
    buffer[1] = ASCII_digits[1];
982
0
    buffer += 2;
983
0
    u -= digits * 10000000; // 10,000,000
984
0
    digits = u / 100000;    // 100,000
985
0
    ASCII_digits = two_ASCII_digits[digits];
986
0
    buffer[0] = ASCII_digits[0];
987
0
    buffer[1] = ASCII_digits[1];
988
0
    buffer += 2;
989
0
    u -= digits * 100000; // 100,000
990
0
    digits = u / 1000;    // 1,000
991
0
    ASCII_digits = two_ASCII_digits[digits];
992
0
    buffer[0] = ASCII_digits[0];
993
0
    buffer[1] = ASCII_digits[1];
994
0
    buffer += 2;
995
0
    u -= digits * 1000; // 1,000
996
0
    digits = u / 10;
997
0
    ASCII_digits = two_ASCII_digits[digits];
998
0
    buffer[0] = ASCII_digits[0];
999
0
    buffer[1] = ASCII_digits[1];
1000
0
    buffer += 2;
1001
0
    u -= digits * 10;
1002
0
    digits = u;
1003
0
    *buffer++ = '0' + digits;
1004
0
    *buffer = 0;
1005
0
    return buffer;
1006
2.88k
}
1007
1008
2.87k
char* FastInt64ToBufferLeft(int64 i, char* buffer) {
1009
2.87k
    uint64 u = i;
1010
2.87k
    if (i < 0) {
1011
0
        *buffer++ = '-';
1012
0
        u = 0 - u;
1013
0
    }
1014
2.87k
    return FastUInt64ToBufferLeft(u, buffer);
1015
2.87k
}
1016
1017
0
int HexDigitsPrefix(const char* buf, int num_digits) {
1018
0
    for (int i = 0; i < num_digits; i++)
1019
0
        if (!ascii_isxdigit(buf[i]))
1020
0
            return 0; // This also detects end of string as '\0' is not xdigit.
1021
0
    return 1;
1022
0
}
1023
1024
// ----------------------------------------------------------------------
1025
// AutoDigitStrCmp
1026
// AutoDigitLessThan
1027
// StrictAutoDigitLessThan
1028
// autodigit_less
1029
// autodigit_greater
1030
// strict_autodigit_less
1031
// strict_autodigit_greater
1032
//    These are like less<string> and greater<string>, except when a
1033
//    run of digits is encountered at corresponding points in the two
1034
//    arguments.  Such digit strings are compared numerically instead
1035
//    of lexicographically.  Therefore if you sort by
1036
//    "autodigit_less", some machine names might get sorted as:
1037
//        exaf1
1038
//        exaf2
1039
//        exaf10
1040
//    When using "strict" comparison (AutoDigitStrCmp with the strict flag
1041
//    set to true, or the strict version of the other functions),
1042
//    strings that represent equal numbers will not be considered equal if
1043
//    the string representations are not identical.  That is, "01" < "1" in
1044
//    strict mode, but "01" == "1" otherwise.
1045
// ----------------------------------------------------------------------
1046
1047
0
int AutoDigitStrCmp(const char* a, int alen, const char* b, int blen, bool strict) {
1048
0
    int aindex = 0;
1049
0
    int bindex = 0;
1050
0
    while ((aindex < alen) && (bindex < blen)) {
1051
0
        if (isdigit(a[aindex]) && isdigit(b[bindex])) {
1052
            // Compare runs of digits.  Instead of extracting numbers, we
1053
            // just skip leading zeroes, and then get the run-lengths.  This
1054
            // allows us to handle arbitrary precision numbers.  We remember
1055
            // how many zeroes we found so that we can differentiate between
1056
            // "1" and "01" in strict mode.
1057
1058
            // Skip leading zeroes, but remember how many we found
1059
0
            int azeroes = aindex;
1060
0
            int bzeroes = bindex;
1061
0
            while ((aindex < alen) && (a[aindex] == '0')) aindex++;
1062
0
            while ((bindex < blen) && (b[bindex] == '0')) bindex++;
1063
0
            azeroes = aindex - azeroes;
1064
0
            bzeroes = bindex - bzeroes;
1065
1066
            // Count digit lengths
1067
0
            int astart = aindex;
1068
0
            int bstart = bindex;
1069
0
            while ((aindex < alen) && isdigit(a[aindex])) aindex++;
1070
0
            while ((bindex < blen) && isdigit(b[bindex])) bindex++;
1071
0
            if (aindex - astart < bindex - bstart) {
1072
                // a has shorter run of digits: so smaller
1073
0
                return -1;
1074
0
            } else if (aindex - astart > bindex - bstart) {
1075
                // a has longer run of digits: so larger
1076
0
                return 1;
1077
0
            } else {
1078
                // Same lengths, so compare digit by digit
1079
0
                for (int i = 0; i < aindex - astart; i++) {
1080
0
                    if (a[astart + i] < b[bstart + i]) {
1081
0
                        return -1;
1082
0
                    } else if (a[astart + i] > b[bstart + i]) {
1083
0
                        return 1;
1084
0
                    }
1085
0
                }
1086
                // Equal: did one have more leading zeroes?
1087
0
                if (strict && azeroes != bzeroes) {
1088
0
                    if (azeroes > bzeroes) {
1089
                        // a has more leading zeroes: a < b
1090
0
                        return -1;
1091
0
                    } else {
1092
                        // b has more leading zeroes: a > b
1093
0
                        return 1;
1094
0
                    }
1095
0
                }
1096
                // Equal: so continue scanning
1097
0
            }
1098
0
        } else if (a[aindex] < b[bindex]) {
1099
0
            return -1;
1100
0
        } else if (a[aindex] > b[bindex]) {
1101
0
            return 1;
1102
0
        } else {
1103
0
            aindex++;
1104
0
            bindex++;
1105
0
        }
1106
0
    }
1107
1108
0
    if (aindex < alen) {
1109
        // b is prefix of a
1110
0
        return 1;
1111
0
    } else if (bindex < blen) {
1112
        // a is prefix of b
1113
0
        return -1;
1114
0
    } else {
1115
        // a is equal to b
1116
0
        return 0;
1117
0
    }
1118
0
}
1119
1120
0
bool AutoDigitLessThan(const char* a, int alen, const char* b, int blen) {
1121
0
    return AutoDigitStrCmp(a, alen, b, blen, false) < 0;
1122
0
}
1123
1124
0
bool StrictAutoDigitLessThan(const char* a, int alen, const char* b, int blen) {
1125
0
    return AutoDigitStrCmp(a, alen, b, blen, true) < 0;
1126
0
}
1127
1128
// ----------------------------------------------------------------------
1129
// SimpleDtoa()
1130
// SimpleFtoa()
1131
// DoubleToBuffer()
1132
// FloatToBuffer()
1133
//    We want to print the value without losing precision, but we also do
1134
//    not want to print more digits than necessary.  This turns out to be
1135
//    trickier than it sounds.  Numbers like 0.2 cannot be represented
1136
//    exactly in binary.  If we print 0.2 with a very large precision,
1137
//    e.g. "%.50g", we get "0.2000000000000000111022302462515654042363167".
1138
//    On the other hand, if we set the precision too low, we lose
1139
//    significant digits when printing numbers that actually need them.
1140
//    It turns out there is no precision value that does the right thing
1141
//    for all numbers.
1142
//
1143
//    Our strategy is to first try printing with a precision that is never
1144
//    over-precise, then parse the result with strtod() to see if it
1145
//    matches.  If not, we print again with a precision that will always
1146
//    give a precise result, but may use more digits than necessary.
1147
//
1148
//    An arguably better strategy would be to use the algorithm described
1149
//    in "How to Print Floating-Point Numbers Accurately" by Steele &
1150
//    White, e.g. as implemented by David M. Gay's dtoa().  It turns out,
1151
//    however, that the following implementation is about as fast as
1152
//    DMG's code.  Furthermore, DMG's code locks mutexes, which means it
1153
//    will not scale well on multi-core machines.  DMG's code is slightly
1154
//    more accurate (in that it will never use more digits than
1155
//    necessary), but this is probably irrelevant for most users.
1156
//
1157
//    Rob Pike and Ken Thompson also have an implementation of dtoa() in
1158
//    third_party/fmt/fltfmt.cc.  Their implementation is similar to this
1159
//    one in that it makes guesses and then uses strtod() to check them.
1160
//    Their implementation is faster because they use their own code to
1161
//    generate the digits in the first place rather than use snprintf(),
1162
//    thus avoiding format string parsing overhead.  However, this makes
1163
//    it considerably more complicated than the following implementation,
1164
//    and it is embedded in a larger library.  If speed turns out to be
1165
//    an issue, we could re-implement this in terms of their
1166
//    implementation.
1167
// ----------------------------------------------------------------------
1168
1169
0
string SimpleDtoa(double value) {
1170
0
    char buffer[kDoubleToBufferSize];
1171
0
    return DoubleToBuffer(value, buffer);
1172
0
}
1173
1174
0
string SimpleFtoa(float value) {
1175
0
    char buffer[kFloatToBufferSize];
1176
0
    return FloatToBuffer(value, buffer);
1177
0
}
1178
1179
0
char* DoubleToBuffer(double value, char* buffer) {
1180
    // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all
1181
    // platforms these days.  Just in case some system exists where DBL_DIG
1182
    // is significantly larger -- and risks overflowing our buffer -- we have
1183
    // this assert.
1184
0
    COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big);
1185
1186
0
    int snprintf_result = snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG, value);
1187
1188
    // The snprintf should never overflow because the buffer is significantly
1189
    // larger than the precision we asked for.
1190
0
    DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
1191
1192
0
    if (strtod(buffer, nullptr) != value) {
1193
0
        snprintf_result = snprintf(buffer, kDoubleToBufferSize, "%.*g", DBL_DIG + 2, value);
1194
1195
        // Should never overflow; see above.
1196
0
        DCHECK(snprintf_result > 0 && snprintf_result < kDoubleToBufferSize);
1197
0
    }
1198
0
    return buffer;
1199
0
}
1200
1201
0
char* FloatToBuffer(float value, char* buffer) {
1202
    // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all
1203
    // platforms these days.  Just in case some system exists where FLT_DIG
1204
    // is significantly larger -- and risks overflowing our buffer -- we have
1205
    // this assert.
1206
0
    COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big);
1207
1208
0
    int snprintf_result = snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG, value);
1209
1210
    // The snprintf should never overflow because the buffer is significantly
1211
    // larger than the precision we asked for.
1212
0
    DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
1213
1214
0
    float parsed_value;
1215
0
    if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
1216
0
        snprintf_result = snprintf(buffer, kFloatToBufferSize, "%.*g", FLT_DIG + 2, value);
1217
1218
        // Should never overflow; see above.
1219
0
        DCHECK(snprintf_result > 0 && snprintf_result < kFloatToBufferSize);
1220
0
    }
1221
0
    return buffer;
1222
0
}
1223
1224
11
int DoubleToBuffer(double value, int width, char* buffer) {
1225
    // DBL_DIG is 15 for IEEE-754 doubles, which are used on almost all
1226
    // platforms these days.  Just in case some system exists where DBL_DIG
1227
    // is significantly larger -- and risks overflowing our buffer -- we have
1228
    // this assert.
1229
11
    COMPILE_ASSERT(DBL_DIG < 20, DBL_DIG_is_too_big);
1230
1231
11
    int snprintf_result = snprintf(buffer, width, "%.*g", DBL_DIG, value);
1232
1233
    // The snprintf should never overflow because the buffer is significantly
1234
    // larger than the precision we asked for.
1235
11
    DCHECK(snprintf_result > 0 && snprintf_result < width);
1236
1237
11
    if (strtod(buffer, nullptr) != value) {
1238
3
        snprintf_result = snprintf(buffer, width, "%.*g", DBL_DIG + 2, value);
1239
1240
        // Should never overflow; see above.
1241
3
        DCHECK(snprintf_result > 0 && snprintf_result < width);
1242
3
    }
1243
1244
11
    return snprintf_result;
1245
11
}
1246
1247
18.0M
int FloatToBuffer(float value, int width, char* buffer) {
1248
    // FLT_DIG is 6 for IEEE-754 floats, which are used on almost all
1249
    // platforms these days.  Just in case some system exists where FLT_DIG
1250
    // is significantly larger -- and risks overflowing our buffer -- we have
1251
    // this assert.
1252
18.0M
    COMPILE_ASSERT(FLT_DIG < 10, FLT_DIG_is_too_big);
1253
1254
18.0M
    int snprintf_result = snprintf(buffer, width, "%.*g", FLT_DIG, value);
1255
1256
    // The snprintf should never overflow because the buffer is significantly
1257
    // larger than the precision we asked for.
1258
18.0M
    DCHECK(snprintf_result > 0 && snprintf_result < width);
1259
1260
18.0M
    float parsed_value;
1261
18.0M
    if (!safe_strtof(buffer, &parsed_value) || parsed_value != value) {
1262
8
        snprintf_result = snprintf(buffer, width, "%.*g", FLT_DIG + 2, value);
1263
1264
        // Should never overflow; see above.
1265
8
        DCHECK(snprintf_result > 0 && snprintf_result < width);
1266
8
    }
1267
1268
18.0M
    return snprintf_result;
1269
18.0M
}
1270
1271
830
int FastDoubleToBuffer(double value, char* buffer) {
1272
830
    auto end = fmt::format_to(buffer, FMT_COMPILE("{}"), value);
1273
830
    *end = '\0';
1274
830
    return end - buffer;
1275
830
}
1276
1277
747
int FastFloatToBuffer(float value, char* buffer) {
1278
747
    auto* end = fmt::format_to(buffer, FMT_COMPILE("{}"), value);
1279
747
    *end = '\0';
1280
747
    return end - buffer;
1281
747
}
1282
1283
// ----------------------------------------------------------------------
1284
// SimpleItoaWithCommas()
1285
//    Description: converts an integer to a string.
1286
//    Puts commas every 3 spaces.
1287
//    Faster than printf("%d")?
1288
//
1289
//    Return value: string
1290
// ----------------------------------------------------------------------
1291
0
string SimpleItoaWithCommas(int32 i) {
1292
    // 10 digits, 3 commas, and sign are good for 32-bit or smaller ints.
1293
    // Longest is -2,147,483,648.
1294
0
    char local[14];
1295
0
    char* p = local + sizeof(local);
1296
    // Need to use uint32 instead of int32 to correctly handle
1297
    // -2,147,483,648.
1298
0
    uint32 n = i;
1299
0
    if (i < 0) n = 0 - n; // negate the unsigned value to avoid overflow
1300
0
    *--p = '0' + n % 10;  // this case deals with the number "0"
1301
0
    n /= 10;
1302
0
    while (n) {
1303
0
        *--p = '0' + n % 10;
1304
0
        n /= 10;
1305
0
        if (n == 0) break;
1306
1307
0
        *--p = '0' + n % 10;
1308
0
        n /= 10;
1309
0
        if (n == 0) break;
1310
1311
0
        *--p = ',';
1312
0
        *--p = '0' + n % 10;
1313
0
        n /= 10;
1314
        // For this unrolling, we check if n == 0 in the main while loop
1315
0
    }
1316
0
    if (i < 0) *--p = '-';
1317
0
    return string(p, local + sizeof(local));
1318
0
}
1319
1320
// We need this overload because otherwise SimpleItoaWithCommas(5U) wouldn't
1321
// compile.
1322
0
string SimpleItoaWithCommas(uint32 i) {
1323
    // 10 digits and 3 commas are good for 32-bit or smaller ints.
1324
    // Longest is 4,294,967,295.
1325
0
    char local[13];
1326
0
    char* p = local + sizeof(local);
1327
0
    *--p = '0' + i % 10; // this case deals with the number "0"
1328
0
    i /= 10;
1329
0
    while (i) {
1330
0
        *--p = '0' + i % 10;
1331
0
        i /= 10;
1332
0
        if (i == 0) break;
1333
1334
0
        *--p = '0' + i % 10;
1335
0
        i /= 10;
1336
0
        if (i == 0) break;
1337
1338
0
        *--p = ',';
1339
0
        *--p = '0' + i % 10;
1340
0
        i /= 10;
1341
        // For this unrolling, we check if i == 0 in the main while loop
1342
0
    }
1343
0
    return string(p, local + sizeof(local));
1344
0
}
1345
1346
0
string SimpleItoaWithCommas(int64 i) {
1347
    // 19 digits, 6 commas, and sign are good for 64-bit or smaller ints.
1348
0
    char local[26];
1349
0
    char* p = SimpleItoaWithCommas(i, local, sizeof(local));
1350
0
    return string(p, local + sizeof(local));
1351
0
}
1352
1353
// We need this overload because otherwise SimpleItoaWithCommas(5ULL) wouldn't
1354
// compile.
1355
0
string SimpleItoaWithCommas(uint64 i) {
1356
    // 20 digits and 6 commas are good for 64-bit or smaller ints.
1357
    // Longest is 18,446,744,073,709,551,615.
1358
0
    char local[26];
1359
0
    char* p = local + sizeof(local);
1360
0
    *--p = '0' + i % 10; // this case deals with the number "0"
1361
0
    i /= 10;
1362
0
    while (i) {
1363
0
        *--p = '0' + i % 10;
1364
0
        i /= 10;
1365
0
        if (i == 0) break;
1366
1367
0
        *--p = '0' + i % 10;
1368
0
        i /= 10;
1369
0
        if (i == 0) break;
1370
1371
0
        *--p = ',';
1372
0
        *--p = '0' + i % 10;
1373
0
        i /= 10;
1374
        // For this unrolling, we check if i == 0 in the main while loop
1375
0
    }
1376
0
    return string(p, local + sizeof(local));
1377
0
}
1378
1379
8
char* SimpleItoaWithCommas(int64_t i, char* buffer, int32_t buffer_size) {
1380
    // 19 digits, 6 commas, and sign are good for 64-bit or smaller ints.
1381
8
    char* p = buffer + buffer_size;
1382
    // Need to use uint64 instead of int64 to correctly handle
1383
    // -9,223,372,036,854,775,808.
1384
8
    uint64 n = i;
1385
8
    if (i < 0) n = 0 - n;
1386
8
    *--p = '0' + n % 10; // this case deals with the number "0"
1387
8
    n /= 10;
1388
20
    while (n) {
1389
18
        *--p = '0' + n % 10;
1390
18
        n /= 10;
1391
18
        if (n == 0) break;
1392
1393
12
        *--p = '0' + n % 10;
1394
12
        n /= 10;
1395
12
        if (n == 0) break;
1396
1397
12
        *--p = ',';
1398
12
        *--p = '0' + n % 10;
1399
12
        n /= 10;
1400
        // For this unrolling, we check if n == 0 in the main while loop
1401
12
    }
1402
8
    if (i < 0) *--p = '-';
1403
8
    return p;
1404
8
}
1405
1406
17
char* SimpleItoaWithCommas(__int128_t i, char* buffer, int32_t buffer_size) {
1407
    // 39 digits, 12 commas, and sign are good for 128-bit or smaller ints.
1408
17
    char* p = buffer + buffer_size;
1409
    // Need to use uint128 instead of int128 to correctly handle
1410
    // -170,141,183,460,469,231,731,687,303,715,884,105,728.
1411
17
    __uint128_t n = i;
1412
17
    if (i < 0) n = 0 - n;
1413
17
    *--p = '0' + n % 10; // this case deals with the number "0"
1414
17
    n /= 10;
1415
45
    while (n) {
1416
38
        *--p = '0' + n % 10;
1417
38
        n /= 10;
1418
38
        if (n == 0) break;
1419
1420
34
        *--p = '0' + n % 10;
1421
34
        n /= 10;
1422
34
        if (n == 0) break;
1423
1424
28
        *--p = ',';
1425
28
        *--p = '0' + n % 10;
1426
28
        n /= 10;
1427
        // For this unrolling, we check if n == 0 in the main while loop
1428
28
    }
1429
17
    if (i < 0) *--p = '-';
1430
17
    return p;
1431
17
}
1432
1433
// ----------------------------------------------------------------------
1434
// ItoaKMGT()
1435
//    Description: converts an integer to a string
1436
//    Truncates values to a readable unit: K, G, M or T
1437
//    Opposite of atoi_kmgt()
1438
//    e.g. 100 -> "100" 1500 -> "1500"  4000 -> "3K"   57185920 -> "45M"
1439
//
1440
//    Return value: string
1441
// ----------------------------------------------------------------------
1442
0
string ItoaKMGT(int64 i) {
1443
0
    const char *sign = "", *suffix = "";
1444
0
    if (i < 0) {
1445
        // We lose some accuracy if the caller passes LONG_LONG_MIN, but
1446
        // that's OK as this function is only for human readability
1447
0
        if (i == numeric_limits<int64>::min()) i++;
1448
0
        sign = "-";
1449
0
        i = -i;
1450
0
    }
1451
1452
0
    int64 val;
1453
1454
0
    if ((val = (i >> 40)) > 1) {
1455
0
        suffix = "T";
1456
0
    } else if ((val = (i >> 30)) > 1) {
1457
0
        suffix = "G";
1458
0
    } else if ((val = (i >> 20)) > 1) {
1459
0
        suffix = "M";
1460
0
    } else if ((val = (i >> 10)) > 1) {
1461
0
        suffix = "K";
1462
0
    } else {
1463
0
        val = i;
1464
0
    }
1465
1466
0
    return StringPrintf("%s%" PRId64 "%s", sign, val, suffix);
1467
0
}
1468
1469
0
string AccurateItoaKMGT(int64 i) {
1470
0
    const char* sign = "";
1471
0
    if (i < 0) {
1472
        // We lose some accuracy if the caller passes LONG_LONG_MIN, but
1473
        // that's OK as this function is only for human readability
1474
0
        if (i == numeric_limits<int64>::min()) i++;
1475
0
        sign = "-";
1476
0
        i = -i;
1477
0
    }
1478
1479
0
    string ret = StringPrintf("%s", sign);
1480
0
    int64 val;
1481
0
    if ((val = (i >> 40)) > 1) {
1482
0
        ret += StringPrintf("%" PRId64
1483
0
                            "%s"
1484
0
                            ",",
1485
0
                            val, "T");
1486
0
        i = i - (val << 40);
1487
0
    }
1488
0
    if ((val = (i >> 30)) > 1) {
1489
0
        ret += StringPrintf("%" PRId64
1490
0
                            "%s"
1491
0
                            ",",
1492
0
                            val, "G");
1493
0
        i = i - (val << 30);
1494
0
    }
1495
0
    if ((val = (i >> 20)) > 1) {
1496
0
        ret += StringPrintf("%" PRId64
1497
0
                            "%s"
1498
0
                            ",",
1499
0
                            val, "M");
1500
0
        i = i - (val << 20);
1501
0
    }
1502
0
    if ((val = (i >> 10)) > 1) {
1503
0
        ret += StringPrintf("%" PRId64 "%s", val, "K");
1504
0
        i = i - (val << 10);
1505
0
    } else {
1506
0
        ret += StringPrintf("%" PRId64 "%s", i, "K");
1507
0
    }
1508
1509
0
    return ret;
1510
0
}
1511
1512
// DEPRECATED(wadetregaskis).
1513
// These are non-inline because some BUILD files turn on -Wformat-non-literal.
1514
1515
0
string FloatToString(float f, const char* format) {
1516
0
    return StringPrintf(format, f);
1517
0
}
1518
1519
0
string IntToString(int i, const char* format) {
1520
0
    return StringPrintf(format, i);
1521
0
}
1522
1523
0
string Int64ToString(int64 i64, const char* format) {
1524
0
    return StringPrintf(format, i64);
1525
0
}
1526
1527
0
string UInt64ToString(uint64 ui64, const char* format) {
1528
0
    return StringPrintf(format, ui64);
1529
0
}