summaryrefslogtreecommitdiff
path: root/utils/jztool/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/jztool/src/buffer.c')
-rw-r--r--utils/jztool/src/buffer.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/utils/jztool/src/buffer.c b/utils/jztool/src/buffer.c
new file mode 100644
index 0000000000..9e9c9ff5d1
--- /dev/null
+++ b/utils/jztool/src/buffer.c
@@ -0,0 +1,134 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "jztool.h"
23#include <stdlib.h>
24#include <string.h>
25#include <stdio.h>
26
27/** \brief Allocate a buffer, optionally providing its contents.
28 * \param size Number of bytes to allocate
29 * \param data Initial contents of the buffer, must be at least `size` bytes
30 * \return Pointer to buffer or NULL if out of memory.
31 * \note The buffer will not take ownership of the `data` pointer, instead it
32 * allocates a fresh buffer and copies the contents of `data` into it.
33 */
34jz_buffer* jz_buffer_alloc(size_t size, const void* data)
35{
36 jz_buffer* buf = malloc(sizeof(struct jz_buffer));
37 if(!buf)
38 return NULL;
39
40 buf->data = malloc(size);
41 if(!buf->data) {
42 free(buf);
43 return NULL;
44 }
45
46 if(data)
47 memcpy(buf->data, data, size);
48
49 buf->size = size;
50 return buf;
51}
52
53/** \brief Free a buffer
54 */
55void jz_buffer_free(jz_buffer* buf)
56{
57 if(buf) {
58 free(buf->data);
59 free(buf);
60 }
61}
62
63/** \brief Load a buffer from a file
64 * \param buf Returns loaded buffer on success, unmodified on error
65 * \param filename Path to the file
66 * \return either JZ_SUCCESS, or one of the following errors
67 * \retval JZ_ERR_OPEN_FILE file cannot be opened
68 * \retval JZ_ERR_OUT_OF_MEMORY cannot allocate buffer to hold file contents
69 * \retval JZ_ERR_FILE_IO problem reading file data
70 */
71int jz_buffer_load(jz_buffer** buf, const char* filename)
72{
73 FILE* f;
74 jz_buffer* b;
75 int rc;
76
77 f = fopen(filename, "rb");
78 if(!f)
79 return JZ_ERR_OPEN_FILE;
80
81 fseek(f, 0, SEEK_END);
82 int size = ftell(f);
83 fseek(f, 0, SEEK_SET);
84
85 b = jz_buffer_alloc(size, NULL);
86 if(!b) {
87 rc = JZ_ERR_OUT_OF_MEMORY;
88 goto err_fclose;
89 }
90
91 if(fread(b->data, size, 1, f) != 1) {
92 rc = JZ_ERR_FILE_IO;
93 goto err_free_buf;
94 }
95
96 rc = JZ_SUCCESS;
97 *buf = b;
98
99 err_fclose:
100 fclose(f);
101 return rc;
102
103 err_free_buf:
104 jz_buffer_free(b);
105 goto err_fclose;
106}
107
108/** \brief Save a buffer to a file
109 * \param buf Buffer to be written out
110 * \param filename Path to the file
111 * \return either JZ_SUCCESS, or one of the following errors
112 * \retval JZ_ERR_OPEN_FILE file cannot be opened
113 * \retval JZ_ERR_FILE_IO problem writing file data
114 */
115int jz_buffer_save(jz_buffer* buf, const char* filename)
116{
117 int rc;
118 FILE* f;
119
120 f = fopen(filename, "wb");
121 if(!f)
122 return JZ_ERR_OPEN_FILE;
123
124 if(fwrite(buf->data, buf->size, 1, f) != 1) {
125 rc = JZ_ERR_FILE_IO;
126 goto err_fclose;
127 }
128
129 rc = JZ_SUCCESS;
130
131 err_fclose:
132 fclose(f);
133 return rc;
134}