libopenmpt  0.7.6+release.autotools
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
24 extern "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;
34 
35 static 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 
79 static 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 
134 static LIBOPENMPT_C_INLINE int64_t openmpt_stream_buffer_tell_func( void * 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 
174  memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
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;
186 
187 static 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 
219 static 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 
274 static int64_t openmpt_stream_buffer_tell_func2( void * 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 
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 */
int64_t prefix_size
Definition: libopenmpt_stream_callbacks_buffer.h:31
int64_t file_size
Definition: libopenmpt_stream_callbacks_buffer.h:183
struct openmpt_stream_buffer openmpt_stream_buffer
struct openmpt_stream_buffer2 openmpt_stream_buffer2
#define LIBOPENMPT_DEPRECATED
Definition: libopenmpt_config.h:315
int64_t file_pos
Definition: libopenmpt_stream_callbacks_buffer.h:30
static size_t openmpt_stream_buffer_read_func2(void *stream, void *dst, size_t bytes)
Definition: libopenmpt_stream_callbacks_buffer.h:187
#define OPENMPT_STREAM_SEEK_CUR
Definition: libopenmpt.h:255
#define OPENMPT_STREAM_SEEK_SET
Definition: libopenmpt.h:253
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
static int64_t openmpt_stream_buffer_tell_func2(void *stream)
Definition: libopenmpt_stream_callbacks_buffer.h:274
const void * file_data
Definition: libopenmpt_stream_callbacks_buffer.h:182
openmpt_stream_tell_func tell
Tell callback.
Definition: libopenmpt.h:320
static int openmpt_stream_buffer_seek_func2(void *stream, int64_t offset, int whence)
Definition: libopenmpt_stream_callbacks_buffer.h:219
static int openmpt_stream_buffer_seek_func(void *stream, int64_t offset, int whence)
Definition: libopenmpt_stream_callbacks_buffer.h:79
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
#define OPENMPT_STREAM_SEEK_END
Definition: libopenmpt.h:257
#define LIBOPENMPT_C_INLINE
Definition: libopenmpt_config.h:339
Definition: libopenmpt_stream_callbacks_buffer.h:181
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
int64_t file_size
Definition: libopenmpt_stream_callbacks_buffer.h:29
Stream callbacks.
Definition: libopenmpt.h:300
int overflow
Definition: libopenmpt_stream_callbacks_buffer.h:32
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_read_func read
Read callback.
Definition: libopenmpt.h:306
static int64_t openmpt_stream_buffer_tell_func(void *stream)
Definition: libopenmpt_stream_callbacks_buffer.h:134
const void * file_data
Definition: libopenmpt_stream_callbacks_buffer.h:28
static size_t openmpt_stream_buffer_read_func(void *stream, void *dst, size_t bytes)
Definition: libopenmpt_stream_callbacks_buffer.h:35
int64_t file_pos
Definition: libopenmpt_stream_callbacks_buffer.h:184
openmpt_stream_seek_func seek
Seek callback.
Definition: libopenmpt.h:313
Definition: libopenmpt_stream_callbacks_buffer.h:27