X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=datastore.c;h=91b4d60ef47bc320162f61658c79ae100d968e5e;hb=a885ce3ee9ed770594d5b231f6dec0b740bba03b;hp=3d72c99d794b904e6fa28e9ed4199c8e4caf489c;hpb=b7f09cf86dd57a59dc1bdece2cac9e4a176900b1;p=libsigrok.git diff --git a/datastore.c b/datastore.c index 3d72c99d..91b4d60e 100644 --- a/datastore.c +++ b/datastore.c @@ -1,7 +1,7 @@ /* * This file is part of the sigrok project. * - * Copyright (C) 2010 Bert Vermeulen + * Copyright (C) 2010-2012 Bert Vermeulen * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,8 +21,31 @@ #include #include #include -#include "sigrok.h" -#include "sigrok-internal.h" +#include "libsigrok.h" +#include "libsigrok-internal.h" + +/* Message logging helpers with driver-specific prefix string. */ +#define DRIVER_LOG_DOMAIN "datastore: " +#define sr_log(l, s, args...) sr_log(l, DRIVER_LOG_DOMAIN s, ## args) +#define sr_spew(s, args...) sr_spew(DRIVER_LOG_DOMAIN s, ## args) +#define sr_dbg(s, args...) sr_dbg(DRIVER_LOG_DOMAIN s, ## args) +#define sr_info(s, args...) sr_info(DRIVER_LOG_DOMAIN s, ## args) +#define sr_warn(s, args...) sr_warn(DRIVER_LOG_DOMAIN s, ## args) +#define sr_err(s, args...) sr_err(DRIVER_LOG_DOMAIN s, ## args) + +/** + * @file + * + * Creating, using, or destroying libsigrok datastores. + */ + +/** + * @defgroup grp_datastore Datastore + * + * Creating, using, or destroying libsigrok datastores. + * + * @{ + */ static gpointer new_chunk(struct sr_datastore **ds); @@ -36,8 +59,8 @@ static gpointer new_chunk(struct sr_datastore **ds); * It is the caller's responsibility to free the allocated memory of the * datastore via the sr_datastore_destroy() function, if no longer needed. * - * TODO: Unitsize should probably be unsigned int or uint32_t or similar. - * TODO: This function should have a 'chunksize' parameter, and + * @todo Unitsize should probably be unsigned int or uint32_t or similar. + * @todo This function should have a 'chunksize' parameter, and * struct sr_datastore a 'chunksize' field. * * @param unitsize The unit size (>= 1) to be used for this datastore. @@ -48,21 +71,21 @@ static gpointer new_chunk(struct sr_datastore **ds); * or SR_ERR_ARG upon invalid arguments. If something other than SR_OK * is returned, the value of 'ds' is undefined. */ -int sr_datastore_new(int unitsize, struct sr_datastore **ds) +SR_API int sr_datastore_new(int unitsize, struct sr_datastore **ds) { if (!ds) { - sr_err("ds: %s: ds was NULL", __func__); + sr_err("%s: ds was NULL", __func__); return SR_ERR_ARG; } if (unitsize <= 0) { - sr_err("ds: %s: unitsize was %d, but it must be >= 1", + sr_err("%s: unitsize was %d, but it must be >= 1", __func__, unitsize); return SR_ERR_ARG; } if (!(*ds = g_try_malloc(sizeof(struct sr_datastore)))) { - sr_err("ds: %s: ds malloc failed", __func__); + sr_err("%s: ds malloc failed", __func__); return SR_ERR_MALLOC; } @@ -83,12 +106,12 @@ int sr_datastore_new(int unitsize, struct sr_datastore **ds) * * @return SR_OK upon success, SR_ERR_ARG upon invalid arguments. */ -int sr_datastore_destroy(struct sr_datastore *ds) +SR_API int sr_datastore_destroy(struct sr_datastore *ds) { GSList *chunk; if (!ds) { - sr_err("ds: %s: ds was NULL", __func__); + sr_err("%s: ds was NULL", __func__); return SR_ERR_ARG; } @@ -96,8 +119,7 @@ int sr_datastore_destroy(struct sr_datastore *ds) g_free(chunk->data); g_slist_free(ds->chunklist); g_free(ds); - - /* TODO: Set ds = NULL? */ + ds = NULL; return SR_OK; } @@ -105,21 +127,20 @@ int sr_datastore_destroy(struct sr_datastore *ds) /** * Append some data to the specified datastore. * - * TODO: More elaborate function description. - * - * TODO: This function should use the (not yet available) 'chunksize' field + * @todo More elaborate function description. + * @todo This function should use the (not yet available) 'chunksize' field * of struct sr_datastore (instead of hardcoding DATASTORE_CHUNKSIZE). - * TODO: in_unitsize and probelist are unused? - * TODO: A few of the parameters can be const. - * TODO: Handle new_chunk() returning NULL. - * TODO: Ideally, 'ds' should be unmodified upon errors. + * @todo in_unitsize and probelist are unused? + * @todo A few of the parameters can be const. + * @todo Ideally, 'ds' should be unmodified upon errors. + * @todo Should 0 be allowed as length? + * @todo Specify/document the data format of the 'data' parameter. * * @param ds Pointer to the datastore which shall receive the data. * Must not be NULL. * @param data Pointer to the memory buffer containing the data to add. - * Must not be NULL. TODO: Data format? + * Must not be NULL. * @param length Length of the data to add (in number of bytes). - * TODO: Should 0 be allowed as length? * @param in_unitsize The unit size (>= 1) of the input data. * @param probelist Pointer to a list of integers (probe numbers). The probe * numbers in this list are 1-based, i.e. the first probe @@ -129,49 +150,49 @@ int sr_datastore_destroy(struct sr_datastore *ds) * or SR_ERR_ARG upon invalid arguments. If something other than SR_OK * is returned, the value/state of 'ds' is undefined. */ -int sr_datastore_put(struct sr_datastore *ds, void *data, unsigned int length, - int in_unitsize, int *probelist) +SR_API int sr_datastore_put(struct sr_datastore *ds, void *data, + unsigned int length, int in_unitsize, const int *probelist) { unsigned int stored; int capacity, size, num_chunks, chunk_bytes_free, chunk_offset; gpointer chunk; - /* Avoid compiler warnings. */ - (void)in_unitsize; - (void)probelist; - if (!ds) { - sr_err("ds: %s: ds was NULL", __func__); + sr_err("%s: ds was NULL", __func__); return SR_ERR_ARG; } /* Unitsize must not be 0, we'll divide by 0 otherwise. */ if (ds->ds_unitsize == 0) { - sr_err("ds: %s: ds->ds_unitsize was 0", __func__); + sr_err("%s: ds->ds_unitsize was 0", __func__); return SR_ERR_ARG; } if (!data) { - sr_err("ds: %s: data was NULL", __func__); + sr_err("%s: data was NULL", __func__); return SR_ERR_ARG; } if (in_unitsize < 1) { - sr_err("ds: %s: in_unitsize was %d, but it must be >= 1", + sr_err("%s: in_unitsize was %d, but it must be >= 1", __func__, in_unitsize); return SR_ERR_ARG; } if (!probelist) { - sr_err("ds: %s: probelist was NULL", __func__); + sr_err("%s: probelist was NULL", __func__); return SR_ERR_ARG; } /* Get the last chunk in the list, or create a new one if needed. */ - if (ds->chunklist == NULL) - chunk = new_chunk(&ds); - else + if (ds->chunklist == NULL) { + if (!(chunk = new_chunk(&ds))) { + sr_err("%s: couldn't allocate new chunk", __func__); + return SR_ERR_MALLOC; + } + } else { chunk = g_slist_last(ds->chunklist)->data; + } /* Get/calculate number of chunks, free space, etc. */ num_chunks = g_slist_length(ds->chunklist); @@ -184,7 +205,11 @@ int sr_datastore_put(struct sr_datastore *ds, void *data, unsigned int length, while (stored < length) { /* No more free space left, allocate a new chunk. */ if (chunk_bytes_free == 0) { - chunk = new_chunk(&ds); + if (!(chunk = new_chunk(&ds))) { + sr_err("%s: couldn't allocate new chunk", + __func__); + return SR_ERR_MALLOC; + } chunk_bytes_free = DATASTORE_CHUNKSIZE; chunk_offset = 0; } @@ -213,9 +238,9 @@ int sr_datastore_put(struct sr_datastore *ds, void *data, unsigned int length, * * The allocated memory is guaranteed to be cleared. * - * TODO: This function should use the datastore's 'chunksize' field instead + * @todo This function should use the datastore's 'chunksize' field instead * of hardcoding DATASTORE_CHUNKSIZE. - * TODO: Return int, so we can return SR_OK / SR_ERR_ARG / SR_ERR_MALLOC? + * @todo Return int, so we can return SR_OK / SR_ERR_ARG / SR_ERR_MALLOC? * * @param ds Pointer to a variable which holds the datastore structure. * Must not be NULL. The contents of 'ds' are modified in-place. @@ -226,14 +251,12 @@ static gpointer new_chunk(struct sr_datastore **ds) { gpointer chunk; - if (!ds) { - sr_err("ds: %s: ds was NULL", __func__); - return NULL; /* TODO: SR_ERR_ARG later? */ - } + /* Note: Caller checked that ds != NULL. */ chunk = g_try_malloc0(DATASTORE_CHUNKSIZE * (*ds)->ds_unitsize); if (!chunk) { - sr_err("ds: %s: chunk malloc failed", __func__); + sr_err("%s: chunk malloc failed (ds_unitsize was %u)", + __func__, (*ds)->ds_unitsize); return NULL; /* TODO: SR_ERR_MALLOC later? */ } @@ -241,3 +264,5 @@ static gpointer new_chunk(struct sr_datastore **ds) return chunk; /* TODO: SR_OK later? */ } + +/** @} */