Changeset ce683ed3 in mainline for uspace/app/bithenge/blob.c


Ignore:
Timestamp:
2012-05-30T01:11:32Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4b16422
Parents:
1923501
Message:

bithenge: add blobs created from memory buffers

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bithenge/blob.c

    r1923501 rce683ed3  
    174174}
    175175
     176typedef struct {
     177        bithenge_blob_t base;
     178        const char *buffer;
     179        size_t size;
     180        bool needs_free;
     181} memory_blob_t;
     182
     183static inline memory_blob_t *memory_from_blob(bithenge_blob_t *base)
     184{
     185        return (memory_blob_t *)base;
     186}
     187
     188static inline bithenge_blob_t *blob_from_memory(memory_blob_t *blob)
     189{
     190        return &blob->base;
     191}
     192
     193static int memory_size(bithenge_blob_t *base, aoff64_t *size)
     194{
     195        memory_blob_t *blob = memory_from_blob(base);
     196        *size = blob->size;
     197        return EOK;
     198}
     199
     200static int memory_read(bithenge_blob_t *base, aoff64_t offset, char *buffer,
     201    aoff64_t *size)
     202{
     203        memory_blob_t *blob = memory_from_blob(base);
     204        if (offset > blob->size)
     205                return ELIMIT;
     206        *size = min(*size, blob->size - offset);
     207        memcpy(buffer, blob->buffer + offset, *size);
     208        return EOK;
     209}
     210
     211static int memory_destroy(bithenge_blob_t *base)
     212{
     213        memory_blob_t *blob = memory_from_blob(base);
     214        if (blob->needs_free)
     215                free(blob->buffer);
     216        free(blob);
     217        return EOK;
     218}
     219
     220static const bithenge_random_access_blob_ops_t memory_ops = {
     221        .size = memory_size,
     222        .read = memory_read,
     223        .destroy = memory_destroy,
     224};
     225
     226/** Create a blob from data. Unlike with @a
     227 * bithenge_blob_t::bithenge_new_blob_from_buffer, the data is copied into a
     228 * new buffer and the original data can be changed after this call. The blob
     229 * must be freed with @a bithenge_blob_t::bithenge_blob_destroy after it is
     230 * used.
     231 * @memberof bithenge_blob_t
     232 * @param[out] out Stores the created blob.
     233 * @param[in] data The data.
     234 * @param len The length of the data.
     235 * @return EOK on success or an error code from errno.h. */
     236int bithenge_new_blob_from_data(bithenge_blob_t **out, const void *data,
     237    size_t len)
     238{
     239        int rc;
     240        assert(data || !len);
     241
     242        memory_blob_t *blob = malloc(sizeof(*blob));
     243        if (!blob)
     244                return ENOMEM;
     245        rc = bithenge_new_random_access_blob(blob_from_memory(blob),
     246            &memory_ops);
     247        if (rc != EOK) {
     248                free(blob);
     249                return rc;
     250        }
     251        char *buffer = malloc(len);
     252        if (!buffer) {
     253                free(blob);
     254                return rc;
     255        }
     256        memcpy(buffer, data, len);
     257        blob->buffer = buffer;
     258        blob->size = len;
     259        blob->needs_free = true;
     260        *out = blob_from_memory(blob);
     261        return EOK;
     262}
     263
     264/** Create a blob from a buffer. The buffer must exist as long as the blob
     265 * does. The blob must be freed with @a bithenge_blob_t::bithenge_blob_destroy
     266 * after it is used.
     267 * @memberof bithenge_blob_t
     268 * @param[out] out Stores the created blob.
     269 * @param[in] buffer The buffer, which must not be changed until the blob is
     270 * destroyed.
     271 * @param len The length of the data.
     272 * @param needs_free Whether the buffer should be freed with free() when the
     273 * blob is destroyed.
     274 * @return EOK on success or an error code from errno.h. */
     275int bithenge_new_blob_from_buffer(bithenge_blob_t **out, const void *buffer,
     276    size_t len, bool needs_free)
     277{
     278        int rc;
     279        assert(buffer || !len);
     280
     281        memory_blob_t *blob = malloc(sizeof(*blob));
     282        if (!blob)
     283                return ENOMEM;
     284        rc = bithenge_new_random_access_blob(blob_from_memory(blob),
     285            &memory_ops);
     286        if (rc != EOK) {
     287                free(blob);
     288                return rc;
     289        }
     290        blob->buffer = buffer;
     291        blob->size = len;
     292        blob->needs_free = needs_free;
     293        *out = blob_from_memory(blob);
     294        return EOK;
     295}
     296
    176297/** @}
    177298 */
Note: See TracChangeset for help on using the changeset viewer.