1 /* GStreamer byte reader
2 *
3 * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
4 * Copyright (C) 2009 Tim-Philipp Müller <tim centricular net>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #ifndef __GST_BYTE_READER_H__
23 #define __GST_BYTE_READER_H__
24
25 #include <gst/gst.h>
26 #include <gst/base/base-prelude.h>
27
28 G_BEGIN_DECLS
29
30 #define GST_BYTE_READER(reader) ((GstByteReader *) (reader))
31
32 /**
33 * GstByteReader:
34 * @data: (array length=size): Data from which the bit reader will
35 * read
36 * @size: Size of @data in bytes
37 * @byte: Current byte position
38 *
39 * A byte reader instance.
40 */
41 typedef struct {
42 const guint8 *data;
43 guint size;
44
45 guint byte; /* Byte position */
46
47 /* < private > */
48 gpointer _gst_reserved[GST_PADDING];
49 } GstByteReader;
50
51 GST_BASE_API
52 GstByteReader * gst_byte_reader_new (const guint8 *data, guint size) G_GNUC_MALLOC;
53
54 GST_BASE_API
55 void gst_byte_reader_free (GstByteReader *reader);
56
57 GST_BASE_API
58 void gst_byte_reader_init (GstByteReader *reader, const guint8 *data, guint size);
59
60 GST_BASE_API
61 gboolean gst_byte_reader_peek_sub_reader (GstByteReader * reader,
62 GstByteReader * sub_reader,
63 guint size);
64 GST_BASE_API
65 gboolean gst_byte_reader_get_sub_reader (GstByteReader * reader,
66 GstByteReader * sub_reader,
67 guint size);
68 GST_BASE_API
69 gboolean gst_byte_reader_set_pos (GstByteReader *reader, guint pos);
70
71 GST_BASE_API
72 guint gst_byte_reader_get_pos (const GstByteReader *reader);
73
74 GST_BASE_API
75 guint gst_byte_reader_get_remaining (const GstByteReader *reader);
76
77 GST_BASE_API
78 guint gst_byte_reader_get_size (const GstByteReader *reader);
79
80 GST_BASE_API
81 gboolean gst_byte_reader_skip (GstByteReader *reader, guint nbytes);
82
83 GST_BASE_API
84 gboolean gst_byte_reader_get_uint8 (GstByteReader *reader, guint8 *val);
85
86 GST_BASE_API
87 gboolean gst_byte_reader_get_int8 (GstByteReader *reader, gint8 *val);
88
89 GST_BASE_API
90 gboolean gst_byte_reader_get_uint16_le (GstByteReader *reader, guint16 *val);
91
92 GST_BASE_API
93 gboolean gst_byte_reader_get_int16_le (GstByteReader *reader, gint16 *val);
94
95 GST_BASE_API
96 gboolean gst_byte_reader_get_uint16_be (GstByteReader *reader, guint16 *val);
97
98 GST_BASE_API
99 gboolean gst_byte_reader_get_int16_be (GstByteReader *reader, gint16 *val);
100
101 GST_BASE_API
102 gboolean gst_byte_reader_get_uint24_le (GstByteReader *reader, guint32 *val);
103
104 GST_BASE_API
105 gboolean gst_byte_reader_get_int24_le (GstByteReader *reader, gint32 *val);
106
107 GST_BASE_API
108 gboolean gst_byte_reader_get_uint24_be (GstByteReader *reader, guint32 *val);
109
110 GST_BASE_API
111 gboolean gst_byte_reader_get_int24_be (GstByteReader *reader, gint32 *val);
112
113 GST_BASE_API
114 gboolean gst_byte_reader_get_uint32_le (GstByteReader *reader, guint32 *val);
115
116 GST_BASE_API
117 gboolean gst_byte_reader_get_int32_le (GstByteReader *reader, gint32 *val);
118
119 GST_BASE_API
120 gboolean gst_byte_reader_get_uint32_be (GstByteReader *reader, guint32 *val);
121
122 GST_BASE_API
123 gboolean gst_byte_reader_get_int32_be (GstByteReader *reader, gint32 *val);
124
125 GST_BASE_API
126 gboolean gst_byte_reader_get_uint64_le (GstByteReader *reader, guint64 *val);
127
128 GST_BASE_API
129 gboolean gst_byte_reader_get_int64_le (GstByteReader *reader, gint64 *val);
130
131 GST_BASE_API
132 gboolean gst_byte_reader_get_uint64_be (GstByteReader *reader, guint64 *val);
133
134 GST_BASE_API
135 gboolean gst_byte_reader_get_int64_be (GstByteReader *reader, gint64 *val);
136
137 GST_BASE_API
138 gboolean gst_byte_reader_peek_uint8 (const GstByteReader *reader, guint8 *val);
139
140 GST_BASE_API
141 gboolean gst_byte_reader_peek_int8 (const GstByteReader *reader, gint8 *val);
142
143 GST_BASE_API
144 gboolean gst_byte_reader_peek_uint16_le (const GstByteReader *reader, guint16 *val);
145
146 GST_BASE_API
147 gboolean gst_byte_reader_peek_int16_le (const GstByteReader *reader, gint16 *val);
148
149 GST_BASE_API
150 gboolean gst_byte_reader_peek_uint16_be (const GstByteReader *reader, guint16 *val);
151
152 GST_BASE_API
153 gboolean gst_byte_reader_peek_int16_be (const GstByteReader *reader, gint16 *val);
154
155 GST_BASE_API
156 gboolean gst_byte_reader_peek_uint24_le (const GstByteReader *reader, guint32 *val);
157
158 GST_BASE_API
159 gboolean gst_byte_reader_peek_int24_le (const GstByteReader *reader, gint32 *val);
160
161 GST_BASE_API
162 gboolean gst_byte_reader_peek_uint24_be (const GstByteReader *reader, guint32 *val);
163
164 GST_BASE_API
165 gboolean gst_byte_reader_peek_int24_be (const GstByteReader *reader, gint32 *val);
166
167 GST_BASE_API
168 gboolean gst_byte_reader_peek_uint32_le (const GstByteReader *reader, guint32 *val);
169
170 GST_BASE_API
171 gboolean gst_byte_reader_peek_int32_le (const GstByteReader *reader, gint32 *val);
172
173 GST_BASE_API
174 gboolean gst_byte_reader_peek_uint32_be (const GstByteReader *reader, guint32 *val);
175
176 GST_BASE_API
177 gboolean gst_byte_reader_peek_int32_be (const GstByteReader *reader, gint32 *val);
178
179 GST_BASE_API
180 gboolean gst_byte_reader_peek_uint64_le (const GstByteReader *reader, guint64 *val);
181
182 GST_BASE_API
183 gboolean gst_byte_reader_peek_int64_le (const GstByteReader *reader, gint64 *val);
184
185 GST_BASE_API
186 gboolean gst_byte_reader_peek_uint64_be (const GstByteReader *reader, guint64 *val);
187
188 GST_BASE_API
189 gboolean gst_byte_reader_peek_int64_be (const GstByteReader *reader, gint64 *val);
190
191 GST_BASE_API
192 gboolean gst_byte_reader_get_float32_le (GstByteReader *reader, gfloat *val);
193
194 GST_BASE_API
195 gboolean gst_byte_reader_get_float32_be (GstByteReader *reader, gfloat *val);
196
197 GST_BASE_API
198 gboolean gst_byte_reader_get_float64_le (GstByteReader *reader, gdouble *val);
199
200 GST_BASE_API
201 gboolean gst_byte_reader_get_float64_be (GstByteReader *reader, gdouble *val);
202
203 GST_BASE_API
204 gboolean gst_byte_reader_peek_float32_le (const GstByteReader *reader, gfloat *val);
205
206 GST_BASE_API
207 gboolean gst_byte_reader_peek_float32_be (const GstByteReader *reader, gfloat *val);
208
209 GST_BASE_API
210 gboolean gst_byte_reader_peek_float64_le (const GstByteReader *reader, gdouble *val);
211
212 GST_BASE_API
213 gboolean gst_byte_reader_peek_float64_be (const GstByteReader *reader, gdouble *val);
214
215 GST_BASE_API
216 gboolean gst_byte_reader_dup_data (GstByteReader * reader, guint size, guint8 ** val);
217
218 GST_BASE_API
219 gboolean gst_byte_reader_get_data (GstByteReader * reader, guint size, const guint8 ** val);
220
221 GST_BASE_API
222 gboolean gst_byte_reader_peek_data (const GstByteReader * reader, guint size, const guint8 ** val);
223
224 #define gst_byte_reader_dup_string(reader,str) \
225 gst_byte_reader_dup_string_utf8(reader,str)
226
227 GST_BASE_API
228 gboolean gst_byte_reader_dup_string_utf8 (GstByteReader * reader, gchar ** str);
229
230 GST_BASE_API
231 gboolean gst_byte_reader_dup_string_utf16 (GstByteReader * reader, guint16 ** str);
232
233 GST_BASE_API
234 gboolean gst_byte_reader_dup_string_utf32 (GstByteReader * reader, guint32 ** str);
235
236 #define gst_byte_reader_skip_string(reader) \
237 gst_byte_reader_skip_string_utf8(reader)
238
239 GST_BASE_API
240 gboolean gst_byte_reader_skip_string_utf8 (GstByteReader * reader);
241
242 GST_BASE_API
243 gboolean gst_byte_reader_skip_string_utf16 (GstByteReader * reader);
244
245 GST_BASE_API
246 gboolean gst_byte_reader_skip_string_utf32 (GstByteReader * reader);
247
248 #define gst_byte_reader_get_string(reader,str) \
249 gst_byte_reader_get_string_utf8(reader,str)
250
251 #define gst_byte_reader_peek_string(reader,str) \
252 gst_byte_reader_peek_string_utf8(reader,str)
253
254 GST_BASE_API
255 gboolean gst_byte_reader_get_string_utf8 (GstByteReader * reader, const gchar ** str);
256
257 GST_BASE_API
258 gboolean gst_byte_reader_peek_string_utf8 (const GstByteReader * reader, const gchar ** str);
259
260 GST_BASE_API
261 guint gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader,
262 guint32 mask,
263 guint32 pattern,
264 guint offset,
265 guint size);
266 GST_BASE_API
267 guint gst_byte_reader_masked_scan_uint32_peek (const GstByteReader * reader,
268 guint32 mask,
269 guint32 pattern,
270 guint offset,
271 guint size,
272 guint32 * value);
273
274 /**
275 * GST_BYTE_READER_INIT:
276 * @data: Data from which the #GstByteReader should read
277 * @size: Size of @data in bytes
278 *
279 * A #GstByteReader must be initialized with this macro, before it can be
280 * used. This macro can used be to initialize a variable, but it cannot
281 * be assigned to a variable. In that case you have to use
282 * gst_byte_reader_init().
283 */
284 #define GST_BYTE_READER_INIT(data, size) {data, size, 0}
285
286 /* unchecked variants */
287 static inline void
gst_byte_reader_skip_unchecked(GstByteReader * reader,guint nbytes)288 gst_byte_reader_skip_unchecked (GstByteReader * reader, guint nbytes)
289 {
290 reader->byte += nbytes;
291 }
292
293 #define __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(bits,type,lower,upper,adj) \
294 \
295 static inline type \
296 gst_byte_reader_peek_##lower##_unchecked (const GstByteReader * reader) \
297 { \
298 type val = (type) GST_READ_##upper (reader->data + reader->byte); \
299 adj \
300 return val; \
301 } \
302 \
303 static inline type \
304 gst_byte_reader_get_##lower##_unchecked (GstByteReader * reader) \
305 { \
306 type val = gst_byte_reader_peek_##lower##_unchecked (reader); \
307 reader->byte += bits / 8; \
308 return val; \
309 }
310
311 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(8,guint8,uint8,UINT8,/* */)
312 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(8,gint8,int8,UINT8,/* */)
313
314 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(16,guint16,uint16_le,UINT16_LE,/* */)
315 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(16,guint16,uint16_be,UINT16_BE,/* */)
316 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(16,gint16,int16_le,UINT16_LE,/* */)
317 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(16,gint16,int16_be,UINT16_BE,/* */)
318
319 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,guint32,uint32_le,UINT32_LE,/* */)
320 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,guint32,uint32_be,UINT32_BE,/* */)
321 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,gint32,int32_le,UINT32_LE,/* */)
322 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,gint32,int32_be,UINT32_BE,/* */)
323
324 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(24,guint32,uint24_le,UINT24_LE,/* */)
325 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(24,guint32,uint24_be,UINT24_BE,/* */)
326
327 /* fix up the sign for 24-bit signed ints stored in 32-bit signed ints */
328 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(24,gint32,int24_le,UINT24_LE,
329 if (val & 0x00800000) val |= 0xff000000;)
330 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(24,gint32,int24_be,UINT24_BE,
331 if (val & 0x00800000) val |= 0xff000000;)
332
333 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,guint64,uint64_le,UINT64_LE,/* */)
334 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,guint64,uint64_be,UINT64_BE,/* */)
335 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,gint64,int64_le,UINT64_LE,/* */)
336 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,gint64,int64_be,UINT64_BE,/* */)
337
338 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,gfloat,float32_le,FLOAT_LE,/* */)
339 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(32,gfloat,float32_be,FLOAT_BE,/* */)
340 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,gdouble,float64_le,DOUBLE_LE,/* */)
341 __GST_BYTE_READER_GET_PEEK_BITS_UNCHECKED(64,gdouble,float64_be,DOUBLE_BE,/* */)
342
343 #undef __GET_PEEK_BITS_UNCHECKED
344
345 static inline const guint8 *
gst_byte_reader_peek_data_unchecked(const GstByteReader * reader)346 gst_byte_reader_peek_data_unchecked (const GstByteReader * reader)
347 {
348 return (const guint8 *) (reader->data + reader->byte);
349 }
350
351 static inline const guint8 *
gst_byte_reader_get_data_unchecked(GstByteReader * reader,guint size)352 gst_byte_reader_get_data_unchecked (GstByteReader * reader, guint size)
353 {
354 const guint8 *data;
355
356 data = gst_byte_reader_peek_data_unchecked (reader);
357 gst_byte_reader_skip_unchecked (reader, size);
358 return data;
359 }
360
361 static inline guint8 *
gst_byte_reader_dup_data_unchecked(GstByteReader * reader,guint size)362 gst_byte_reader_dup_data_unchecked (GstByteReader * reader, guint size)
363 {
364 gconstpointer data = gst_byte_reader_get_data_unchecked (reader, size);
365 guint8 *dup_data = (guint8 *) g_malloc (size);
366
367 memcpy (dup_data, data, size);
368 return dup_data;
369 }
370
371 /* Unchecked variants that should not be used */
372 static inline guint
_gst_byte_reader_get_pos_unchecked(const GstByteReader * reader)373 _gst_byte_reader_get_pos_unchecked (const GstByteReader * reader)
374 {
375 return reader->byte;
376 }
377
378 static inline guint
_gst_byte_reader_get_remaining_unchecked(const GstByteReader * reader)379 _gst_byte_reader_get_remaining_unchecked (const GstByteReader * reader)
380 {
381 return reader->size - reader->byte;
382 }
383
384 static inline guint
_gst_byte_reader_get_size_unchecked(const GstByteReader * reader)385 _gst_byte_reader_get_size_unchecked (const GstByteReader * reader)
386 {
387 return reader->size;
388 }
389
390 /* inlined variants (do not use directly) */
391
392 static inline guint
_gst_byte_reader_get_remaining_inline(const GstByteReader * reader)393 _gst_byte_reader_get_remaining_inline (const GstByteReader * reader)
394 {
395 g_return_val_if_fail (reader != NULL, 0);
396
397 return _gst_byte_reader_get_remaining_unchecked (reader);
398 }
399
400 static inline guint
_gst_byte_reader_get_size_inline(const GstByteReader * reader)401 _gst_byte_reader_get_size_inline (const GstByteReader * reader)
402 {
403 g_return_val_if_fail (reader != NULL, 0);
404
405 return _gst_byte_reader_get_size_unchecked (reader);
406 }
407
408 #define __GST_BYTE_READER_GET_PEEK_BITS_INLINE(bits,type,name) \
409 \
410 static inline gboolean \
411 _gst_byte_reader_peek_##name##_inline (const GstByteReader * reader, type * val) \
412 { \
413 g_return_val_if_fail (reader != NULL, FALSE); \
414 g_return_val_if_fail (val != NULL, FALSE); \
415 \
416 if (_gst_byte_reader_get_remaining_unchecked (reader) < (bits / 8)) \
417 return FALSE; \
418 \
419 *val = gst_byte_reader_peek_##name##_unchecked (reader); \
420 return TRUE; \
421 } \
422 \
423 static inline gboolean \
424 _gst_byte_reader_get_##name##_inline (GstByteReader * reader, type * val) \
425 { \
426 g_return_val_if_fail (reader != NULL, FALSE); \
427 g_return_val_if_fail (val != NULL, FALSE); \
428 \
429 if (_gst_byte_reader_get_remaining_unchecked (reader) < (bits / 8)) \
430 return FALSE; \
431 \
432 *val = gst_byte_reader_get_##name##_unchecked (reader); \
433 return TRUE; \
434 }
435
436 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(8,guint8,uint8)
437 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(8,gint8,int8)
438
439 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,guint16,uint16_le)
440 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,guint16,uint16_be)
441 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,gint16,int16_le)
442 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,gint16,int16_be)
443
444 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,guint32,uint32_le)
445 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,guint32,uint32_be)
446 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gint32,int32_le)
447 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gint32,int32_be)
448
449 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,guint32,uint24_le)
450 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,guint32,uint24_be)
451 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,gint32,int24_le)
452 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,gint32,int24_be)
453
454 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,guint64,uint64_le)
455 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,guint64,uint64_be)
456 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gint64,int64_le)
457 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gint64,int64_be)
458
459 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gfloat,float32_le)
460 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gfloat,float32_be)
461 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gdouble,float64_le)
462 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gdouble,float64_be)
463
464 #undef __GST_BYTE_READER_GET_PEEK_BITS_INLINE
465
466 #ifndef GST_BYTE_READER_DISABLE_INLINES
467
468 #define gst_byte_reader_init(reader,data,size) \
469 _gst_byte_reader_init_inline(reader,data,size)
470
471 #define gst_byte_reader_get_remaining(reader) \
472 _gst_byte_reader_get_remaining_inline(reader)
473
474 #define gst_byte_reader_get_size(reader) \
475 _gst_byte_reader_get_size_inline(reader)
476
477 #define gst_byte_reader_get_pos(reader) \
478 _gst_byte_reader_get_pos_inline(reader)
479
480 /* we use defines here so we can add the G_LIKELY() */
481 #define gst_byte_reader_get_uint8(reader,val) \
482 G_LIKELY(_gst_byte_reader_get_uint8_inline(reader,val))
483 #define gst_byte_reader_get_int8(reader,val) \
484 G_LIKELY(_gst_byte_reader_get_int8_inline(reader,val))
485 #define gst_byte_reader_get_uint16_le(reader,val) \
486 G_LIKELY(_gst_byte_reader_get_uint16_le_inline(reader,val))
487 #define gst_byte_reader_get_int16_le(reader,val) \
488 G_LIKELY(_gst_byte_reader_get_int16_le_inline(reader,val))
489 #define gst_byte_reader_get_uint16_be(reader,val) \
490 G_LIKELY(_gst_byte_reader_get_uint16_be_inline(reader,val))
491 #define gst_byte_reader_get_int16_be(reader,val) \
492 G_LIKELY(_gst_byte_reader_get_int16_be_inline(reader,val))
493 #define gst_byte_reader_get_uint24_le(reader,val) \
494 G_LIKELY(_gst_byte_reader_get_uint24_le_inline(reader,val))
495 #define gst_byte_reader_get_int24_le(reader,val) \
496 G_LIKELY(_gst_byte_reader_get_int24_le_inline(reader,val))
497 #define gst_byte_reader_get_uint24_be(reader,val) \
498 G_LIKELY(_gst_byte_reader_get_uint24_be_inline(reader,val))
499 #define gst_byte_reader_get_int24_be(reader,val) \
500 G_LIKELY(_gst_byte_reader_get_int24_be_inline(reader,val))
501 #define gst_byte_reader_get_uint32_le(reader,val) \
502 G_LIKELY(_gst_byte_reader_get_uint32_le_inline(reader,val))
503 #define gst_byte_reader_get_int32_le(reader,val) \
504 G_LIKELY(_gst_byte_reader_get_int32_le_inline(reader,val))
505 #define gst_byte_reader_get_uint32_be(reader,val) \
506 G_LIKELY(_gst_byte_reader_get_uint32_be_inline(reader,val))
507 #define gst_byte_reader_get_int32_be(reader,val) \
508 G_LIKELY(_gst_byte_reader_get_int32_be_inline(reader,val))
509 #define gst_byte_reader_get_uint64_le(reader,val) \
510 G_LIKELY(_gst_byte_reader_get_uint64_le_inline(reader,val))
511 #define gst_byte_reader_get_int64_le(reader,val) \
512 G_LIKELY(_gst_byte_reader_get_int64_le_inline(reader,val))
513 #define gst_byte_reader_get_uint64_be(reader,val) \
514 G_LIKELY(_gst_byte_reader_get_uint64_be_inline(reader,val))
515 #define gst_byte_reader_get_int64_be(reader,val) \
516 G_LIKELY(_gst_byte_reader_get_int64_be_inline(reader,val))
517
518 #define gst_byte_reader_peek_uint8(reader,val) \
519 G_LIKELY(_gst_byte_reader_peek_uint8_inline(reader,val))
520 #define gst_byte_reader_peek_int8(reader,val) \
521 G_LIKELY(_gst_byte_reader_peek_int8_inline(reader,val))
522 #define gst_byte_reader_peek_uint16_le(reader,val) \
523 G_LIKELY(_gst_byte_reader_peek_uint16_le_inline(reader,val))
524 #define gst_byte_reader_peek_int16_le(reader,val) \
525 G_LIKELY(_gst_byte_reader_peek_int16_le_inline(reader,val))
526 #define gst_byte_reader_peek_uint16_be(reader,val) \
527 G_LIKELY(_gst_byte_reader_peek_uint16_be_inline(reader,val))
528 #define gst_byte_reader_peek_int16_be(reader,val) \
529 G_LIKELY(_gst_byte_reader_peek_int16_be_inline(reader,val))
530 #define gst_byte_reader_peek_uint24_le(reader,val) \
531 G_LIKELY(_gst_byte_reader_peek_uint24_le_inline(reader,val))
532 #define gst_byte_reader_peek_int24_le(reader,val) \
533 G_LIKELY(_gst_byte_reader_peek_int24_le_inline(reader,val))
534 #define gst_byte_reader_peek_uint24_be(reader,val) \
535 G_LIKELY(_gst_byte_reader_peek_uint24_be_inline(reader,val))
536 #define gst_byte_reader_peek_int24_be(reader,val) \
537 G_LIKELY(_gst_byte_reader_peek_int24_be_inline(reader,val))
538 #define gst_byte_reader_peek_uint32_le(reader,val) \
539 G_LIKELY(_gst_byte_reader_peek_uint32_le_inline(reader,val))
540 #define gst_byte_reader_peek_int32_le(reader,val) \
541 G_LIKELY(_gst_byte_reader_peek_int32_le_inline(reader,val))
542 #define gst_byte_reader_peek_uint32_be(reader,val) \
543 G_LIKELY(_gst_byte_reader_peek_uint32_be_inline(reader,val))
544 #define gst_byte_reader_peek_int32_be(reader,val) \
545 G_LIKELY(_gst_byte_reader_peek_int32_be_inline(reader,val))
546 #define gst_byte_reader_peek_uint64_le(reader,val) \
547 G_LIKELY(_gst_byte_reader_peek_uint64_le_inline(reader,val))
548 #define gst_byte_reader_peek_int64_le(reader,val) \
549 G_LIKELY(_gst_byte_reader_peek_int64_le_inline(reader,val))
550 #define gst_byte_reader_peek_uint64_be(reader,val) \
551 G_LIKELY(_gst_byte_reader_peek_uint64_be_inline(reader,val))
552 #define gst_byte_reader_peek_int64_be(reader,val) \
553 G_LIKELY(_gst_byte_reader_peek_int64_be_inline(reader,val))
554
555 #define gst_byte_reader_get_float32_le(reader,val) \
556 G_LIKELY(_gst_byte_reader_get_float32_le_inline(reader,val))
557 #define gst_byte_reader_get_float32_be(reader,val) \
558 G_LIKELY(_gst_byte_reader_get_float32_be_inline(reader,val))
559 #define gst_byte_reader_get_float64_le(reader,val) \
560 G_LIKELY(_gst_byte_reader_get_float64_le_inline(reader,val))
561 #define gst_byte_reader_get_float64_be(reader,val) \
562 G_LIKELY(_gst_byte_reader_get_float64_be_inline(reader,val))
563 #define gst_byte_reader_peek_float32_le(reader,val) \
564 G_LIKELY(_gst_byte_reader_peek_float32_le_inline(reader,val))
565 #define gst_byte_reader_peek_float32_be(reader,val) \
566 G_LIKELY(_gst_byte_reader_peek_float32_be_inline(reader,val))
567 #define gst_byte_reader_peek_float64_le(reader,val) \
568 G_LIKELY(_gst_byte_reader_peek_float64_le_inline(reader,val))
569 #define gst_byte_reader_peek_float64_be(reader,val) \
570 G_LIKELY(_gst_byte_reader_peek_float64_be_inline(reader,val))
571
572 #endif /* GST_BYTE_READER_DISABLE_INLINES */
573
574 static inline void
_gst_byte_reader_init_inline(GstByteReader * reader,const guint8 * data,guint size)575 _gst_byte_reader_init_inline (GstByteReader * reader, const guint8 * data, guint size)
576 {
577 g_return_if_fail (reader != NULL);
578
579 reader->data = data;
580 reader->size = size;
581 reader->byte = 0;
582 }
583
584 static inline gboolean
_gst_byte_reader_peek_sub_reader_inline(GstByteReader * reader,GstByteReader * sub_reader,guint size)585 _gst_byte_reader_peek_sub_reader_inline (GstByteReader * reader,
586 GstByteReader * sub_reader, guint size)
587 {
588 g_return_val_if_fail (reader != NULL, FALSE);
589 g_return_val_if_fail (sub_reader != NULL, FALSE);
590
591 if (_gst_byte_reader_get_remaining_unchecked (reader) < size)
592 return FALSE;
593
594 sub_reader->data = reader->data + reader->byte;
595 sub_reader->byte = 0;
596 sub_reader->size = size;
597 return TRUE;
598 }
599
600 static inline gboolean
_gst_byte_reader_get_sub_reader_inline(GstByteReader * reader,GstByteReader * sub_reader,guint size)601 _gst_byte_reader_get_sub_reader_inline (GstByteReader * reader,
602 GstByteReader * sub_reader, guint size)
603 {
604 if (!_gst_byte_reader_peek_sub_reader_inline (reader, sub_reader, size))
605 return FALSE;
606 gst_byte_reader_skip_unchecked (reader, size);
607 return TRUE;
608 }
609
610 static inline gboolean
_gst_byte_reader_dup_data_inline(GstByteReader * reader,guint size,guint8 ** val)611 _gst_byte_reader_dup_data_inline (GstByteReader * reader, guint size, guint8 ** val)
612 {
613 g_return_val_if_fail (reader != NULL, FALSE);
614 g_return_val_if_fail (val != NULL, FALSE);
615
616 if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
617 return FALSE;
618
619 *val = gst_byte_reader_dup_data_unchecked (reader, size);
620 return TRUE;
621 }
622
623 static inline gboolean
_gst_byte_reader_get_data_inline(GstByteReader * reader,guint size,const guint8 ** val)624 _gst_byte_reader_get_data_inline (GstByteReader * reader, guint size, const guint8 ** val)
625 {
626 g_return_val_if_fail (reader != NULL, FALSE);
627 g_return_val_if_fail (val != NULL, FALSE);
628
629 if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
630 return FALSE;
631
632 *val = gst_byte_reader_get_data_unchecked (reader, size);
633 return TRUE;
634 }
635
636 static inline gboolean
_gst_byte_reader_peek_data_inline(const GstByteReader * reader,guint size,const guint8 ** val)637 _gst_byte_reader_peek_data_inline (const GstByteReader * reader, guint size, const guint8 ** val)
638 {
639 g_return_val_if_fail (reader != NULL, FALSE);
640 g_return_val_if_fail (val != NULL, FALSE);
641
642 if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
643 return FALSE;
644
645 *val = gst_byte_reader_peek_data_unchecked (reader);
646 return TRUE;
647 }
648
649 static inline guint
_gst_byte_reader_get_pos_inline(const GstByteReader * reader)650 _gst_byte_reader_get_pos_inline (const GstByteReader * reader)
651 {
652 g_return_val_if_fail (reader != NULL, 0);
653
654 return _gst_byte_reader_get_pos_unchecked (reader);
655 }
656
657 static inline gboolean
_gst_byte_reader_skip_inline(GstByteReader * reader,guint nbytes)658 _gst_byte_reader_skip_inline (GstByteReader * reader, guint nbytes)
659 {
660 g_return_val_if_fail (reader != NULL, FALSE);
661
662 if (G_UNLIKELY (_gst_byte_reader_get_remaining_unchecked (reader) < nbytes))
663 return FALSE;
664
665 reader->byte += nbytes;
666 return TRUE;
667 }
668
669 #ifndef GST_BYTE_READER_DISABLE_INLINES
670
671 #define gst_byte_reader_dup_data(reader,size,val) \
672 G_LIKELY(_gst_byte_reader_dup_data_inline(reader,size,val))
673 #define gst_byte_reader_get_data(reader,size,val) \
674 G_LIKELY(_gst_byte_reader_get_data_inline(reader,size,val))
675 #define gst_byte_reader_peek_data(reader,size,val) \
676 G_LIKELY(_gst_byte_reader_peek_data_inline(reader,size,val))
677 #define gst_byte_reader_skip(reader,nbytes) \
678 G_LIKELY(_gst_byte_reader_skip_inline(reader,nbytes))
679
680 #endif /* GST_BYTE_READER_DISABLE_INLINES */
681
682 G_END_DECLS
683
684 #endif /* __GST_BYTE_READER_H__ */
685