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 commits.

Change-Id: Iaddaeb109f08be6be84c6728d72c6a043b0e7a9f
Signed-off-by: Hung-Te Lin <hungte@chromium.org>
Reviewed-on: http://review.coreboot.org/2205
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
diff --git a/util/cbfstool/common.c b/util/cbfstool/common.c
index d4560f6..aa98696 100644
--- a/util/cbfstool/common.c
+++ b/util/cbfstool/common.c
@@ -40,6 +40,69 @@
 	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) {
+		fprintf(stderr, "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) {
+		fprintf(stderr, "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) {
+		fprintf(stderr, "incomplete write: %s\n", filename);
+		fclose(fp);
+		return -1;
+	}
+	fclose(fp);
+	return 0;
+}
+
+void 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;
+}
+
 size_t getfilesize(const char *filename)
 {
 	size_t size;