source: mainline/uspace/lib/bithenge/blob.h@ a42d7d8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a42d7d8 was a42d7d8, checked in by Sean Bartell <wingedtachikoma@…>, 13 years ago

Bithenge: add fake system call errors to test error handling

  • Property mode set to 100644
File size: 8.8 KB
Line 
1/*
2 * Copyright (c) 2012 Sean Bartell
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup bithenge
30 * @{
31 */
32/**
33 * @file
34 * Raw binary blobs.
35 */
36
37#ifndef BITHENGE_BLOB_H_
38#define BITHENGE_BLOB_H_
39
40#include <sys/types.h>
41#include "tree.h"
42
43/** A blob of raw binary data.
44 * @implements bithenge_node_t */
45typedef struct {
46 /** @privatesection */
47 struct bithenge_node_t base;
48} bithenge_blob_t;
49
50/** Operations providing random access to binary data.
51 * @todo Should these be thread-safe? */
52typedef struct bithenge_random_access_blob_ops_t {
53 /** @copydoc bithenge_blob_t::bithenge_blob_size */
54 int (*size)(bithenge_blob_t *self, aoff64_t *size);
55 /** @copydoc bithenge_blob_t::bithenge_blob_read */
56 int (*read)(bithenge_blob_t *self, aoff64_t offset, char *buffer,
57 aoff64_t *size);
58 /** @copydoc bithenge_blob_t::bithenge_blob_read_bits */
59 int (*read_bits)(bithenge_blob_t *self, aoff64_t offset, char *buffer,
60 aoff64_t *size, bool little_endian);
61 /** Destroy the blob.
62 * @param blob The blob. */
63 void (*destroy)(bithenge_blob_t *self);
64} bithenge_random_access_blob_ops_t;
65
66/** A blob built from an object that supports only sequential reading.
67 * @implements bithenge_blob_t */
68typedef struct {
69 /** @privatesection */
70 /** The base random-access blob. */
71 bithenge_blob_t base;
72 /** Operations providing sequential access. */
73 const struct bithenge_sequential_blob_ops_t *ops;
74 /** Buffer containing all data read. */
75 char *buffer;
76 /** Size of buffer. */
77 aoff64_t buffer_size;
78 /** Amount of data actually in buffer. */
79 aoff64_t data_size;
80} bithenge_sequential_blob_t;
81
82/** Operations providing sequential access to binary data.
83 * @memberof bithenge_sequential_blob_t */
84typedef struct bithenge_sequential_blob_ops_t {
85
86 /** Get the total size of the blob. If the total size cannot be
87 * determined easily, this field may be null or return an error,
88 * forcing the entire blob to be read to determine its size.
89 *
90 * @memberof bithenge_blob_t
91 * @param self The blob.
92 * @param[out] size Total size of the blob.
93 * @return EOK on success or an error code from errno.h.
94 */
95 int (*size)(bithenge_sequential_blob_t *self, aoff64_t *size);
96
97 /** Read the next part of the blob. If the requested data extends
98 * beyond the end of the blob, the data up until the end of the blob
99 * will be read.
100 *
101 * @param self The blob.
102 * @param[out] buffer Buffer to read into. If an error occurs, the contents are
103 * undefined.
104 * @param[in,out] size Number of bytes to read; may be 0. If not enough
105 * data is left in the blob, the actual number of bytes read should be
106 * stored here. If an error occurs, the contents are undefined.
107 * @return EOK on success or an error code from errno.h.
108 */
109 int (*read)(bithenge_sequential_blob_t *self, char *buffer,
110 aoff64_t *size);
111
112 /** Destroy the blob.
113 * @param self The blob. */
114 void (*destroy)(bithenge_sequential_blob_t *self);
115} bithenge_sequential_blob_ops_t;
116
117/** Get the total size of the blob.
118 *
119 * @memberof bithenge_blob_t
120 * @param self The blob.
121 * @param[out] size Total size of the blob.
122 * @return EOK on success or an error code from errno.h.
123 */
124static inline int bithenge_blob_size(bithenge_blob_t *self, aoff64_t *size)
125{
126 assert(self);
127 assert(self->base.blob_ops);
128 return self->base.blob_ops->size(self, size);
129}
130
131/** Read part of the blob. If the requested data extends beyond the end of the
132 * blob, the data up until the end of the blob will be read. If the offset is
133 * beyond the end of the blob, even if the size is zero, an error will be
134 * returned.
135 *
136 * @memberof bithenge_blob_t
137 * @param self The blob.
138 * @param offset Byte offset within the blob.
139 * @param[out] buffer Buffer to read into. If an error occurs, the contents are
140 * undefined.
141 * @param[in,out] size Number of bytes to read; may be 0. If the requested
142 * range extends beyond the end of the blob, the actual number of bytes read
143 * should be stored here. If an error occurs, the contents are undefined.
144 * @return EOK on success or an error code from errno.h.
145 */
146static inline int bithenge_blob_read(bithenge_blob_t *self, aoff64_t offset,
147 char *buffer, aoff64_t *size)
148{
149 assert(self);
150 assert(self->base.blob_ops);
151 if (!self->base.blob_ops->read)
152 return EINVAL;
153 return self->base.blob_ops->read(self, offset, buffer, size);
154}
155
156/** Read part of the bit blob. If the requested data extends beyond the end of
157 * the blob, the data up until the end of the blob will be read. If the offset
158 * is beyond the end of the blob, even if the size is zero, an error will be
159 * returned.
160 *
161 * @memberof bithenge_blob_t
162 * @param self The blob.
163 * @param offset Byte offset within the blob.
164 * @param[out] buffer Buffer to read into. If an error occurs, the contents are
165 * undefined.
166 * @param[in,out] size Number of bytes to read; may be 0. If the requested
167 * range extends beyond the end of the blob, the actual number of bytes read
168 * should be stored here. If an error occurs, the contents are undefined.
169 * @param little_endian If true, bytes will be filled starting at the least
170 * significant bit; otherwise, they will be filled starting at the most
171 * significant bit.
172 * @return EOK on success or an error code from errno.h.
173 */
174static inline int bithenge_blob_read_bits(bithenge_blob_t *self,
175 aoff64_t offset, char *buffer, aoff64_t *size, bool little_endian)
176{
177 assert(self);
178 assert(self->base.blob_ops);
179 if (!self->base.blob_ops->read_bits)
180 return EINVAL;
181 return self->base.blob_ops->read_bits(self, offset, buffer, size,
182 little_endian);
183}
184
185/** Check whether the blob is empty.
186 *
187 * @memberof bithenge_blob_t
188 * @param self The blob.
189 * @param[out] out Holds whether the blob is empty.
190 * @return EOK on success or an error code from errno.h. */
191static inline int bithenge_blob_empty(bithenge_blob_t *self, bool *out)
192{
193 assert(self);
194 assert(self->base.blob_ops);
195 aoff64_t size;
196 int rc = bithenge_blob_size(self, &size);
197 *out = size == 0;
198 return rc;
199}
200
201/** Cast a blob node to a generic node.
202 * @memberof bithenge_blob_t
203 * @param blob The blob to cast.
204 * @return The blob node as a generic node. */
205static inline bithenge_node_t *bithenge_blob_as_node(bithenge_blob_t *blob)
206{
207 return &blob->base;
208}
209
210/** Cast a generic node to a blob node.
211 * @memberof bithenge_blob_t
212 * @param node The node to cast, which must be a blob node.
213 * @return The generic node as a blob node. */
214static inline bithenge_blob_t *bithenge_node_as_blob(bithenge_node_t *node)
215{
216 assert(node->type == BITHENGE_NODE_BLOB);
217 return (bithenge_blob_t *)node;
218}
219
220/** Increment a blob's reference count.
221 * @param blob The blob to reference. */
222static inline void bithenge_blob_inc_ref(bithenge_blob_t *blob)
223{
224 bithenge_node_inc_ref(bithenge_blob_as_node(blob));
225}
226
227/** Decrement a blob's reference count.
228 * @param blob The blob to dereference, or NULL. */
229static inline void bithenge_blob_dec_ref(bithenge_blob_t *blob)
230{
231 if (blob)
232 bithenge_node_dec_ref(bithenge_blob_as_node(blob));
233}
234
235int bithenge_init_random_access_blob(bithenge_blob_t *,
236 const bithenge_random_access_blob_ops_t *);
237int bithenge_init_sequential_blob(bithenge_sequential_blob_t *,
238 const bithenge_sequential_blob_ops_t *);
239int bithenge_new_blob_from_data(bithenge_node_t **, const void *, size_t);
240int bithenge_new_blob_from_buffer(bithenge_node_t **, const void *, size_t,
241 bool);
242int bithenge_new_offset_blob(bithenge_node_t **, bithenge_blob_t *, aoff64_t);
243int bithenge_new_subblob(bithenge_node_t **, bithenge_blob_t *, aoff64_t,
244 aoff64_t);
245int bithenge_blob_equal(bool *, bithenge_blob_t *, bithenge_blob_t *);
246
247#endif
248
249/** @}
250 */
Note: See TracBrowser for help on using the repository browser.