Motr  M0
buf.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
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  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include "lib/arith.h" /* min_type */
24 #include "lib/memory.h"
25 #include "lib/errno.h"
26 #include "lib/misc.h"
27 #include "lib/buf.h"
28 
29 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LIB
30 #include "lib/trace.h"
31 
37 M0_INTERNAL void m0_buf_init(struct m0_buf *buf, void *data, uint32_t nob)
38 {
39  buf->b_addr = data;
40  buf->b_nob = nob;
41 }
42 
43 M0_INTERNAL int m0_buf_alloc(struct m0_buf *buf, size_t size)
44 {
46 
47  buf->b_addr = m0_alloc(size);
48  if (buf->b_addr == NULL)
49  return -ENOMEM;
50 
51  buf->b_nob = size;
52  return 0;
53 }
54 
55 M0_INTERNAL void m0_buf_free(struct m0_buf *buf)
56 {
57  m0_free0(&buf->b_addr);
58  buf->b_nob = 0;
59 }
60 
61 M0_INTERNAL int m0_buf_new_aligned(struct m0_buf *buf,
62  const void *data, uint32_t nob,
63  unsigned shift)
64 {
65  M0_ALLOC_ARR_ALIGNED(buf->b_addr, nob, shift);
66  if (buf->b_addr == NULL)
67  return M0_ERR(-ENOMEM);
68  buf->b_nob = nob;
69  memcpy(buf->b_addr, data, nob);
70  return 0;
71 }
72 
73 M0_INTERNAL int m0_buf_cmp(const struct m0_buf *x, const struct m0_buf *y)
74 {
75  int rc;
76 
77  rc = memcmp(x->b_addr, y->b_addr,
78  min_type(m0_bcount_t, x->b_nob, y->b_nob));
79  /*
80  * Special case when one buffer is prefix for the second. We can't
81  * compare the first byte of the suffix with 0, because m0_buf may
82  * contain '\0' and in this situation 0 would return for not equal
83  * buffers.
84  */
85  if (rc == 0 && x->b_nob != y->b_nob)
86  rc = x->b_nob > y->b_nob ? 1 : -1;
87  return rc;
88 }
89 
90 M0_INTERNAL bool m0_buf_eq(const struct m0_buf *x, const struct m0_buf *y)
91 {
92  return x->b_nob == y->b_nob &&
93  memcmp(x->b_addr, y->b_addr, x->b_nob) == 0;
94 }
95 
96 M0_INTERNAL void m0_buf_memcpy(struct m0_buf *dst, const struct m0_buf *src)
97 {
98  M0_PRE(dst->b_nob == src->b_nob);
99  M0_PRE(dst->b_addr != NULL);
100 
101  memcpy(dst->b_addr, src->b_addr, src->b_nob);
102 }
103 
104 M0_INTERNAL int m0_buf_copy(struct m0_buf *dest, const struct m0_buf *src)
105 {
106  M0_PRE(dest->b_nob == 0 && dest->b_addr == NULL);
107 
108  if (src->b_nob != 0) {
109  dest->b_addr = m0_alloc(src->b_nob);
110  if (dest->b_addr == NULL)
111  return M0_ERR(-ENOMEM);
112  dest->b_nob = src->b_nob;
113  memcpy(dest->b_addr, src->b_addr, src->b_nob);
114  }
116  return 0;
117 }
118 
119 M0_INTERNAL int m0_buf_copy_aligned(struct m0_buf *dst,
120  const struct m0_buf *src,
121  unsigned shift)
122 {
123  M0_PRE(dst->b_nob == 0 && dst->b_addr == NULL);
124  return m0_buf_new_aligned(dst, src->b_addr, src->b_nob, shift);
125 }
126 
127 M0_INTERNAL bool m0_buf_is_set(const struct m0_buf *buf)
128 {
129  return buf->b_nob > 0 && buf->b_addr != NULL;
130 }
131 
132 M0_INTERNAL bool m0_buf_streq(const struct m0_buf *buf, const char *str)
133 {
134  M0_PRE(str != NULL);
135 
136  return strlen(str) == buf->b_nob &&
137  memcmp(str, buf->b_addr, buf->b_nob) == 0;
138 }
139 
140 M0_INTERNAL char *m0_buf_strdup(const struct m0_buf *buf)
141 {
142  size_t len;
143  char *s;
144 
145  /* Measure the size of payload. */
146  s = memchr(buf->b_addr, 0, buf->b_nob);
147  len = s == NULL ? buf->b_nob : s - (char *)buf->b_addr;
148 
149  M0_ALLOC_ARR(s, len + 1);
150  if (s != NULL) {
151  memcpy(s, buf->b_addr, len);
152  s[len] = 0;
153  }
154  return s;
155 }
156 
157 M0_INTERNAL int m0_bufs_from_strings(struct m0_bufs *dest, const char **src)
158 {
159  size_t i;
160  int rc;
161 
162  M0_SET0(dest);
163 
164  if (src == NULL)
165  return 0;
166 
167  while (src[dest->ab_count] != NULL)
168  ++dest->ab_count;
169  if (dest->ab_count == 0)
170  return 0;
171 
172  M0_ALLOC_ARR(dest->ab_elems, dest->ab_count);
173  if (dest->ab_elems == NULL)
174  return M0_ERR(-ENOMEM);
175 
176  for (i = 0; i < dest->ab_count; ++i) {
177  rc = m0_buf_copy(&dest->ab_elems[i],
178  &M0_BUF_INITS((char *)src[i]));
179  if (rc != 0) {
181  return M0_ERR(-ENOMEM);
182  }
183  }
184  return 0;
185 }
186 
187 M0_INTERNAL int
188 m0_bufs_to_strings(const char ***dest, const struct m0_bufs *src)
189 {
190  uint32_t i;
191 
192  M0_PRE(*dest == NULL);
193  M0_PRE((src->ab_count == 0) == (src->ab_elems == NULL));
194 
195  if (src->ab_count == 0)
196  return 0; /* there is nothing to copy */
197 
198  M0_ALLOC_ARR(*dest, src->ab_count + 1);
199  if (*dest == NULL)
200  return M0_ERR(-ENOMEM);
201 
202  for (i = 0; i < src->ab_count; ++i) {
203  (*dest)[i] = m0_buf_strdup(&src->ab_elems[i]);
204  if ((*dest)[i] == NULL)
205  goto fail;
206  }
207  (*dest)[i] = NULL; /* end of list */
208 
209  return 0;
210 fail:
211  for (; i != 0; --i)
212  m0_free((void *)(*dest)[i]);
213  m0_free(*dest);
214  return M0_ERR(-ENOMEM);
215 }
216 
217 M0_INTERNAL bool m0_bufs_streq(const struct m0_bufs *bufs, const char **strs)
218 {
219  uint32_t i;
220 
221  for (i = 0; strs[i] != NULL; ++i) {
222  if (i >= bufs->ab_count || !m0_buf_streq(&bufs->ab_elems[i],
223  strs[i]))
224  return false;
225  }
226  return i == bufs->ab_count;
227 }
228 
229 M0_INTERNAL void m0_bufs_free(struct m0_bufs *bufs)
230 {
231  while (bufs->ab_count > 0)
232  m0_buf_free(&bufs->ab_elems[--bufs->ab_count]);
233  m0_free0(&bufs->ab_elems);
234  M0_POST(bufs->ab_count == 0);
235 }
236 
237 #undef M0_TRACE_SUBSYSTEM
238 
241 /*
242  * Local variables:
243  * c-indentation-style: "K&R"
244  * c-basic-offset: 8
245  * tab-width: 8
246  * fill-column: 80
247  * scroll-step: 1
248  * End:
249  */
M0_INTERNAL int m0_buf_copy_aligned(struct m0_buf *dst, const struct m0_buf *src, unsigned shift)
Definition: buf.c:119
M0_INTERNAL int m0_buf_new_aligned(struct m0_buf *buf, const void *data, uint32_t nob, unsigned shift)
Definition: buf.c:61
#define M0_PRE(cond)
struct m0_buf * ab_elems
Definition: buf.h:45
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
M0_INTERNAL bool m0_buf_is_set(const struct m0_buf *buf)
Definition: buf.c:127
#define NULL
Definition: misc.h:38
static struct m0_bufvec dst
Definition: xform.c:61
static bool x
Definition: sm.c:168
void * b_addr
Definition: buf.h:39
M0_INTERNAL bool m0_buf_eq(const struct m0_buf *x, const struct m0_buf *y)
Definition: buf.c:90
M0_INTERNAL bool m0_buf_streq(const struct m0_buf *buf, const char *str)
Definition: buf.c:132
uint32_t ab_count
Definition: buf.h:44
M0_INTERNAL void m0_buf_init(struct m0_buf *buf, void *data, uint32_t nob)
Definition: buf.c:37
struct m0_bufvec data
Definition: di.c:40
#define min_type(t, a, b)
Definition: arith.h:76
uint64_t m0_bcount_t
Definition: types.h:77
#define M0_SET0(obj)
Definition: misc.h:64
M0_INTERNAL int m0_buf_cmp(const struct m0_buf *x, const struct m0_buf *y)
Definition: buf.c:73
Definition: sock.c:887
M0_INTERNAL void m0_buf_memcpy(struct m0_buf *dst, const struct m0_buf *src)
Definition: buf.c:96
Definition: buf.h:37
int i
Definition: dir.c:1033
return M0_ERR(-EOPNOTSUPP)
M0_INTERNAL bool m0_bufs_streq(const struct m0_bufs *bufs, const char **strs)
Definition: buf.c:217
#define m0_free0(pptr)
Definition: memory.h:77
m0_bcount_t b_nob
Definition: buf.h:38
M0_INTERNAL void m0_bufs_free(struct m0_bufs *bufs)
Definition: buf.c:229
M0_INTERNAL int m0_buf_alloc(struct m0_buf *buf, size_t size)
Definition: buf.c:43
void * m0_alloc(size_t size)
Definition: memory.c:126
#define M0_POST(cond)
#define M0_BUF_INITS(str)
Definition: buf.h:70
M0_INTERNAL void m0_buf_free(struct m0_buf *buf)
Definition: buf.c:55
M0_INTERNAL int m0_buf_copy(struct m0_buf *dest, const struct m0_buf *src)
Definition: buf.c:104
static uint8_t fail[DATA_UNIT_COUNT_MAX+PARITY_UNIT_COUNT_MAX]
M0_INTERNAL char * m0_buf_strdup(const struct m0_buf *buf)
Definition: buf.c:140
M0_INTERNAL int m0_bufs_to_strings(const char ***dest, const struct m0_bufs *src)
Definition: buf.c:188
m0_bcount_t size
Definition: di.c:39
#define M0_ALLOC_ARR_ALIGNED(arr, nr, shift)
Definition: memory.h:88
Definition: buf.h:43
void m0_free(void *data)
Definition: memory.c:146
static struct m0_addb2_source * s
Definition: consumer.c:39
struct m0_pdclust_src_addr src
Definition: fd.c:108
int32_t rc
Definition: trigger_fop.h:47
M0_INTERNAL int m0_bufs_from_strings(struct m0_bufs *dest, const char **src)
Definition: buf.c:157