1 /****************************************************************************
2 *
3 * The MIT License (MIT)
4 *
5 * Copyright 2020 NXP
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * 'Software'), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject
14 * to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial
18 * portions of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
21 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL VIVANTE AND/OR ITS SUPPLIERS BE LIABLE FOR ANY
24 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 *****************************************************************************/
29 #include "buf_reader.h"
30 #include "stdio.h"
31 #include "string.h"
32
33 #define DBG_TRACE(x) printf x
34
_is_buffered_handle_valid(bufferred_reader_t * fd)35 static int _is_buffered_handle_valid(bufferred_reader_t *fd)
36 {
37 if (fd == NULL)
38 return E_BUF_INVALID_HANDLE;
39 if ( fd->data_buf == NULL )
40 return E_BUF_INVALID_HANDLE;
41 if ( fd->size < 0 )
42 return E_BUF_INVALID_HANDLE;
43 if ( fd->index > fd->size )
44 return E_BUF_INVALID_HANDLE;
45
46 return 0;
47 }
48
49 /* Write buffered IO operations */
bufferred_fopen(bufferred_reader_t * fd,char * buf,int size)50 int bufferred_fopen(bufferred_reader_t *fd, char *buf, int size)
51 {
52 if (fd == NULL)
53 return E_BUF_INVALID_HANDLE;
54
55 fd->data_buf = buf;
56 fd->size = size;
57 fd->index = 0;
58
59 if ( _is_buffered_handle_valid(fd)) {
60 return E_BUF_INVALID_HANDLE;
61 }
62
63 fd->is_valid = 1;
64
65 return 0;
66 }
67
bufferred_ftell(bufferred_reader_t * fd)68 int bufferred_ftell(bufferred_reader_t *fd)
69 {
70 if ( _is_buffered_handle_valid(fd)) {
71 return E_BUF_INVALID_HANDLE;
72 }
73
74 return fd->index;
75 }
76
bufferred_fread(void * ptr,int size,int nmemb,bufferred_reader_t * fd)77 int bufferred_fread(
78 void *ptr,
79 int size,
80 int nmemb,
81 bufferred_reader_t *fd
82 )
83 {
84 int to_copy = 0;
85 char *data_ptr = NULL;
86 char *buff = (char *)ptr;
87 int byte_to_read = size * nmemb;
88
89 if ( _is_buffered_handle_valid(fd)) {
90 return E_BUF_INVALID_HANDLE;
91 }
92
93 if ( buff == NULL ) {
94 return E_BUF_IO_INVALID_PARAMETERS;
95 }
96
97 if ( byte_to_read < 0 ) {
98 return E_BUF_IO_INVALID_PARAMETERS;
99 }
100
101 to_copy = (fd->size - fd->index);
102 data_ptr = fd->data_buf + fd->index;
103
104 if ( to_copy > byte_to_read )
105 to_copy = byte_to_read;
106
107 if (to_copy <= 0)
108 return -1; //EOF
109
110 memcpy(buff, data_ptr, to_copy);
111
112 fd->index += to_copy;
113
114 return 0;
115 }
116
bufferred_fseek(bufferred_reader_t * fd,int offset,int direction)117 int bufferred_fseek(
118 bufferred_reader_t *fd,
119 int offset,
120 int direction
121 )
122 {
123 if ( _is_buffered_handle_valid(fd)) {
124 return E_BUF_INVALID_HANDLE;
125 }
126
127 switch(direction)
128 {
129 case SEEK_SET:
130 fd->index = offset;
131 break;
132 case SEEK_CUR:
133 fd->index += offset;
134 break;
135 case SEEK_END:
136 fd->index = fd->size - offset;
137 break;
138 }
139
140 /* Clamp current offset */
141 if ( fd->index > fd->size ) {
142 DBG_TRACE(("WARNING: seeking beyond buffer size\n"));
143 fd->index = fd->size;
144 }
145 if ( fd->index < 0 ) {
146 DBG_TRACE(("WARNING: seeking beyond buffer size\n"));
147 fd->index = 0;
148 }
149
150 return 0;
151 }
152
bufferred_fclose(bufferred_reader_t * fd)153 int bufferred_fclose(bufferred_reader_t *fd)
154 {
155 if ( _is_buffered_handle_valid(fd)) {
156 return E_BUF_INVALID_HANDLE;
157 }
158
159 fd->size = -1;
160 fd->is_valid = 0;
161
162 return 0;
163 }
164
bufferred_fgets(char * buff,int len,bufferred_reader_t * fd)165 char *bufferred_fgets(char* buff, int len, bufferred_reader_t *fd)
166 {
167 char *ptr;
168 int i, j, valid_bytes;
169
170 if ( buff == NULL ) {
171 return NULL;
172 }
173
174 if ( len <= 0 ) {
175 return NULL;
176 }
177
178 if ( _is_buffered_handle_valid(fd)) {
179 return NULL;
180 }
181
182 /* Check how many bytes are available to read */
183 valid_bytes = fd->size - fd->index;
184 if ( len > 0 )
185 len -=1; /* fgets read one character less than buffer length */
186 if ( len > valid_bytes )
187 len = valid_bytes;
188
189 if ( valid_bytes <= 0 )
190 return NULL;
191
192 ptr = fd->data_buf + fd->index;
193 for(i=0; ptr[i] != '\0' && i < len; i++)
194 {
195 if ( ptr[i] == '\n' )
196 break;
197 if ( ptr[i] == '\r' )
198 break;
199 buff[i] = ptr[i];
200 }
201 buff[i] = '\0';
202 j = i;
203 /* skip trailing newline from file buffer */
204 if ( ptr[i] == '\r' )
205 i++;
206 if ( ptr[i] == '\n' )
207 i++;
208 fd->index += i;
209
210 /* Trim trailing spaces from output buffer */
211 for (i = j-1 ; i>0; i--) {
212 if (buff[i] == ' ')
213 buff[i] = '\0';
214 else
215 break;
216 }
217
218
219 return ptr;
220
221 }
222