libopenmpt: libopenmpt/libopenmpt_stream_callbacks_buffer.h Source File

libopenmpt 0.9.0-pre.12+r25552 cross-platform C++ and C library to decode tracked music files

Loading...
Searching...
No Matches
libopenmpt_stream_callbacks_buffer.h
Go to the documentation of this file.
1/*
2 * libopenmpt_stream_callbacks_buffer.h
3 * ------------------------------------
4 * Purpose: libopenmpt public c interface
5 * Notes : (currently none)
6 * Authors: OpenMPT Devs
7 * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
8 */
9
10#ifndef LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H
11#define LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H
12
13#include "libopenmpt.h"
14
15#include <stdint.h>
16#include <stdlib.h>
17#include <string.h>
18
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27 typedef struct openmpt_stream_buffer {
28 const void * file_data; /* or prefix data IFF prefix_size < file_size */
29 int64_t file_size;
30 int64_t file_pos;
31 int64_t prefix_size;
32 int overflow;
33} openmpt_stream_buffer;
34
35 static LIBOPENMPT_C_INLINE size_t openmpt_stream_buffer_read_func( void * stream, void * dst, size_t bytes ) {
36 openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream;
37 int64_t offset = 0;
38 int64_t begpos = 0;
39 int64_t endpos = 0;
40 size_t valid_bytes = 0;
41 if ( !s ) {
42 return 0;
43 }
44 offset = bytes;
45 begpos = s->file_pos;
46 endpos = s->file_pos;
47 valid_bytes = 0;
48 endpos = (uint64_t)endpos + (uint64_t)offset;
49 if ( ( offset > 0 ) && !( (uint64_t)endpos > (uint64_t)begpos ) ) {
50 /* integer wrapped */
51 return 0;
52 }
53 if ( bytes == 0 ) {
54 return 0;
55 }
56 if ( begpos >= s->file_size ) {
57 return 0;
58 }
59 if ( endpos > s->file_size ) {
60 /* clip to eof */
61 bytes = bytes - (size_t)( endpos - s->file_size );
62 endpos = endpos - ( endpos - s->file_size );
63 }
64 memset( dst, 0, bytes );
65 if ( begpos >= s->prefix_size ) {
66 s->overflow = 1;
67 valid_bytes = 0;
68 } else if ( endpos > s->prefix_size ) {
69 s->overflow = 1;
70 valid_bytes = bytes - (size_t)( endpos - s->prefix_size );
71 } else {
72 valid_bytes = bytes;
73 }
74 memcpy( dst, (const char*)s->file_data + s->file_pos, valid_bytes );
75 s->file_pos = s->file_pos + bytes;
76 return bytes;
77}
78
79 static LIBOPENMPT_C_INLINE int openmpt_stream_buffer_seek_func( void * stream, int64_t offset, int whence ) {
80 openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream;
81 int result = -1;
82 if ( !s ) {
83 return -1;
84 }
85 switch ( whence ) {
86 case OPENMPT_STREAM_SEEK_SET:
87 if ( offset < 0 ) {
88 return -1;
89 }
90 if ( offset > s->file_size ) {
91 return -1;
92 }
93 s->file_pos = offset;
94 result = 0;
95 break;
96 case OPENMPT_STREAM_SEEK_CUR:
97 do {
98 int64_t oldpos = s->file_pos;
99 int64_t pos = s->file_pos;
100 pos = (uint64_t)pos + (uint64_t)offset;
101 if ( ( offset > 0 ) && !( (uint64_t)pos > (uint64_t)oldpos ) ) {
102 /* integer wrapped */
103 return -1;
104 }
105 if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
106 /* integer wrapped */
107 return -1;
108 }
109 s->file_pos = pos;
110 } while(0);
111 result = 0;
112 break;
113 case OPENMPT_STREAM_SEEK_END:
114 if ( offset > 0 ) {
115 return -1;
116 }
117 do {
118 int64_t oldpos = s->file_pos;
119 int64_t pos = s->file_pos;
120 pos = s->file_size;
121 pos = (uint64_t)pos + (uint64_t)offset;
122 if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
123 /* integer wrapped */
124 return -1;
125 }
126 s->file_pos = pos;
127 } while(0);
128 result = 0;
129 break;
130 }
131 return result;
132}
133
134 static LIBOPENMPT_C_INLINE int64_t openmpt_stream_buffer_tell_func( void * stream ) {
135 openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream;
136 if ( !s ) {
137 return -1;
138 }
139 return s->file_pos;
140}
141
142 LIBOPENMPT_DEPRECATED static LIBOPENMPT_C_INLINE void openmpt_stream_buffer_init( openmpt_stream_buffer * buffer, const void * file_data, int64_t file_size ) {
143 memset( buffer, 0, sizeof( openmpt_stream_buffer ) );
144 buffer->file_data = file_data;
145 buffer->file_size = file_size;
146 buffer->file_pos = 0;
147 buffer->prefix_size = file_size;
148 buffer->overflow = 0;
149}
150
151#define openmpt_stream_buffer_init_prefix_only( buffer_, prefix_data_, prefix_size_, file_size_ ) do { \
152 openmpt_stream_buffer_init( (buffer_), (prefix_data_), (file_size_) ); \
153 (buffer_)->prefix_size = (prefix_size_); \
154} while(0)
155
156#define openmpt_stream_buffer_overflowed( buffer_ ) ( (buffer_)->overflow )
157
172 LIBOPENMPT_DEPRECATED static LIBOPENMPT_C_INLINE openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks(void) {
173 openmpt_stream_callbacks retval;
174 memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
175 retval.read = openmpt_stream_buffer_read_func;
176 retval.seek = openmpt_stream_buffer_seek_func;
177 retval.tell = openmpt_stream_buffer_tell_func;
178 return retval;
179}
180
181 typedef struct openmpt_stream_buffer2 {
182 const void * file_data;
183 int64_t file_size;
184 int64_t file_pos;
185} openmpt_stream_buffer2;
186
187 static size_t openmpt_stream_buffer_read_func2( void * stream, void * dst, size_t bytes ) {
188 openmpt_stream_buffer2 * s = (openmpt_stream_buffer2*)stream;
189 int64_t offset = 0;
190 int64_t begpos = 0;
191 int64_t endpos = 0;
192 if ( !s ) {
193 return 0;
194 }
195 offset = bytes;
196 begpos = s->file_pos;
197 endpos = s->file_pos;
198 endpos = (uint64_t)endpos + (uint64_t)offset;
199 if ( ( offset > 0 ) && !( (uint64_t)endpos > (uint64_t)begpos ) ) {
200 /* integer wrapped */
201 return 0;
202 }
203 if ( bytes == 0 ) {
204 return 0;
205 }
206 if ( begpos >= s->file_size ) {
207 return 0;
208 }
209 if ( endpos > s->file_size ) {
210 /* clip to eof */
211 bytes = bytes - (size_t)( endpos - s->file_size );
212 endpos = endpos - ( endpos - s->file_size );
213 }
214 memcpy( dst, (const char*)s->file_data + s->file_pos, bytes );
215 s->file_pos = s->file_pos + bytes;
216 return bytes;
217}
218
219 static int openmpt_stream_buffer_seek_func2( void * stream, int64_t offset, int whence ) {
220 openmpt_stream_buffer2 * s = (openmpt_stream_buffer2*)stream;
221 int result = -1;
222 if ( !s ) {
223 return -1;
224 }
225 switch ( whence ) {
226 case OPENMPT_STREAM_SEEK_SET:
227 if ( offset < 0 ) {
228 return -1;
229 }
230 if ( offset > s->file_size ) {
231 return -1;
232 }
233 s->file_pos = offset;
234 result = 0;
235 break;
236 case OPENMPT_STREAM_SEEK_CUR:
237 do {
238 int64_t oldpos = s->file_pos;
239 int64_t pos = s->file_pos;
240 pos = (uint64_t)pos + (uint64_t)offset;
241 if ( ( offset > 0 ) && !( (uint64_t)pos > (uint64_t)oldpos ) ) {
242 /* integer wrapped */
243 return -1;
244 }
245 if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
246 /* integer wrapped */
247 return -1;
248 }
249 s->file_pos = pos;
250 } while(0);
251 result = 0;
252 break;
253 case OPENMPT_STREAM_SEEK_END:
254 if ( offset > 0 ) {
255 return -1;
256 }
257 do {
258 int64_t oldpos = s->file_pos;
259 int64_t pos = s->file_pos;
260 pos = s->file_size;
261 pos = (uint64_t)pos + (uint64_t)offset;
262 if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
263 /* integer wrapped */
264 return -1;
265 }
266 s->file_pos = pos;
267 } while(0);
268 result = 0;
269 break;
270 }
271 return result;
272}
273
274 static int64_t openmpt_stream_buffer_tell_func2( void * stream ) {
275 openmpt_stream_buffer2 * s = (openmpt_stream_buffer2*)stream;
276 if ( !s ) {
277 return -1;
278 }
279 return s->file_pos;
280}
281
282 static void openmpt_stream_buffer_init2( openmpt_stream_buffer2 * buffer, const void * file_data, int64_t file_size ) {
283 memset( buffer, 0, sizeof( openmpt_stream_buffer2 ) );
284 buffer->file_data = file_data;
285 buffer->file_size = file_size;
286 buffer->file_pos = 0;
287}
288
303 static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks2(void) {
304 openmpt_stream_callbacks retval;
305 memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
306 retval.read = openmpt_stream_buffer_read_func2;
307 retval.seek = openmpt_stream_buffer_seek_func2;
308 retval.tell = openmpt_stream_buffer_tell_func2;
309 return retval;
310}
311
312#ifdef __cplusplus
313}
314#endif
315
319
320#endif /* LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H */
openmpt_stream_get_buffer_callbacks2
static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks2(void)
Provide openmpt_stream_callbacks for in-memoy buffers.
Definition libopenmpt_stream_callbacks_buffer.h:303
OPENMPT_STREAM_SEEK_SET
#define OPENMPT_STREAM_SEEK_SET
Definition libopenmpt.h:253
OPENMPT_STREAM_SEEK_CUR
#define OPENMPT_STREAM_SEEK_CUR
Definition libopenmpt.h:255
openmpt_stream_buffer_seek_func2
static int openmpt_stream_buffer_seek_func2(void *stream, int64_t offset, int whence)
Definition libopenmpt_stream_callbacks_buffer.h:219
openmpt_stream_buffer_init
static void openmpt_stream_buffer_init(openmpt_stream_buffer *buffer, const void *file_data, int64_t file_size)
Definition libopenmpt_stream_callbacks_buffer.h:142
openmpt_stream_buffer_tell_func
static int64_t openmpt_stream_buffer_tell_func(void *stream)
Definition libopenmpt_stream_callbacks_buffer.h:134
openmpt_stream_get_buffer_callbacks
static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks(void)
Provide openmpt_stream_callbacks for in-memoy buffers.
Definition libopenmpt_stream_callbacks_buffer.h:172
OPENMPT_STREAM_SEEK_END
#define OPENMPT_STREAM_SEEK_END
Definition libopenmpt.h:257
openmpt_stream_buffer_init2
static void openmpt_stream_buffer_init2(openmpt_stream_buffer2 *buffer, const void *file_data, int64_t file_size)
Definition libopenmpt_stream_callbacks_buffer.h:282
openmpt_stream_buffer_seek_func
static int openmpt_stream_buffer_seek_func(void *stream, int64_t offset, int whence)
Definition libopenmpt_stream_callbacks_buffer.h:79
openmpt_stream_buffer_read_func2
static size_t openmpt_stream_buffer_read_func2(void *stream, void *dst, size_t bytes)
Definition libopenmpt_stream_callbacks_buffer.h:187
openmpt_stream_buffer_read_func
static size_t openmpt_stream_buffer_read_func(void *stream, void *dst, size_t bytes)
Definition libopenmpt_stream_callbacks_buffer.h:35
openmpt_stream_buffer_tell_func2
static int64_t openmpt_stream_buffer_tell_func2(void *stream)
Definition libopenmpt_stream_callbacks_buffer.h:274
libopenmpt.h
LIBOPENMPT_DEPRECATED
#define LIBOPENMPT_DEPRECATED
Definition libopenmpt_config.h:315
LIBOPENMPT_C_INLINE
#define LIBOPENMPT_C_INLINE
Definition libopenmpt_config.h:339
openmpt_stream_buffer2
Definition libopenmpt_stream_callbacks_buffer.h:181
openmpt_stream_buffer2::file_size
int64_t file_size
Definition libopenmpt_stream_callbacks_buffer.h:183
openmpt_stream_buffer2::file_data
const void * file_data
Definition libopenmpt_stream_callbacks_buffer.h:182
openmpt_stream_buffer2::file_pos
int64_t file_pos
Definition libopenmpt_stream_callbacks_buffer.h:184
openmpt_stream_buffer
Definition libopenmpt_stream_callbacks_buffer.h:27
openmpt_stream_buffer::prefix_size
int64_t prefix_size
Definition libopenmpt_stream_callbacks_buffer.h:31
openmpt_stream_buffer::file_size
int64_t file_size
Definition libopenmpt_stream_callbacks_buffer.h:29
openmpt_stream_buffer::overflow
int overflow
Definition libopenmpt_stream_callbacks_buffer.h:32
openmpt_stream_buffer::file_pos
int64_t file_pos
Definition libopenmpt_stream_callbacks_buffer.h:30
openmpt_stream_buffer::file_data
const void * file_data
Definition libopenmpt_stream_callbacks_buffer.h:28
openmpt_stream_callbacks
Stream callbacks.
Definition libopenmpt.h:300
openmpt_stream_callbacks::read
openmpt_stream_read_func read
Read callback.
Definition libopenmpt.h:306
openmpt_stream_callbacks::seek
openmpt_stream_seek_func seek
Seek callback.
Definition libopenmpt.h:313
openmpt_stream_callbacks::tell
openmpt_stream_tell_func tell
Tell callback.
Definition libopenmpt.h:320