libbtc
bitcoinclibrary
cstr.c
Go to the documentation of this file.
1 /* Copyright 2015 BitPay, Inc.
2  * Distributed under the MIT/X11 software license, see the accompanying
3  * file COPYING or http://www.opensource.org/licenses/mit-license.php.
4  */
5 
6 #include "btc/cstr.h"
7 
8 #include <string.h>
9 
10 static btc_bool cstr_alloc_min_sz(cstring* s, size_t sz)
11 {
12  sz++; // NUL overhead
13 
14  if (s->alloc && (s->alloc >= sz))
15  return true;
16 
17  unsigned int shift = 3;
18  unsigned int al_sz;
19  while ((al_sz = (1 << shift)) < sz)
20  shift++;
21 
22  char* new_s = realloc(s->str, al_sz);
23  if (!new_s)
24  return false;
25 
26  s->str = new_s;
27  s->alloc = al_sz;
28  s->str[s->len] = 0;
29 
30  return true;
31 }
32 
33 cstring* cstr_new_sz(size_t sz)
34 {
35  cstring* s = calloc(1, sizeof(cstring));
36  if (!s)
37  return NULL;
38 
39  if (!cstr_alloc_min_sz(s, sz)) {
40  free(s);
41  return NULL;
42  }
43 
44  return s;
45 }
46 
47 cstring* cstr_new_buf(const void* buf, size_t sz)
48 {
49  cstring* s = cstr_new_sz(sz);
50  if (!s)
51  return NULL;
52 
53  memcpy(s->str, buf, sz);
54  s->len = sz;
55  s->str[s->len] = 0;
56 
57  return s;
58 }
59 
60 cstring* cstr_new(const char* init_str)
61 {
62  if (!init_str || !*init_str)
63  return cstr_new_sz(0);
64 
65  size_t slen = strlen(init_str);
66  return cstr_new_buf(init_str, slen);
67 }
68 
69 void cstr_free(cstring* s, btc_bool free_buf)
70 {
71  if (!s)
72  return;
73 
74  if (free_buf)
75  free(s->str);
76 
77  memset(s, 0, sizeof(*s));
78  free(s);
79 }
80 
81 btc_bool cstr_resize(cstring* s, size_t new_sz)
82 {
83  // no change
84  if (new_sz == s->len)
85  return true;
86 
87  // truncate string
88  if (new_sz <= s->len) {
89  s->len = new_sz;
90  s->str[s->len] = 0;
91  return true;
92  }
93 
94  // increase string size
95  if (!cstr_alloc_min_sz(s, new_sz))
96  return false;
97 
98  // contents of string tail undefined
99 
100  s->len = new_sz;
101  s->str[s->len] = 0;
102 
103  return true;
104 }
105 
106 btc_bool cstr_append_buf(cstring* s, const void* buf, size_t sz)
107 {
108  if (!cstr_alloc_min_sz(s, s->len + sz))
109  return false;
110 
111  memcpy(s->str + s->len, buf, sz);
112  s->len += sz;
113  s->str[s->len] = 0;
114 
115  return true;
116 }
117 
118 btc_bool cstr_equal(const cstring* a, const cstring* b)
119 {
120  if (a == b)
121  return true;
122  if (!a || !b)
123  return false;
124  if (a->len != b->len)
125  return false;
126  return (memcmp(a->str, b->str, a->len) == 0);
127 }
128 
129 btc_bool cstr_erase(cstring* s, size_t pos, ssize_t len)
130 {
131  if (pos == s->len && len == 0)
132  return true;
133  if (pos >= s->len)
134  return false;
135 
136  ssize_t old_tail = s->len - pos;
137  if ((len >= 0) && (len > old_tail))
138  return false;
139 
140  memmove(&s->str[pos], &s->str[pos + len], old_tail - len);
141  s->len -= len;
142  s->str[s->len] = 0;
143 
144  return true;
145 }
uint8_t btc_bool
Definition: btc.h:34
cstring * cstr_new(const char *init_str)
Definition: cstr.c:60
char * str
Definition: cstr.h:43
cstring * cstr_new_sz(size_t sz)
Definition: cstr.c:33
size_t len
Definition: buffer.h:16
size_t alloc
Definition: cstr.h:45
btc_bool cstr_resize(cstring *s, size_t new_sz)
Definition: cstr.c:81
cstring * cstr_new_buf(const void *buf, size_t sz)
Definition: cstr.c:47
btc_bool cstr_erase(cstring *s, size_t pos, ssize_t len)
Definition: cstr.c:129
static btc_bool cstr_alloc_min_sz(cstring *s, size_t sz)
Definition: cstr.c:10
size_t len
Definition: cstr.h:44
void cstr_free(cstring *s, btc_bool free_buf)
Definition: cstr.c:69
btc_bool cstr_append_buf(cstring *s, const void *buf, size_t sz)
Definition: cstr.c:106
Definition: cstr.h:41
btc_bool cstr_equal(const cstring *a, const cstring *b)
Definition: cstr.c:118