libopenmpt 0.8.0-pre.12+r22603
cross-platform C++ and C library to decode tracked music files
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
23#ifdef __cplusplus
24extern "C" {
25#endif
26
27typedef 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;
34
35static LIBOPENMPT_C_INLINE size_t openmpt_stream_buffer_read_func( void * stream, void * dst, size_t bytes ) {
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
79static LIBOPENMPT_C_INLINE int openmpt_stream_buffer_seek_func( void * stream, int64_t offset, int whence ) {
81 int result = -1;
82 if ( !s ) {
83 return -1;
84 }
85 switch ( whence ) {
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;
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;
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
136 if ( !s ) {
137 return -1;
138 }
139 return s->file_pos;
140}
141
142LIBOPENMPT_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
174 memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
178 return retval;
179}
180
182 const void * file_data;
183 int64_t file_size;
184 int64_t file_pos;
186
187static size_t openmpt_stream_buffer_read_func2( void * stream, void * dst, size_t bytes ) {
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
219static int openmpt_stream_buffer_seek_func2( void * stream, int64_t offset, int whence ) {
221 int result = -1;
222 if ( !s ) {
223 return -1;
224 }
225 switch ( whence ) {
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;
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;
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
274static int64_t openmpt_stream_buffer_tell_func2( void * stream ) {
276 if ( !s ) {
277 return -1;
278 }
279 return s->file_pos;
280}
281
282static 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
305 memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
309 return retval;
310}
311
312#ifdef __cplusplus
313}
314#endif
315
320#endif /* LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H */
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
#define OPENMPT_STREAM_SEEK_SET
Definition: libopenmpt.h:253
#define OPENMPT_STREAM_SEEK_CUR
Definition: libopenmpt.h:255
static int openmpt_stream_buffer_seek_func2(void *stream, int64_t offset, int whence)
Definition: libopenmpt_stream_callbacks_buffer.h:219
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
struct openmpt_stream_buffer openmpt_stream_buffer
struct openmpt_stream_buffer2 openmpt_stream_buffer2
static int64_t openmpt_stream_buffer_tell_func(void *stream)
Definition: libopenmpt_stream_callbacks_buffer.h:134
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
#define OPENMPT_STREAM_SEEK_END
Definition: libopenmpt.h:257
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
static int openmpt_stream_buffer_seek_func(void *stream, int64_t offset, int whence)
Definition: libopenmpt_stream_callbacks_buffer.h:79
static size_t openmpt_stream_buffer_read_func2(void *stream, void *dst, size_t bytes)
Definition: libopenmpt_stream_callbacks_buffer.h:187
static size_t openmpt_stream_buffer_read_func(void *stream, void *dst, size_t bytes)
Definition: libopenmpt_stream_callbacks_buffer.h:35
static int64_t openmpt_stream_buffer_tell_func2(void *stream)
Definition: libopenmpt_stream_callbacks_buffer.h:274
#define LIBOPENMPT_DEPRECATED
Definition: libopenmpt_config.h:315
#define LIBOPENMPT_C_INLINE
Definition: libopenmpt_config.h:339
Definition: libopenmpt_stream_callbacks_buffer.h:181
int64_t file_size
Definition: libopenmpt_stream_callbacks_buffer.h:183
const void * file_data
Definition: libopenmpt_stream_callbacks_buffer.h:182
int64_t file_pos
Definition: libopenmpt_stream_callbacks_buffer.h:184
Definition: libopenmpt_stream_callbacks_buffer.h:27
int64_t prefix_size
Definition: libopenmpt_stream_callbacks_buffer.h:31
int64_t file_size
Definition: libopenmpt_stream_callbacks_buffer.h:29
int overflow
Definition: libopenmpt_stream_callbacks_buffer.h:32
int64_t file_pos
Definition: libopenmpt_stream_callbacks_buffer.h:30
const void * file_data
Definition: libopenmpt_stream_callbacks_buffer.h:28
Stream callbacks.
Definition: libopenmpt.h:300
openmpt_stream_read_func read
Read callback.
Definition: libopenmpt.h:306
openmpt_stream_seek_func seek
Seek callback.
Definition: libopenmpt.h:313
openmpt_stream_tell_func tell
Tell callback.
Definition: libopenmpt.h:320