libopenmpt  0.3.1+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 /* 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 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 typedef struct openmpt_stream_buffer {
35  const void * file_data; /* or prefix data IFF prefix_size < file_size */
36  int64_t file_size;
37  int64_t file_pos;
38  int64_t prefix_size;
39  int overflow;
41 
42 static size_t openmpt_stream_buffer_read_func( void * stream, void * dst, size_t bytes ) {
44  int64_t offset = 0;
45  int64_t begpos = 0;
46  int64_t endpos = 0;
47  size_t valid_bytes = 0;
48  if ( !s ) {
49  return 0;
50  }
51  offset = bytes;
52  begpos = s->file_pos;
53  endpos = s->file_pos;
54  valid_bytes = 0;
55  endpos = (uint64_t)endpos + (uint64_t)offset;
56  if ( ( offset > 0 ) && !( (uint64_t)endpos > (uint64_t)begpos ) ) {
57  /* integer wrapped */
58  return 0;
59  }
60  if ( bytes == 0 ) {
61  return 0;
62  }
63  if ( begpos >= s->file_size ) {
64  return 0;
65  }
66  if ( endpos > s->file_size ) {
67  /* clip to eof */
68  bytes = bytes - (size_t)( endpos - s->file_size );
69  endpos = endpos - ( endpos - s->file_size );
70  }
71  memset( dst, 0, bytes );
72  if ( begpos >= s->prefix_size ) {
73  s->overflow = 1;
74  valid_bytes = 0;
75  } else if ( endpos > s->prefix_size ) {
76  s->overflow = 1;
77  valid_bytes = bytes - (size_t)( endpos - s->prefix_size );
78  } else {
79  valid_bytes = bytes;
80  }
81  memcpy( dst, (const char*)s->file_data + s->file_pos, valid_bytes );
82  s->file_pos = s->file_pos + bytes;
83  return bytes;
84 }
85 
86 static int openmpt_stream_buffer_seek_func( void * stream, int64_t offset, int whence ) {
88  int result = -1;
89  if ( !s ) {
90  return -1;
91  }
92  switch ( whence ) {
94  if ( offset < 0 ) {
95  return -1;
96  }
97  if ( offset > s->file_size ) {
98  return -1;
99  }
100  s->file_pos = offset;
101  result = 0;
102  break;
104  do {
105  int64_t oldpos = s->file_pos;
106  int64_t pos = s->file_pos;
107  pos = (uint64_t)pos + (uint64_t)offset;
108  if ( ( offset > 0 ) && !( (uint64_t)pos > (uint64_t)oldpos ) ) {
109  /* integer wrapped */
110  return -1;
111  }
112  if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
113  /* integer wrapped */
114  return -1;
115  }
116  s->file_pos = pos;
117  } while(0);
118  result = 0;
119  break;
121  if ( offset > 0 ) {
122  return -1;
123  }
124  do {
125  int64_t oldpos = s->file_pos;
126  int64_t pos = s->file_pos;
127  pos = s->file_size;
128  pos = (uint64_t)pos + (uint64_t)offset;
129  if ( ( offset < 0 ) && !( (uint64_t)pos < (uint64_t)oldpos ) ) {
130  /* integer wrapped */
131  return -1;
132  }
133  s->file_pos = pos;
134  } while(0);
135  result = 0;
136  break;
137  }
138  return result;
139 }
140 
141 static int64_t openmpt_stream_buffer_tell_func( void * stream ) {
143  if ( !s ) {
144  return -1;
145  }
146  return s->file_pos;
147 }
148 
149 static void openmpt_stream_buffer_init( openmpt_stream_buffer * buffer, const void * file_data, int64_t file_size ) {
150  memset( buffer, 0, sizeof( openmpt_stream_buffer ) );
151  buffer->file_data = file_data;
152  buffer->file_size = file_size;
153  buffer->file_pos = 0;
154  buffer->prefix_size = file_size;
155  buffer->overflow = 0;
156 }
157 
158 #define openmpt_stream_buffer_init_prefix_only( buffer_, prefix_data_, prefix_size_, file_size_ ) do { \
159  openmpt_stream_buffer_init( (buffer_), (prefix_data_), (file_size_) ); \
160  (buffer_)->prefix_size = (prefix_size_); \
161 } while(0)
162 
163 #define openmpt_stream_buffer_overflowed( buffer_ ) ( (buffer_)->overflow )
164 
167  memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
171  return retval;
172 }
173 
174 #ifdef __cplusplus
175 }
176 #endif
177 
178 #endif /* LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H */
179 
int64_t prefix_size
Definition: libopenmpt_stream_callbacks_buffer.h:38
int64_t file_pos
Definition: libopenmpt_stream_callbacks_buffer.h:37
#define OPENMPT_STREAM_SEEK_CUR
Definition: libopenmpt.h:223
#define OPENMPT_STREAM_SEEK_SET
Definition: libopenmpt.h:221
static void openmpt_stream_buffer_init(openmpt_stream_buffer *buffer, const void *file_data, int64_t file_size)
Definition: libopenmpt_stream_callbacks_buffer.h:149
openmpt_stream_tell_func tell
Tell callback.
Definition: libopenmpt.h:285
#define OPENMPT_STREAM_SEEK_END
Definition: libopenmpt.h:225
int64_t file_size
Definition: libopenmpt_stream_callbacks_buffer.h:36
Stream callbacks.
Definition: libopenmpt.h:265
int overflow
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:42
static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks(void)
Definition: libopenmpt_stream_callbacks_buffer.h:165
static int openmpt_stream_buffer_seek_func(void *stream, int64_t offset, int whence)
Definition: libopenmpt_stream_callbacks_buffer.h:86
openmpt_stream_read_func read
Read callback.
Definition: libopenmpt.h:271
struct openmpt_stream_buffer openmpt_stream_buffer
static int64_t openmpt_stream_buffer_tell_func(void *stream)
Definition: libopenmpt_stream_callbacks_buffer.h:141
const void * file_data
Definition: libopenmpt_stream_callbacks_buffer.h:35
openmpt_stream_seek_func seek
Seek callback.
Definition: libopenmpt.h:278
Definition: libopenmpt_stream_callbacks_buffer.h:34