GRPC Core 0.10.0.0

- Main Page
- Data Structures
- Files

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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_SUPPORT_SLICE_H
35 #define GRPC_SUPPORT_SLICE_H
36
37 #include <grpc/support/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 *);
66 } gpr_slice_refcount;
67
68 #define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(gpr_uint8 *) - 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 {
80 struct gpr_slice_refcount *refcount;
81 union {
82 struct {
83 gpr_uint8 *bytes;
84 size_t length;
85 } refcounted;
86 struct {
87 gpr_uint8 length;
88 gpr_uint8 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 = (gpr_uint8)(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. */
108 gpr_slice gpr_slice_ref(gpr_slice 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. */
116 void gpr_slice_unref(gpr_slice s);
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 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 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 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 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 gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
146
147 /* Return a result slice derived from s, which shares a ref count with s, where
148 result.data==s.data+begin, and result.length==end-begin.
149 The ref count of s is increased by one.
150 Requires s initialized, begin <= end, begin <= s.length, and
151 end <= source->length. */
152 gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end);
153
154 /* The same as gpr_slice_sub, but without altering the ref count */
155 gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end);
156
157 /* Splits s into two: modifies s to be s[0:split], and returns a new slice,
158 sharing a refcount with s, that contains s[split:s.length].
159 Requires s intialized, split <= s.length */
160 gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split);
161
162 /* Splits s into two: modifies s to be s[split:s.length], and returns a new
163 slice, sharing a refcount with s, that contains s[0:split].
164 Requires s intialized, split <= s.length */
165 gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split);
166
167 gpr_slice gpr_empty_slice(void);
168
169 /* Returns <0 if a < b, ==0 if a == b, >0 if a > b
170 The order is arbitrary, and is not guaranteed to be stable across different
171 versions of the API. */
172 int gpr_slice_cmp(gpr_slice a, gpr_slice b);
173 int gpr_slice_str_cmp(gpr_slice a, const char *b);
174
175 #ifdef __cplusplus
176 }
177 #endif
178
179 #endif /* GRPC_SUPPORT_SLICE_H */
gpr_slice_sub
gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end)
Definition: slice.c:227
gpr_uint8
uint8_t gpr_uint8
Definition: port_platform.h:307
gpr_slice_new_with_len
gpr_slice gpr_slice_new_with_len(void *p, size_t len, void(*destroy)(void *, size_t))
Definition: slice.c:120
gpr_slice_split_head
gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split)
Definition: slice.c:278
gpr_slice::refcounted
struct gpr_slice::@27::@28 refcounted
gpr_slice::length
size_t length
Definition: slice.h:84
gpr_slice::data
union gpr_slice::@27 data
gpr_slice::bytes
gpr_uint8 * bytes
Definition: slice.h:83
gpr_slice_from_copied_string
gpr_slice gpr_slice_from_copied_string(const char *source)
Definition: slice.c:144
gpr_empty_slice
gpr_slice gpr_empty_slice(void)
Definition: slice.c:40
gpr_slice_str_cmp
int gpr_slice_str_cmp(gpr_slice a, const char *b)
Definition: slice.c:322
gpr_slice::inlined
struct gpr_slice::@27::@29 inlined
gpr_slice_from_copied_buffer
gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len)
Definition: slice.c:138
gpr_slice_ref
gpr_slice gpr_slice_ref(gpr_slice s)
Definition: slice.c:47
gpr_slice_cmp
int gpr_slice_cmp(gpr_slice a, gpr_slice b)
Definition: slice.c:315
gpr_slice_new
gpr_slice gpr_slice_new(void *p, size_t len, void(*destroy)(void *))
Definition: slice.c:82
gpr_slice_refcount::unref
void(* unref)(void *)
Definition: slice.h:65
gpr_slice_refcount::ref
void(* ref)(void *)
Definition: slice.h:64
gpr_slice::refcount
struct gpr_slice_refcount * refcount
Definition: slice.h:80
gpr_slice_malloc
gpr_slice gpr_slice_malloc(size_t length)
Definition: slice.c:165
gpr_slice_split_tail
gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split)
Definition: slice.c:243
sync.h
GPR_SLICE_INLINED_SIZE
#define GPR_SLICE_INLINED_SIZE
Definition: slice.h:68
gpr_slice_unref
void gpr_slice_unref(gpr_slice s)
Definition: slice.c:54
gpr_slice::length
gpr_uint8 length
Definition: slice.h:87
gpr_slice_refcount
Definition: slice.h:63
gpr_slice_refcount
struct gpr_slice_refcount gpr_slice_refcount
gpr_slice
struct gpr_slice gpr_slice
gpr_slice
Definition: slice.h:79
gpr_slice_sub_no_ref
gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end)
Definition: slice.c:202