libopenmpt  0.4.10+release
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 /* The use of this header requires:
16 
17 #include <libopenmpt/libopenmpt.h>
18 #if defined( LIBOPENMPT_STREAM_CALLBACKS_BUFFER )
19 #include <libopenmpt/libopenmpt_stream_callbacks_buffer.h>
20 #else
21 #error "libopenmpt too old."
22 #endif
23 
24 */
25 
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 typedef struct openmpt_stream_buffer {
39  const void * file_data; /* or prefix data IFF prefix_size < file_size */
40  int64_t file_size;
41  int64_t file_pos;
42  int64_t prefix_size;
43  int overflow;
45 
46 static size_t openmpt_stream_buffer_read_func( void * stream, void * dst, size_t bytes ) {
48  int64_t offset = 0;
49  int64_t begpos = 0;
50  int64_t endpos = 0;
51  size_t valid_bytes = 0;
52  if ( !s ) {
53  return 0;
54  }
55  offset = bytes;
56  begpos = s->file_pos;
57  endpos = s->file_pos;
58  valid_bytes = 0;
59  endpos = (uint64_t)endpos + (uint64_t)offset;
60  if ( ( offset > 0 ) && !( (uint64_t)endpos > (uint64_t)begpos ) ) {
61  /* integer wrapped */
62  return 0;
63  }
64  if ( bytes == 0 ) {
65  return 0;
66  }
67  if ( begpos >= s->file_size ) {
68  return 0;
69  }
70  if ( endpos > s->file_size ) {
71  /* clip to eof */
72  bytes = bytes - (size_t)( endpos - s->file_size );
73  endpos = endpos - ( endpos - s->file_size );
74  }
75  memset( dst, 0, bytes );
76  if ( begpos >= s->prefix_size ) {
77  s->overflow = 1;
78  valid_bytes = 0;
79  } else if ( endpos > s->prefix_size ) {
80  s->overflow = 1;
81  valid_bytes = bytes - (size_t)( endpos - s->prefix_size );
82  } else {
83  valid_bytes = bytes;
84  }
85  memcpy( dst, (const char*)s->file_data + s->file_pos, valid_bytes );
86  s->file_pos = s->file_pos + bytes;
87  return bytes;
88 }
89 
90 static int openmpt_stream_buffer_seek_func( void * stream, int64_t offset, int whence ) {
92  int result = -1;
93  if ( !s ) {
94  return -1;
95  }
96  switch ( whence ) {
98  if ( offset < 0 ) {
99  return -1;
100  }
101  if ( offset > s->file_size ) {
102  return -1;
103  }
104  s->file_pos = offset;
105  result = 0;
106  break;
108  do {
109  int64_t oldpos = s->file_pos;
110  int64_t pos = s->file_pos;
111  pos = (uint64_t)pos + (uint64_t)offset;
112  if ( ( offset > 0 ) && !( (uint64_t)pos > (uint64_t)oldpos ) ) {
113  /* integer wrapped */
114  return -1;
115  }
116  if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
117  /* integer wrapped */
118  return -1;
119  }
120  s->file_pos = pos;
121  } while(0);
122  result = 0;
123  break;
125  if ( offset > 0 ) {
126  return -1;
127  }
128  do {
129  int64_t oldpos = s->file_pos;
130  int64_t pos = s->file_pos;
131  pos = s->file_size;
132  pos = (uint64_t)pos + (uint64_t)offset;
133  if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
134  /* integer wrapped */
135  return -1;
136  }
137  s->file_pos = pos;
138  } while(0);
139  result = 0;
140  break;
141  }
142  return result;
143 }
144 
145 static int64_t openmpt_stream_buffer_tell_func( void * stream ) {
147  if ( !s ) {
148  return -1;
149  }
150  return s->file_pos;
151 }
152 
153 static void openmpt_stream_buffer_init( openmpt_stream_buffer * buffer, const void * file_data, int64_t file_size ) {
154  memset( buffer, 0, sizeof( openmpt_stream_buffer ) );
155  buffer->file_data = file_data;
156  buffer->file_size = file_size;
157  buffer->file_pos = 0;
158  buffer->prefix_size = file_size;
159  buffer->overflow = 0;
160 }
161 
162 #define openmpt_stream_buffer_init_prefix_only( buffer_, prefix_data_, prefix_size_, file_size_ ) do { \
163  openmpt_stream_buffer_init( (buffer_), (prefix_data_), (file_size_) ); \
164  (buffer_)->prefix_size = (prefix_size_); \
165 } while(0)
166 
167 #define openmpt_stream_buffer_overflowed( buffer_ ) ( (buffer_)->overflow )
168 
182  memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
186  return retval;
187 }
188 
189 #ifdef __cplusplus
190 }
191 #endif
192 
197 #endif /* LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H */
198 
int64_t prefix_size
Definition: libopenmpt_stream_callbacks_buffer.h:42
struct openmpt_stream_buffer openmpt_stream_buffer
int64_t file_pos
Definition: libopenmpt_stream_callbacks_buffer.h:41
#define OPENMPT_STREAM_SEEK_CUR
Definition: libopenmpt.h:255
#define OPENMPT_STREAM_SEEK_SET
Definition: libopenmpt.h:253
openmpt_stream_tell_func tell
Tell callback.
Definition: libopenmpt.h:320
static int openmpt_stream_buffer_seek_func(void *stream, int64_t offset, int whence)
Definition: libopenmpt_stream_callbacks_buffer.h:90
#define OPENMPT_STREAM_SEEK_END
Definition: libopenmpt.h:257
static void openmpt_stream_buffer_init(openmpt_stream_buffer *buffer, const void *file_data, int64_t file_size)
Definition: libopenmpt_stream_callbacks_buffer.h:153
int64_t file_size
Definition: libopenmpt_stream_callbacks_buffer.h:40
Stream callbacks.
Definition: libopenmpt.h:300
int overflow
Definition: libopenmpt_stream_callbacks_buffer.h:43
static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks(void)
Provide openmpt_stream_callbacks for in-memoy buffers.
Definition: libopenmpt_stream_callbacks_buffer.h:180
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:145
const void * file_data
Definition: libopenmpt_stream_callbacks_buffer.h:39
static size_t openmpt_stream_buffer_read_func(void *stream, void *dst, size_t bytes)
Definition: libopenmpt_stream_callbacks_buffer.h:46
openmpt_stream_seek_func seek
Seek callback.
Definition: libopenmpt.h:313
Definition: libopenmpt_stream_callbacks_buffer.h:38