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