]> git.sesse.net Git - vlc/blob - include/vlc_block_helper.h
* include/vlc_block_helper.h, modules/codec/a52.c: same as thedj ;)
[vlc] / include / vlc_block_helper.h
1 /*****************************************************************************
2  * vlc_block_helper.h: Helper functions for data blocks management.
3  *****************************************************************************
4  * Copyright (C) 2003 VideoLAN
5  * $Id: vlc_block_helper.h,v 1.2 2003/09/30 20:36:46 gbazin Exp $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #ifndef _VLC_BLOCK_HELPER_H
25 #define _VLC_BLOCK_HELPER_H 1
26
27 typedef struct block_bytestream_t
28 {
29     block_t             *p_chain;
30     block_t             *p_block;
31     int                 i_offset;
32 } block_bytestream_t;
33
34 #define block_BytestreamInit( a, b, c ) __block_BytestreamInit( VLC_OBJECT(a), b, c )
35
36 /*****************************************************************************
37  * block_bytestream_t management
38  *****************************************************************************/
39 static inline block_bytestream_t __block_BytestreamInit( vlc_object_t *p_obj,
40                                            block_t *p_block, int i_offset )
41 {
42     block_bytestream_t bytestream;
43
44     bytestream.i_offset = i_offset;
45     bytestream.p_block = p_block;
46     bytestream.p_chain = p_block;
47
48     return bytestream;
49 }
50
51 static inline block_t *block_BytestreamFlush( block_bytestream_t *p_bytestream)
52 {
53     while( p_bytestream->p_chain != p_bytestream->p_block )
54     {
55         block_t *p_next;
56         p_next = p_bytestream->p_chain->p_next;
57         p_bytestream->p_chain->pf_release( p_bytestream->p_chain );
58         p_bytestream->p_chain = p_next;
59     }
60
61     return p_bytestream->p_chain;
62 }
63
64 static inline int block_SkipByte( block_bytestream_t *p_bytestream )
65 {
66     /* Most common case first */
67     if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset )
68     {
69         p_bytestream->i_offset++;
70         return VLC_SUCCESS;
71     }
72     else
73     {
74         block_t *p_block;
75
76         /* Less common case which is also slower */
77         for( p_block = p_bytestream->p_block->p_next;
78              p_block != NULL; p_block = p_block->p_next )
79         {
80             if( p_block->i_buffer )
81             {
82                 p_bytestream->i_offset = 1;
83                 p_bytestream->p_block = p_block;
84                 return VLC_SUCCESS;
85             }
86         }
87     }
88
89     /* Not enough data, bail out */
90     return VLC_EGENERIC;
91 }
92
93 static inline int block_PeekByte( block_bytestream_t *p_bytestream,
94                                   uint8_t *p_data )
95 {
96     /* Most common case first */
97     if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset )
98     {
99         *p_data = p_bytestream->p_block->p_buffer[p_bytestream->i_offset];
100         return VLC_SUCCESS;
101     }
102     else
103     {
104         block_t *p_block;
105
106         /* Less common case which is also slower */
107         for( p_block = p_bytestream->p_block->p_next;
108              p_block != NULL; p_block = p_block->p_next )
109         {
110             if( p_block->i_buffer )
111             {
112                 *p_data = p_block->p_buffer[0];
113                 return VLC_SUCCESS;
114             }
115         }
116     }
117
118     /* Not enough data, bail out */
119     return VLC_EGENERIC;
120 }
121
122 static inline int block_GetByte( block_bytestream_t *p_bytestream,
123                                  uint8_t *p_data )
124 {
125     /* Most common case first */
126     if( p_bytestream->p_block->i_buffer - p_bytestream->i_offset )
127     {
128         *p_data = p_bytestream->p_block->p_buffer[p_bytestream->i_offset];
129         p_bytestream->i_offset++;
130         return VLC_SUCCESS;
131     }
132     else
133     {
134         block_t *p_block;
135
136         /* Less common case which is also slower */
137         for( p_block = p_bytestream->p_block->p_next;
138              p_block != NULL; p_block = p_block->p_next )
139         {
140             if( p_block->i_buffer )
141             {
142                 *p_data = p_block->p_buffer[0];
143                 p_bytestream->i_offset = 1;
144                 p_bytestream->p_block = p_block;
145                 return VLC_SUCCESS;
146             }
147         }
148     }
149
150     /* Not enough data, bail out */
151     return VLC_EGENERIC;
152 }
153
154 static inline int block_SkipBytes( block_bytestream_t *p_bytestream,
155                                    int i_data )
156 {
157     block_t *p_block;
158     int i_offset, i_copy;
159
160     /* Check we have that much data */
161     i_offset = p_bytestream->i_offset;
162     i_copy = 0;
163     for( p_block = p_bytestream->p_block;
164          p_block != NULL; p_block = p_block->p_next )
165     {
166         i_copy = __MIN( i_data, p_block->i_buffer - i_offset );
167         i_data -= i_copy;
168         i_offset = 0;
169
170         if( !i_data ) break;
171     }
172
173     if( i_data )
174     {
175         /* Not enough data, bail out */
176         return VLC_EGENERIC;
177     }
178
179     p_bytestream->p_block = p_block;
180     p_bytestream->i_offset = i_copy;
181     return VLC_SUCCESS;
182 }
183
184 static inline int block_PeekBytes( block_bytestream_t *p_bytestream,
185                                    uint8_t *p_data, int i_data )
186 {
187     block_t *p_block;
188     int i_offset, i_copy, i_size;
189
190     /* Check we have that much data */
191     i_offset = p_bytestream->i_offset;
192     i_size = i_data;
193     i_copy = 0;
194     for( p_block = p_bytestream->p_block;
195          p_block != NULL; p_block = p_block->p_next )
196     {
197         i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
198         i_size -= i_copy;
199         i_offset = 0;
200
201         if( !i_size ) break;
202     }
203
204     if( i_size )
205     {
206         /* Not enough data, bail out */
207         return VLC_EGENERIC;
208     }
209
210     /* Copy the data */
211     i_offset = p_bytestream->i_offset;
212     i_size = i_data;
213     i_copy = 0;
214     for( p_block = p_bytestream->p_block;
215          p_block != NULL; p_block = p_block->p_next )
216     {
217         i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
218         i_size -= i_copy;
219
220         if( i_copy )
221         {
222             memcpy( p_data, p_block->p_buffer + i_offset, i_copy );
223             p_data += i_copy;
224         }
225
226         i_offset = 0;
227
228         if( !i_size ) break;
229     }
230
231     return VLC_SUCCESS;
232 }
233
234 static inline int block_GetBytes( block_bytestream_t *p_bytestream,
235                                   uint8_t *p_data, int i_data )
236 {
237     block_t *p_block;
238     int i_offset, i_copy, i_size;
239
240     /* Check we have that much data */
241     i_offset = p_bytestream->i_offset;
242     i_size = i_data;
243     i_copy = 0;
244     for( p_block = p_bytestream->p_block;
245          p_block != NULL; p_block = p_block->p_next )
246     {
247         i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
248         i_size -= i_copy;
249         i_offset = 0;
250
251         if( !i_size ) break;
252     }
253
254     if( i_size )
255     {
256         /* Not enough data, bail out */
257         return VLC_EGENERIC;
258     }
259
260     /* Copy the data */
261     i_offset = p_bytestream->i_offset;
262     i_size = i_data;
263     i_copy = 0;
264     for( p_block = p_bytestream->p_block;
265          p_block != NULL; p_block = p_block->p_next )
266     {
267         i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
268         i_size -= i_copy;
269
270         if( i_copy )
271         {
272             memcpy( p_data, p_block->p_buffer + i_offset, i_copy );
273             p_data += i_copy;
274         }
275
276         i_offset = 0;
277
278         if( !i_size ) break;
279     }
280
281     /* No buffer given, just skip the data */
282     p_bytestream->p_block = p_block;
283     p_bytestream->i_offset = i_copy;
284
285     return VLC_SUCCESS;
286 }
287
288 static inline int block_PeekOffsetBytes( block_bytestream_t *p_bytestream,
289     int i_peek_offset, uint8_t *p_data, int i_data )
290 {
291     block_t *p_block;
292     int i_offset, i_copy, i_size;
293
294     /* Check we have that much data */
295     i_offset = p_bytestream->i_offset;
296     i_size = i_data + i_peek_offset;
297     i_copy = 0;
298     for( p_block = p_bytestream->p_block;
299          p_block != NULL; p_block = p_block->p_next )
300     {
301         i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
302         i_size -= i_copy;
303         i_offset = 0;
304
305         if( !i_size ) break;
306     }
307
308     if( i_size )
309     {
310         /* Not enough data, bail out */
311         return VLC_EGENERIC;
312     }
313
314     /* Find the right place */
315     i_offset = p_bytestream->i_offset;
316     i_size = i_peek_offset;
317     i_copy = 0;
318     for( p_block = p_bytestream->p_block;
319          p_block != NULL; p_block = p_block->p_next )
320     {
321         i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
322         i_size -= i_copy;
323         i_offset = 0;
324
325         if( !i_size ) break;
326     }
327
328     /* Copy the data */
329     i_offset = i_copy;
330     i_size = i_data;
331     i_copy = 0;
332     for( ; p_block != NULL; p_block = p_block->p_next )
333     {
334         i_copy = __MIN( i_size, p_block->i_buffer - i_offset );
335         i_size -= i_copy;
336
337         if( i_copy )
338         {
339             memcpy( p_data, p_block->p_buffer + i_offset, i_copy );
340             p_data += i_copy;
341         }
342
343         i_offset = 0;
344
345         if( !i_size ) break;
346     }
347
348     return VLC_SUCCESS;
349 }
350
351 #endif /* VLC_BLOCK_HELPER_H */