gRPC  0.6.0
 All Classes Namespaces Functions Variables Enumerations Properties Pages
slice.h
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 *);
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 = (newlen)) \
101  : ((slice).data.inlined.length = (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, len) is called. Requires
114  s initialized. */
115 void gpr_slice_unref(gpr_slice s);
116 
117 /* Create a slice pointing at some data. Calls malloc to allocate a refcount
118  for the object, and arranges that destroy will be called with the pointer
119  passed in at destruction. */
120 gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *));
121 
122 /* Equivalent to gpr_slice_new, but with a two argument destroy function that
123  also takes the slice length. */
124 gpr_slice gpr_slice_new_with_len(void *p, size_t len,
125  void (*destroy)(void *, size_t));
126 
127 /* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc()
128  call.
129  Aborts if malloc() fails. */
130 gpr_slice gpr_slice_malloc(size_t length);
131 
132 /* Create a slice by copying a string.
133  Does not preserve null terminators.
134  Equivalent to:
135  size_t len = strlen(source);
136  gpr_slice slice = gpr_slice_malloc(len);
137  memcpy(slice->data, source, len); */
138 gpr_slice gpr_slice_from_copied_string(const char *source);
139 
140 /* Create a slice by copying a buffer.
141  Equivalent to:
142  gpr_slice slice = gpr_slice_malloc(len);
143  memcpy(slice->data, source, len); */
144 gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
145 
146 /* Return a result slice derived from s, which shares a ref count with s, where
147  result.data==s.data+begin, and result.length==end-begin.
148  The ref count of s is increased by one.
149  Requires s initialized, begin <= end, begin <= s.length, and
150  end <= source->length. */
151 gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end);
152 
153 /* The same as gpr_slice_sub, but without altering the ref count */
154 gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end);
155 
156 /* Splits s into two: modifies s to be s[0:split], and returns a new slice,
157  sharing a refcount with s, that contains s[split:s.length].
158  Requires s intialized, split <= s.length */
159 gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split);
160 
161 /* Splits s into two: modifies s to be s[split:s.length], and returns a new
162  slice, sharing a refcount with s, that contains s[0:split].
163  Requires s intialized, split <= s.length */
164 gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split);
165 
166 gpr_slice gpr_empty_slice(void);
167 
168 /* Returns <0 if a < b, ==0 if a == b, >0 if a > b
169  The order is arbitrary, and is not guaranteed to be stable across different
170  versions of the API. */
171 int gpr_slice_cmp(gpr_slice a, gpr_slice b);
172 int gpr_slice_str_cmp(gpr_slice a, const char *b);
173 
174 #ifdef __cplusplus
175 }
176 #endif
177 
178 #endif /* GRPC_SUPPORT_SLICE_H */
Definition: slice.h:63
Definition: slice.h:79