Hung-Te Lin (hungte@chromium.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2205
-gerrit
commit 3a77c06dc4d3a208349a4a2db1470d73bcc1f1a6 Author: Hung-Te Lin hungte@chromium.org Date: Tue Jan 29 01:33:46 2013 +0800
cbfstool: Add buffer management API.
Many functions in cbfstool need to deal with a memory buffer - both location and size. Right now it's made by different ways: for ROM image using global variable (romsize, master_header); and in cbfs-* using return value for size and char** to return memory location.
This may cause bugs like assuming incorrect return types, ex: uint32_t file_size = parse(); // which returns "-1" on error if (file_size <= 0) { ... And the parse error will never be caught.
We can simplify this by introducing a buffer API, to change unsigned int do_something(char *input, size_t len, char **output, ...) into int do_something(struct buffer *input, struct buffer *output, ...)
The buffer API will be used by further CLs.
Change-Id: Iaddaeb109f08be6be84c6728d72c6a043b0e7a9f Signed-off-by: Hung-Te Lin hungte@chromium.org --- util/cbfstool/common.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ util/cbfstool/common.h | 22 ++++++++++++++++++ 2 files changed, 85 insertions(+)
diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c index 34153eb..16854dc 100644 --- a/util/cbfstool/common.c +++ b/util/cbfstool/common.c @@ -39,6 +39,69 @@ int is_big_endian(void) return 0; }
+/* Buffer and file I/O */ + +int buffer_create(struct buffer *buffer, size_t size, const char *name) { + buffer->name = strdup(name); + buffer->size = size; + buffer->data = (char *)malloc(buffer->size); + if (!buffer->data) { + ERROR("buffer_create: Insufficient memory (0x%zx).\n", size); + } + return (buffer->data == NULL); +} + +int buffer_from_file(struct buffer *buffer, const char *filename) { + FILE *fp = fopen(filename, "rb"); + if (!fp) { + perror(filename); + return -1; + } + fseek(fp, 0, SEEK_END); + buffer->size = ftell(fp); + buffer->name = strdup(filename); + rewind(fp); + buffer->data = (char *)malloc(buffer->size); + assert(buffer->data); + if (fread(buffer->data, 1, buffer->size, fp) != buffer->size) { + ERROR("incomplete read: %s\n", filename); + fclose(fp); + return -1; + } + fclose(fp); + return 0; +} + +int buffer_write_file(struct buffer *buffer, const char *filename) { + FILE *fp = fopen(filename, "wb"); + if (!fp) { + perror(filename); + return -1; + } + assert(buffer && buffer->data); + if (fwrite(buffer->data, 1, buffer->size, fp) != buffer->size) { + ERROR("incomplete write: %s\n", filename); + fclose(fp); + return -1; + } + fclose(fp); + return 0; +} + +int buffer_delete(struct buffer *buffer) { + assert(buffer); + if (buffer->name) { + free(buffer->name); + buffer->name = NULL; + } + if (buffer->data) { + free(buffer->data); + buffer->data = NULL; + } + buffer->size = 0; + return 0; +} + size_t getfilesize(const char *filename) { size_t size; diff --git a/util/cbfstool/common.h b/util/cbfstool/common.h index 7ade6b2..3901ca7 100644 --- a/util/cbfstool/common.h +++ b/util/cbfstool/common.h @@ -21,6 +21,7 @@ #define __CBFSTOOL_COMMON_H
#include <stdint.h> +#include <assert.h>
/* Endianess */ #include "swab.h" @@ -40,6 +41,27 @@ extern int verbose; #define INFO(x...) { if (verbose > 0) fprintf(stderr, "INFO: " x); } #define DEBUG(x...) { if (verbose > 1) fprintf(stderr, "DEBUG: " x); }
+/* Buffer and file I/O */ +struct buffer { + char *name; + char *data; + size_t size; +}; + +/* Creates an empty memory buffer with given size. + * Returns 0 on success, otherwise non-zero. */ +int buffer_create(struct buffer *buffer, size_t size, const char *name); + +/* Loads a file into memory buffer. Returns 0 on success, otherwise non-zero. */ +int buffer_from_file(struct buffer *buffer, const char *filename); + +/* Writes memory buffer content into file. + * Returns 0 on success, otherwise non-zero. */ +int buffer_write_file(struct buffer *buffer, const char *filename); + +/* Destroys a memory buffer. Returns 0 on success, otherwise non-zero. */ +int buffer_delete(struct buffer *buffer); + /* Utilities */ const char *simple_basename(const char *name);