string.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
22 
23 #include <ctype.h>
24 #include <limits.h>
25 #include <stddef.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <time.h>
30 
31 #include "absl/strings/str_cat.h"
32 
33 #include <grpc/support/alloc.h>
34 #include <grpc/support/log.h>
36 
38 
39 char* gpr_strdup(const char* src) {
40  char* dst;
41  size_t len;
42 
43  if (!src) {
44  return nullptr;
45  }
46 
47  len = strlen(src) + 1;
48  dst = static_cast<char*>(gpr_malloc(len));
49 
50  memcpy(dst, src, len);
51 
52  return dst;
53 }
54 
56  char time_buffer[35];
57  char ns_buffer[11]; // '.' + 9 digits of precision
58  struct tm* tm_info = localtime(reinterpret_cast<time_t*>(&tm.tv_sec));
59  strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%dT%H:%M:%S", tm_info);
60  snprintf(ns_buffer, 11, ".%09d", tm.tv_nsec);
61  // This loop trims off trailing zeros by inserting a null character that the
62  // right point. We iterate in chunks of three because we want 0, 3, 6, or 9
63  // fractional digits.
64  for (int i = 7; i >= 1; i -= 3) {
65  if (ns_buffer[i] == '0' && ns_buffer[i + 1] == '0' &&
66  ns_buffer[i + 2] == '0') {
67  ns_buffer[i] = '\0';
68  // Edge case in which all fractional digits were 0.
69  if (i == 1) {
70  ns_buffer[0] = '\0';
71  }
72  } else {
73  break;
74  }
75  }
76  return absl::StrCat(time_buffer, ns_buffer, "Z");
77 }
78 
79 struct dump_out {
80  size_t capacity;
81  size_t length;
82  char* data;
83 };
84 
85 static dump_out dump_out_create(void) {
86  dump_out r = {0, 0, nullptr};
87  return r;
88 }
89 
90 static void dump_out_append(dump_out* out, char c) {
91  if (out->length == out->capacity) {
92  out->capacity = std::max(size_t(8), 2 * out->capacity);
93  out->data = static_cast<char*>(gpr_realloc(out->data, out->capacity));
94  }
95  out->data[out->length++] = c;
96 }
97 
98 static void hexdump(dump_out* out, const char* buf, size_t len) {
99  static const char* hex = "0123456789abcdef";
100 
101  const uint8_t* const beg = reinterpret_cast<const uint8_t*>(buf);
102  const uint8_t* const end = beg + len;
103  const uint8_t* cur;
104 
105  for (cur = beg; cur != end; ++cur) {
106  if (cur != beg) dump_out_append(out, ' ');
107  dump_out_append(out, hex[*cur >> 4]);
108  dump_out_append(out, hex[*cur & 0xf]);
109  }
110 }
111 
112 static void asciidump(dump_out* out, const char* buf, size_t len) {
113  const uint8_t* const beg = reinterpret_cast<const uint8_t*>(buf);
114  const uint8_t* const end = beg + len;
115  const uint8_t* cur;
116  int out_was_empty = (out->length == 0);
117  if (!out_was_empty) {
118  dump_out_append(out, ' ');
119  dump_out_append(out, '\'');
120  }
121  for (cur = beg; cur != end; ++cur) {
123  out, (isprint(*cur) ? *reinterpret_cast<const char*>(cur) : '.'));
124  }
125  if (!out_was_empty) {
126  dump_out_append(out, '\'');
127  }
128 }
129 
130 char* gpr_dump_return_len(const char* buf, size_t len, uint32_t flags,
131  size_t* out_len) {
133  if (flags & GPR_DUMP_HEX) {
134  hexdump(&out, buf, len);
135  }
136  if (flags & GPR_DUMP_ASCII) {
137  asciidump(&out, buf, len);
138  }
139  dump_out_append(&out, 0);
140  *out_len = out.length;
141  return out.data;
142 }
143 
144 char* gpr_dump(const char* buf, size_t len, uint32_t flags) {
145  size_t unused;
146  return gpr_dump_return_len(buf, len, flags, &unused);
147 }
148 
149 int gpr_parse_bytes_to_uint32(const char* buf, size_t len, uint32_t* result) {
150  uint32_t out = 0;
151  uint32_t new_val;
152  size_t i;
153 
154  if (len == 0) return 0; /* must have some bytes */
155 
156  for (i = 0; i < len; i++) {
157  if (buf[i] < '0' || buf[i] > '9') return 0; /* bad char */
158  new_val = 10 * out + static_cast<uint32_t>(buf[i] - '0');
159  if (new_val < out) return 0; /* overflow */
160  out = new_val;
161  }
162 
163  *result = out;
164  return 1;
165 }
166 
167 void gpr_reverse_bytes(char* str, int len) {
168  char *p1, *p2;
169  for (p1 = str, p2 = str + len - 1; p2 > p1; ++p1, --p2) {
170  char temp = *p1;
171  *p1 = *p2;
172  *p2 = temp;
173  }
174 }
175 
176 int gpr_ltoa(long value, char* output) {
177  long sign;
178  int i = 0;
179 
180  if (value == 0) {
181  output[0] = '0';
182  output[1] = 0;
183  return 1;
184  }
185 
186  sign = value < 0 ? -1 : 1;
187  while (value) {
188  output[i++] = static_cast<char>('0' + sign * (value % 10));
189  value /= 10;
190  }
191  if (sign < 0) output[i++] = '-';
193  output[i] = 0;
194  return i;
195 }
196 
198  int64_t sign;
199  int i = 0;
200 
201  if (value == 0) {
202  output[0] = '0';
203  output[1] = 0;
204  return 1;
205  }
206 
207  sign = value < 0 ? -1 : 1;
208  while (value) {
209  output[i++] = static_cast<char>('0' + sign * (value % 10));
210  value /= 10;
211  }
212  if (sign < 0) output[i++] = '-';
214  output[i] = 0;
215  return i;
216 }
217 
219  char* end;
220  long result = strtol(value, &end, 10);
221  if (*end != '\0' || result < 0 || result > INT_MAX) return -1;
222  return static_cast<int>(result);
223 }
224 
225 char* gpr_leftpad(const char* str, char flag, size_t length) {
226  const size_t str_length = strlen(str);
227  const size_t out_length = str_length > length ? str_length : length;
228  char* out = static_cast<char*>(gpr_malloc(out_length + 1));
229  memset(out, flag, out_length - str_length);
230  memcpy(out + out_length - str_length, str, str_length);
231  out[out_length] = 0;
232  return out;
233 }
234 
235 char* gpr_strjoin(const char** strs, size_t nstrs, size_t* final_length) {
236  return gpr_strjoin_sep(strs, nstrs, "", final_length);
237 }
238 
239 char* gpr_strjoin_sep(const char** strs, size_t nstrs, const char* sep,
240  size_t* final_length) {
241  const size_t sep_len = strlen(sep);
242  size_t out_length = 0;
243  size_t i;
244  char* out;
245  for (i = 0; i < nstrs; i++) {
246  out_length += strlen(strs[i]);
247  }
248  out_length += 1; /* null terminator */
249  if (nstrs > 0) {
250  out_length += sep_len * (nstrs - 1); /* separators */
251  }
252  out = static_cast<char*>(gpr_malloc(out_length));
253  out_length = 0;
254  for (i = 0; i < nstrs; i++) {
255  const size_t slen = strlen(strs[i]);
256  if (i != 0) {
257  memcpy(out + out_length, sep, sep_len);
258  out_length += sep_len;
259  }
260  memcpy(out + out_length, strs[i], slen);
261  out_length += slen;
262  }
263  out[out_length] = 0;
264  if (final_length != nullptr) {
265  *final_length = out_length;
266  }
267  return out;
268 }
269 
270 int gpr_strincmp(const char* a, const char* b, size_t n) {
271  int ca, cb;
272  do {
273  ca = tolower(*a);
274  cb = tolower(*b);
275  ++a;
276  ++b;
277  --n;
278  } while (ca == cb && ca != 0 && cb != 0 && n != 0);
279  return ca - cb;
280 }
281 
282 int gpr_stricmp(const char* a, const char* b) {
283  return gpr_strincmp(a, b, SIZE_MAX);
284 }
285 
286 static void add_string_to_split(const char* beg, const char* end, char*** strs,
287  size_t* nstrs, size_t* capstrs) {
288  char* out =
289  static_cast<char*>(gpr_malloc(static_cast<size_t>(end - beg) + 1));
290  memcpy(out, beg, static_cast<size_t>(end - beg));
291  out[end - beg] = 0;
292  if (*nstrs == *capstrs) {
293  *capstrs = std::max(size_t(8), 2 * *capstrs);
294  *strs = static_cast<char**>(gpr_realloc(*strs, sizeof(*strs) * *capstrs));
295  }
296  (*strs)[*nstrs] = out;
297  ++*nstrs;
298 }
299 
300 void gpr_string_split(const char* input, const char* sep, char*** strs,
301  size_t* nstrs) {
302  const char* next;
303  *strs = nullptr;
304  *nstrs = 0;
305  size_t capstrs = 0;
306  while ((next = strstr(input, sep))) {
307  add_string_to_split(input, next, strs, nstrs, &capstrs);
308  input = next + strlen(sep);
309  }
310  add_string_to_split(input, input + strlen(input), strs, nstrs, &capstrs);
311 }
312 
313 void* gpr_memrchr(const void* s, int c, size_t n) {
314  if (s == nullptr) return nullptr;
315  char* b = const_cast<char*>(reinterpret_cast<const char*>(s));
316  size_t i;
317  for (i = 0; i < n; i++) {
318  if (b[n - i - 1] == c) {
319  return &b[n - i - 1];
320  }
321  }
322  return nullptr;
323 }
324 
325 bool gpr_parse_bool_value(const char* value, bool* dst) {
326  const char* kTrue[] = {"1", "t", "true", "y", "yes"};
327  const char* kFalse[] = {"0", "f", "false", "n", "no"};
328  static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal");
329 
330  if (value == nullptr) {
331  return false;
332  }
333  for (size_t i = 0; i < GPR_ARRAY_SIZE(kTrue); ++i) {
334  if (gpr_stricmp(value, kTrue[i]) == 0) {
335  *dst = true;
336  return true;
337  } else if (gpr_stricmp(value, kFalse[i]) == 0) {
338  *dst = false;
339  return true;
340  }
341  }
342  return false; // didn't match a legal input
343 }
xds_interop_client.str
str
Definition: xds_interop_client.py:487
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
flag
uint32_t flag
Definition: ssl_versions.cc:162
dst
static const char dst[]
Definition: test-fs-copyfile.c:37
fix_build_deps.temp
temp
Definition: fix_build_deps.py:488
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
log.h
gpr_string_split
void gpr_string_split(const char *input, const char *sep, char ***strs, size_t *nstrs)
Definition: string.cc:300
dump_out
Definition: string.cc:79
absl::StrCat
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: abseil-cpp/absl/strings/str_cat.cc:98
memset
return memset(p, 0, total)
dump_out_create
static dump_out dump_out_create(void)
Definition: string.cc:85
hexdump
static void hexdump(dump_out *out, const char *buf, size_t len)
Definition: string.cc:98
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
useful.h
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
gpr_reverse_bytes
void gpr_reverse_bytes(char *str, int len)
Definition: string.cc:167
gpr_malloc
GPRAPI void * gpr_malloc(size_t size)
Definition: alloc.cc:29
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
add_string_to_split
static void add_string_to_split(const char *beg, const char *end, char ***strs, size_t *nstrs, size_t *capstrs)
Definition: string.cc:286
GPR_DUMP_HEX
#define GPR_DUMP_HEX
Definition: string.h:34
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
GPR_DUMP_ASCII
#define GPR_DUMP_ASCII
Definition: string.h:35
gpr_parse_bool_value
bool gpr_parse_bool_value(const char *value, bool *dst)
Definition: string.cc:325
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
string_util.h
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
gpr_strjoin
char * gpr_strjoin(const char **strs, size_t nstrs, size_t *final_length)
Definition: string.cc:235
gpr_realloc
GPRAPI void * gpr_realloc(void *p, size_t size)
Definition: alloc.cc:56
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
dump_out::capacity
size_t capacity
Definition: string.cc:80
SIZE_MAX
#define SIZE_MAX
Definition: stdint-msvc2008.h:206
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
text_format_test_wrapper.sep
sep
Definition: text_format_test_wrapper.py:34
asciidump
static void asciidump(dump_out *out, const char *buf, size_t len)
Definition: string.cc:112
google::protobuf::isprint
bool isprint(char c)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:79
gpr_leftpad
char * gpr_leftpad(const char *str, char flag, size_t length)
Definition: string.cc:225
gpr_strjoin_sep
char * gpr_strjoin_sep(const char **strs, size_t nstrs, const char *sep, size_t *final_length)
Definition: string.cc:239
dump_out_append
static void dump_out_append(dump_out *out, char c)
Definition: string.cc:90
gpr_memrchr
void * gpr_memrchr(const void *s, int c, size_t n)
Definition: string.cc:313
gpr_format_timespec
std::string gpr_format_timespec(gpr_timespec tm)
Definition: string.cc:55
gpr_strdup
char * gpr_strdup(const char *src)
Definition: string.cc:39
gpr_stricmp
int gpr_stricmp(const char *a, const char *b)
Definition: string.cc:282
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
tm
static uv_timer_t tm
Definition: test-tcp-open.c:41
value
const char * value
Definition: hpack_parser_table.cc:165
memory_diff.cur
def cur
Definition: memory_diff.py:83
GPR_ARRAY_SIZE
#define GPR_ARRAY_SIZE(array)
Definition: useful.h:129
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
dump_out::data
char * data
Definition: string.cc:82
dump_out::length
size_t length
Definition: string.cc:81
gpr_parse_bytes_to_uint32
int gpr_parse_bytes_to_uint32(const char *buf, size_t len, uint32_t *result)
Definition: string.cc:149
alloc.h
next
AllocList * next[kMaxLevel]
Definition: abseil-cpp/absl/base/internal/low_level_alloc.cc:100
fix_build_deps.r
r
Definition: fix_build_deps.py:491
int64_ttoa
int int64_ttoa(int64_t value, char *output)
Definition: string.cc:197
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
gpr_parse_nonnegative_int
int gpr_parse_nonnegative_int(const char *value)
Definition: string.cc:218
gpr_dump
char * gpr_dump(const char *buf, size_t len, uint32_t flags)
Definition: string.cc:144
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
gpr_timespec
Definition: gpr_types.h:50
length
std::size_t length
Definition: abseil-cpp/absl/time/internal/test_util.cc:57
gpr_strincmp
int gpr_strincmp(const char *a, const char *b, size_t n)
Definition: string.cc:270
cb
OPENSSL_EXPORT pem_password_cb * cb
Definition: pem.h:351
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
gpr_dump_return_len
char * gpr_dump_return_len(const char *buf, size_t len, uint32_t flags, size_t *out_len)
Definition: string.cc:130
gpr_ltoa
int gpr_ltoa(long value, char *output)
Definition: string.cc:176
port_platform.h


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:25