libopenmpt: libopenmpt/libopenmpt_stream_callbacks_buffer.h Source File

libopenmpt 0.4.53-pre.0+r25032 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;
44 } openmpt_stream_buffer;
45
46 static size_t openmpt_stream_buffer_read_func( void * stream, void * dst, size_t bytes ) {
47 openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream;
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 ) {
91 openmpt_stream_buffer * s = (openmpt_stream_buffer*)stream;
92 int result = -1;
93 if ( !s ) {
94 return -1;
95 }
96 switch ( whence ) {
97 case OPENMPT_STREAM_SEEK_SET:
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;
107 case OPENMPT_STREAM_SEEK_CUR:
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;
124 case OPENMPT_STREAM_SEEK_END:
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 ) {
146 openmpt_stream_buffer * s = (openmpt_stream_buffer*)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
180 static openmpt_stream_callbacks openmpt_stream_get_buffer_callbacks(void) {
181 openmpt_stream_callbacks retval;
182 memset( &retval, 0, sizeof( openmpt_stream_callbacks ) );
183 retval.read = openmpt_stream_buffer_read_func;
184 retval.seek = openmpt_stream_buffer_seek_func;
185 retval.tell = openmpt_stream_buffer_tell_func;
186 return retval;
187 }
188
189 #ifdef __cplusplus
190 }
191 #endif
192
197 #endif /* LIBOPENMPT_STREAM_CALLBACKS_BUFFER_H */
198
openmpt_stream_buffer::prefix_size
int64_t prefix_size
Definition: libopenmpt_stream_callbacks_buffer.h:42
openmpt_stream_buffer
struct openmpt_stream_buffer openmpt_stream_buffer
openmpt_stream_buffer::file_pos
int64_t file_pos
Definition: libopenmpt_stream_callbacks_buffer.h:41
OPENMPT_STREAM_SEEK_CUR
#define OPENMPT_STREAM_SEEK_CUR
Definition: libopenmpt.h:255
OPENMPT_STREAM_SEEK_SET
#define OPENMPT_STREAM_SEEK_SET
Definition: libopenmpt.h:253
libopenmpt.h
openmpt_stream_callbacks::tell
openmpt_stream_tell_func tell
Tell callback.
Definition: libopenmpt.h:320
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:90
OPENMPT_STREAM_SEEK_END
#define OPENMPT_STREAM_SEEK_END
Definition: libopenmpt.h:257
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:153
openmpt_stream_buffer::file_size
int64_t file_size
Definition: libopenmpt_stream_callbacks_buffer.h:40
openmpt_stream_callbacks
Stream callbacks.
Definition: libopenmpt.h:300
openmpt_stream_buffer::overflow
int overflow
Definition: libopenmpt_stream_callbacks_buffer.h:43
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:180
openmpt_stream_callbacks::read
openmpt_stream_read_func read
Read callback.
Definition: libopenmpt.h:306
openmpt_stream_buffer_tell_func
static int64_t openmpt_stream_buffer_tell_func(void *stream)
Definition: libopenmpt_stream_callbacks_buffer.h:145
openmpt_stream_buffer::file_data
const void * file_data
Definition: libopenmpt_stream_callbacks_buffer.h:39
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:46
openmpt_stream_callbacks::seek
openmpt_stream_seek_func seek
Seek callback.
Definition: libopenmpt.h:313
openmpt_stream_buffer
Definition: libopenmpt_stream_callbacks_buffer.h:38