source: mainline/uspace/app/bithenge/blob.c@ a54bd98

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

Bithenge: binary blobs.

  • Create binary blobs from random-access or sequential data sources.
  • Create binary blobs from block devices.
  • Simple test program.
  • Property mode set to 100644
File size: 4.5 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#include <bool.h>
38#include <errno.h>
39#include <macros.h>
40#include <mem.h>
41#include <stdlib.h>
42#include "blob.h"
43
44/** Initialize a random access blob.
45 * @memberof bithenge_blob_t
46 * @param[out] blob The blob to initialize.
47 * @param[in] ops Operations provided random access support. This pointer must
48 * be valid until the blob is destroyed.
49 * @return EOK on success or an error code from errno.h.
50 */
51int bithenge_new_random_access_blob(
52 bithenge_blob_t *blob,
53 const bithenge_random_access_blob_ops_t *ops) {
54 blob->ops = ops;
55 return EOK;
56}
57
58static int sequential_buffer(bithenge_sequential_blob_t *blob, aoff64_t end) {
59 bool need_realloc = false;
60 while (end > blob->buffer_size) {
61 blob->buffer_size = max(4096, 2 * blob->buffer_size);
62 need_realloc = true;
63 }
64 if (need_realloc) {
65 char *buffer = realloc(blob->buffer, blob->buffer_size);
66 if (!buffer)
67 return errno;
68 blob->buffer = buffer;
69 }
70 size_t size = end - blob->data_size;
71 int rc = blob->ops->read(blob, blob->buffer + blob->data_size, &size);
72 if (rc != EOK)
73 return rc;
74 blob->data_size += size;
75 return EOK;
76}
77
78static int sequential_size(bithenge_blob_t *base, aoff64_t *size) {
79 bithenge_sequential_blob_t *blob = (bithenge_sequential_blob_t *)base;
80 int rc = blob->ops->size(blob, size);
81 if (rc != EOK) {
82 rc = sequential_buffer(blob, blob->buffer_size);
83 if (rc != EOK)
84 return rc;
85 while (blob->data_size == blob->buffer_size) {
86 rc = sequential_buffer(blob, 2 * blob->buffer_size);
87 if (rc != EOK)
88 return rc;
89 }
90 *size = blob->data_size;
91 }
92 return EOK;
93}
94
95static int sequential_read(bithenge_blob_t *base, aoff64_t offset, char *buffer, aoff64_t *size) {
96 bithenge_sequential_blob_t *blob = (bithenge_sequential_blob_t *)base;
97 aoff64_t end = offset + *size;
98 if (end > blob->data_size) {
99 int rc = sequential_buffer(blob, end);
100 if (rc != EOK)
101 return rc;
102 }
103 if (offset > blob->data_size)
104 return EINVAL;
105 *size = min(*size, blob->data_size - end);
106 memcpy(buffer, blob->buffer + offset, *size);
107 return EOK;
108}
109
110static int sequential_destroy(bithenge_blob_t *base) {
111 bithenge_sequential_blob_t *blob = (bithenge_sequential_blob_t *)base;
112 free(blob->buffer);
113 return blob->ops->destroy(blob);
114}
115
116static const bithenge_random_access_blob_ops_t sequential_ops = {
117 .size = sequential_size,
118 .read = sequential_read,
119 .destroy = sequential_destroy,
120};
121
122/** Initialize a sequential blob.
123 * @memberof bithenge_sequential_blob_t
124 * @param[out] blob The blob to initialize.
125 * @param[in] ops Operations providing sequential access support. This pointer
126 * must be valid until the blob is destroyed.
127 * @return EOK on success or an error code from errno.h.
128 */
129int bithenge_new_sequential_blob(
130 bithenge_sequential_blob_t *blob,
131 const bithenge_sequential_blob_ops_t *ops) {
132 int rc = bithenge_new_random_access_blob(&blob->base, &sequential_ops);
133 if (rc != EOK)
134 return rc;
135 blob->ops = ops;
136 blob->buffer = NULL; // realloc(NULL, ...) works like malloc
137 blob->buffer_size = 0;
138 blob->data_size = 0;
139 return EOK;
140}
141
142/** @}
143 */
Note: See TracBrowser for help on using the repository browser.