0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
String.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 3
9  * of the License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Hypertable. If not, see <http://www.gnu.org/licenses/>
18  */
19 
24 #include "Common/Compat.h"
25 
26 #include <cstdarg>
27 #include <cstdio>
28 #include <algorithm>
29 
30 #include "String.h"
31 
32 using namespace std;
33 using namespace Hypertable;
34 
35 namespace Hypertable {
36 
37 String format(const char *fmt, ...) {
38  char buf[1024]; // should be enough for most cases
39  int n, size = sizeof(buf);
40  char *p = buf;
41  va_list ap;
42 
43  do {
44  va_start(ap, fmt);
45  n = vsnprintf(p, size, fmt, ap);
46  va_end(ap);
47 
48  if (n > -1 && n < size)
49  break; // worked!
50 
51  if (n > -1) // glibc 2.1+/iso c99
52  size = n + 1; // exactly what's needed
53  else // glibc 2.0
54  size *= 2; // double the size and try again
55 
56  p = (char *)(p == buf ? malloc(size) : realloc(p, size));
57 
58  if (!p)
59  throw bad_alloc();
60  } while (true);
61 
62  if (buf == p)
63  return string(p, n);
64 
65  string ret(p, n);
66  free(p);
67 
68  return ret;
69 }
70 
71 char const *const digits = "0123456789";
72 
73 String format_number(int64_t n, int sep) {
74  char buf[30], *p = buf, *p0 = buf;
75  int ndigits = 0;
76  uint64_t num; // for edge cases when -n is still negative when n < 0
77 
78  if (n < 0) {
79  *p++ = '-';
80  p0 = p;
81  num = -n;
82  }
83  else
84  num = n;
85 
86  if (num == 0)
87  *p++ = '0';
88  else for (; num != 0; num /= 10) {
89  *p++ = digits[num % 10];
90  ++ndigits;
91 
92  if (num >= 10 && ndigits % 3 == 0)
93  *p++ = sep;
94  }
95 
96  int len = ndigits + (ndigits - 1) / 3;
97  std::reverse(p0, p0 + len);
98 
99  return String(buf, len + p0 - buf);
100 }
101 
102 String
103 format_bytes(size_t n, const void *buf, size_t len, const char *trailer) {
104  if (buf) {
105  if (len <= n)
106  return String((char *)buf, len);
107 
108  String out((char *)buf, n);
109  out += trailer;
110  return out;
111  }
112  return "<null>";
113 }
114 
115 const char NumericFormatterDigits::DIGITS[] =
116  "0001020304050607080910111213141516171819"
117  "2021222324252627282930313233343536373839"
118  "4041424344454647484950515253545556575859"
119  "6061626364656667686970717273747576777879"
120  "8081828384858687888990919293949596979899";
121 
122 } // namespace Hypertable
char const *const digits
Definition: String.cc:71
String format_number(int64_t n, int sep)
Return decimal number string separated by a separator (default: comma) for every 3 digits...
Definition: String.cc:73
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
Definition: String.cc:37
STL namespace.
String format_bytes(size_t n, const void *buf, size_t len, const char *trailer)
Return first n bytes of buffer with an optional trailer if the size of the buffer exceeds n...
Definition: String.cc:103
Compatibility Macros for C/C++.
Hypertable definitions
A String class based on std::string.