GRPC Core  1.0.0
slice.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015, Google Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * * Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above
13  * copyright notice, this list of conditions and the following disclaimer
14  * in the documentation and/or other materials provided with the
15  * distribution.
16  * * Neither the name of Google Inc. nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 
34 #ifndef GRPC_IMPL_CODEGEN_SLICE_H
35 #define GRPC_IMPL_CODEGEN_SLICE_H
36 
37 #include <grpc/impl/codegen/sync.h>
38 
39 #include <stddef.h>
40 
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44 
45 /* Slice API
46 
47  A slice represents a contiguous reference counted array of bytes.
48  It is cheap to take references to a slice, and it is cheap to create a
49  slice pointing to a subset of another slice.
50 
51  The data-structure for slices is exposed here to allow non-gpr code to
52  build slices from whatever data they have available.
53 
54  When defining interfaces that handle slices, care should be taken to define
55  reference ownership semantics (who should call unref?) and mutability
56  constraints (is the callee allowed to modify the slice?) */
57 
58 /* Reference count container for gpr_slice. Contains function pointers to
59  increment and decrement reference counts. Implementations should cleanup
60  when the reference count drops to zero.
61  Typically client code should not touch this, and use gpr_slice_malloc,
62  gpr_slice_new, or gpr_slice_new_with_len instead. */
63 typedef struct gpr_slice_refcount {
64  void (*ref)(void *);
65  void (*unref)(void *);
67 
68 #define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
69 
70 /* A gpr_slice s, if initialized, represents the byte range
71  s.bytes[0..s.length-1].
72 
73  It can have an associated ref count which has a destruction routine to be run
74  when the ref count reaches zero (see gpr_slice_new() and grp_slice_unref()).
75  Multiple gpr_slice values may share a ref count.
76 
77  If the slice does not have a refcount, it represents an inlined small piece
78  of data that is copied by value. */
79 typedef struct gpr_slice {
81  union {
82  struct {
83  uint8_t *bytes;
84  size_t length;
85  } refcounted;
86  struct {
87  uint8_t length;
88  uint8_t bytes[GPR_SLICE_INLINED_SIZE];
89  } inlined;
90  } data;
91 } gpr_slice;
92 
93 #define GPR_SLICE_START_PTR(slice) \
94  ((slice).refcount ? (slice).data.refcounted.bytes \
95  : (slice).data.inlined.bytes)
96 #define GPR_SLICE_LENGTH(slice) \
97  ((slice).refcount ? (slice).data.refcounted.length \
98  : (slice).data.inlined.length)
99 #define GPR_SLICE_SET_LENGTH(slice, newlen) \
100  ((slice).refcount ? ((slice).data.refcounted.length = (size_t)(newlen)) \
101  : ((slice).data.inlined.length = (uint8_t)(newlen)))
102 #define GPR_SLICE_END_PTR(slice) \
103  GPR_SLICE_START_PTR(slice) + GPR_SLICE_LENGTH(slice)
104 #define GPR_SLICE_IS_EMPTY(slice) (GPR_SLICE_LENGTH(slice) == 0)
105 
106 /* Increment the refcount of s. Requires slice is initialized.
107  Returns s. */
109 
110 /* Decrement the ref count of s. If the ref count of s reaches zero, all
111  slices sharing the ref count are destroyed, and considered no longer
112  initialized. If s is ultimately derived from a call to gpr_slice_new(start,
113  len, dest) where dest!=NULL , then (*dest)(start) is called, else if s is
114  ultimately derived from a call to gpr_slice_new_with_len(start, len, dest)
115  where dest!=NULL , then (*dest)(start, len). Requires s initialized. */
117 
118 /* Create a slice pointing at some data. Calls malloc to allocate a refcount
119  for the object, and arranges that destroy will be called with the pointer
120  passed in at destruction. */
121 GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *));
122 
123 /* Equivalent to gpr_slice_new, but with a two argument destroy function that
124  also takes the slice length. */
125 GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len,
126  void (*destroy)(void *, size_t));
127 
128 /* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc()
129  call.
130  Aborts if malloc() fails. */
131 GPRAPI gpr_slice gpr_slice_malloc(size_t length);
132 
133 /* Create a slice by copying a string.
134  Does not preserve null terminators.
135  Equivalent to:
136  size_t len = strlen(source);
137  gpr_slice slice = gpr_slice_malloc(len);
138  memcpy(slice->data, source, len); */
139 GPRAPI gpr_slice gpr_slice_from_copied_string(const char *source);
140 
141 /* Create a slice by copying a buffer.
142  Equivalent to:
143  gpr_slice slice = gpr_slice_malloc(len);
144  memcpy(slice->data, source, len); */
145 GPRAPI gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
146 
147 /* Create a slice pointing to constant memory */
148 GPRAPI gpr_slice gpr_slice_from_static_string(const char *source);
149 
150 /* Return a result slice derived from s, which shares a ref count with s, where
151  result.data==s.data+begin, and result.length==end-begin.
152  The ref count of s is increased by one.
153  Requires s initialized, begin <= end, begin <= s.length, and
154  end <= source->length. */
155 GPRAPI gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end);
156 
157 /* The same as gpr_slice_sub, but without altering the ref count */
158 GPRAPI gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end);
159 
160 /* Splits s into two: modifies s to be s[0:split], and returns a new slice,
161  sharing a refcount with s, that contains s[split:s.length].
162  Requires s intialized, split <= s.length */
164 
165 /* Splits s into two: modifies s to be s[split:s.length], and returns a new
166  slice, sharing a refcount with s, that contains s[0:split].
167  Requires s intialized, split <= s.length */
169 
171 
172 /* Returns <0 if a < b, ==0 if a == b, >0 if a > b
173  The order is arbitrary, and is not guaranteed to be stable across different
174  versions of the API. */
176 GPRAPI int gpr_slice_str_cmp(gpr_slice a, const char *b);
177 
178 #ifdef __cplusplus
179 }
180 #endif
181 
182 #endif /* GRPC_IMPL_CODEGEN_SLICE_H */
struct gpr_slice gpr_slice
GPRAPI gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len)
#define GPR_SLICE_INLINED_SIZE
Definition: slice.h:68
size_t length
Definition: slice.h:84
GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len, void(*destroy)(void *, size_t))
GPRAPI gpr_slice gpr_empty_slice(void)
#define GPRAPI
Definition: port_platform.h:463
GPRAPI gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end)
GPRAPI int gpr_slice_cmp(gpr_slice a, gpr_slice b)
GPRAPI void gpr_slice_unref(gpr_slice s)
GPRAPI gpr_slice gpr_slice_malloc(size_t length)
GPRAPI gpr_slice gpr_slice_from_static_string(const char *source)
GPRAPI gpr_slice gpr_slice_from_copied_string(const char *source)
GPRAPI gpr_slice gpr_slice_ref(gpr_slice s)
GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void(*destroy)(void *))
struct gpr_slice_refcount * refcount
Definition: slice.h:80
GPRAPI gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split)
GPRAPI int gpr_slice_str_cmp(gpr_slice a, const char *b)
uint8_t * bytes
Definition: slice.h:83
GPRAPI gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end)
struct gpr_slice_refcount gpr_slice_refcount
void(* unref)(void *)
Definition: slice.h:65
uint8_t length
Definition: slice.h:87
GPRAPI gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split)
Definition: slice.h:63
void(* ref)(void *)
Definition: slice.h:64
Definition: slice.h:79