1 /********************************************************
2  Bitstream Library, a module for reading bits of data
3 
4  Copyright (C) 2007-2014  Brian Langenberger
5 
6  The Bitstream Library is free software; you can redistribute it and/or modify
7  it under the terms of either:
8 
9    * the GNU Lesser General Public License as published by the Free
10      Software Foundation; either version 3 of the License, or (at your
11      option) any later version.
12 
13  or
14 
15    * the GNU General Public License as published by the Free Software
16      Foundation; either version 2 of the License, or (at your option) any
17      later version.
18 
19  or both in parallel, as here.
20 
21  The Bitstream Library is distributed in the hope that it will be useful, but
22  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24  for more details.
25 
26  You should have received copies of the GNU General Public License and the
27  GNU Lesser General Public License along with the GNU MP Library.  If not,
28  see https://www.gnu.org/licenses/.
29  *******************************************************/
30 
31 #ifndef __BITSTREAMLIB_FUNCIO_H__
32 #define __BITSTREAMLIB_FUNCIO_H__
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <stdint.h>
37 
38 
39 /*casts for inserting functions with non-void pointers into ext_open_r*/
40 
41 /*returns number of bytes actually read*/
42 typedef unsigned (*ext_read_f)(void* user_data,
43                                uint8_t* buffer,
44                                unsigned buffer_size);
45 
46 /*casts for inserting functions with non-void pointers into ext_open_w*/
47 
48 /*returns 0 on successful write, 1 if a write error occurs*/
49 typedef int (*ext_write_f)(void* user_data,
50                            const uint8_t* buffer,
51                            unsigned buffer_size);
52 
53 /*returns 0 on a successful flush, EOF if a write error occurs*/
54 typedef int (*ext_flush_f)(void* user_data);
55 
56 /*casts used by both ext_open_r and ext_open_w*/
57 
58 /*returns 0 on a successful seek, EOF if a seek error occurs*/
59 typedef int (*ext_setpos_f)(void* user_data, void* pos);
60 
61 /*returns non-NULL on a successful tell, NULL if a tell error occurs*/
62 typedef void* (*ext_getpos_f)(void* user_data);
63 
64 /*frees position object pos as returned by ext_tell_f*/
65 typedef void (*ext_free_pos_f)(void *pos);
66 
67 /*returns 0 on successful seek, nonzero if an error occurs*/
68 typedef int (*ext_seek_f)(void* user_data, long position, int whence);
69 
70 /*returns 0 on a successful close, EOF if a close error occurs*/
71 typedef int (*ext_close_f)(void* user_data);
72 
73 /*free user data as used by read_f or write_f*/
74 typedef void (*ext_free_f)(void* user_data);
75 
76 struct br_external_input {
77     void* user_data;
78     ext_read_f read;
79     ext_setpos_f setpos;
80     ext_getpos_f getpos;
81     ext_free_pos_f free_pos;
82     ext_seek_f seek;
83     ext_close_f close;
84     ext_free_f free;
85 
86     struct {
87         uint8_t *data;
88         unsigned pos;
89         unsigned size;
90         unsigned maximum_size;
91     } buffer;
92 };
93 
94 struct bw_external_output {
95     void* user_data;
96     ext_write_f write;
97     ext_setpos_f setpos;
98     ext_getpos_f getpos;
99     ext_free_pos_f free_pos;
100     ext_flush_f flush;
101     ext_close_f close;
102     ext_free_f free;
103 
104     struct {
105         uint8_t *data;
106         unsigned pos;
107         unsigned maximum_size;
108     } buffer;
109 };
110 
111 /*** stdio-like functions for br_external_input ***/
112 
113 /*analagous to fopen for reading*/
114 struct br_external_input*
115 ext_open_r(void* user_data,
116            unsigned buffer_size,
117            ext_read_f read,
118            ext_setpos_f setpos,
119            ext_getpos_f getpos,
120            ext_free_pos_f free_pos,
121            ext_seek_f seek,
122            ext_close_f close,
123            ext_free_f free);
124 
125 /*analagous to fgetc
126 
127   returns EOF and end of stream or if a read error occurs*/
128 int
129 ext_getc(struct br_external_input* stream);
130 
131 /*analagous to fread
132 
133   reads "data_size" bytes from "stream" to "data"
134   and returns the amount of bytes actually read
135   (which may be less than the amount requested)*/
136 unsigned
137 ext_fread(struct br_external_input* stream,
138           uint8_t* data,
139           unsigned data_size);
140 
141 /*analagous to fseek
142 
143   moves current stream position to position
144   relative to stream position "whence"
145 
146   returns 0 on success, nonzero on failure*/
147 int
148 ext_fseek_r(struct br_external_input *stream, long position, int whence);
149 
150 
151 /*analagous to fclose
152 
153   this calls the passed-in close() function
154   but doesn't deallocate "stream" itself*/
155 void
156 ext_close_r(struct br_external_input* stream);
157 
158 /*this calls the passed-in free() function
159   before deallocating "stream" itself*/
160 void
161 ext_free_r(struct br_external_input* stream);
162 
163 /*** stdio-like functions for bw_external_input ***/
164 
165 /*analagous to fopen for writing*/
166 struct bw_external_output*
167 ext_open_w(void* user_data,
168            unsigned buffer_size,
169            ext_write_f write,
170            ext_setpos_f setpos,
171            ext_getpos_f getpos,
172            ext_free_pos_f free_pos,
173            ext_flush_f flush,
174            ext_close_f close,
175            ext_free_f free);
176 
177 /*analagous to fputc
178 
179   returns character written on success, EOF if a write error occurs*/
180 int
181 ext_putc(int i, struct bw_external_output* stream);
182 
183 /*analagous to fwrite
184 
185   returns 0 on success, EOF if a write error occurs*/
186 int
187 ext_fwrite(struct bw_external_output* stream,
188            const uint8_t *data,
189            unsigned data_size);
190 
191 /*analagous to fsetpos
192 
193   moves current stream position to pos
194   which has been returned by ext_tell_w
195 
196   returns 0 on success, EOF on failure*/
197 int
198 ext_setpos_w(struct bw_external_output *stream, void *pos);
199 
200 /*analagous to fgetpos
201 
202   returns current position as pos
203   which may be fed to ext_seek_w
204 
205   returns NULL if an error occurs*/
206 void*
207 ext_getpos_w(struct bw_external_output *stream);
208 
209 /*analagous to fflush,
210   this sends all buffered bytes to write function
211   and calls passed-in flush() function
212 
213   returns 0 on success, EOF on error*/
214 int
215 ext_flush_w(struct bw_external_output* stream);
216 
217 /*analagous to fclose
218 
219   this flushes output and calls passed-in close() function
220   but doesn't deallocate "stream" itself
221 
222   returns 0 on success, EOF on error*/
223 int
224 ext_close_w(struct bw_external_output* stream);
225 
226 /*this calls the passed-in free() function
227   before deallocating "stream"*/
228 void
229 ext_free_w(struct bw_external_output* stream);
230 
231 
232 #endif
233