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   return (guint8 *) g_memdup (data, size);
366 }
367 
368 /* Unchecked variants that should not be used */
369 static inline guint
_gst_byte_reader_get_pos_unchecked(const GstByteReader * reader)370 _gst_byte_reader_get_pos_unchecked (const GstByteReader * reader)
371 {
372   return reader->byte;
373 }
374 
375 static inline guint
_gst_byte_reader_get_remaining_unchecked(const GstByteReader * reader)376 _gst_byte_reader_get_remaining_unchecked (const GstByteReader * reader)
377 {
378   return reader->size - reader->byte;
379 }
380 
381 static inline guint
_gst_byte_reader_get_size_unchecked(const GstByteReader * reader)382 _gst_byte_reader_get_size_unchecked (const GstByteReader * reader)
383 {
384   return reader->size;
385 }
386 
387 /* inlined variants (do not use directly) */
388 
389 static inline guint
_gst_byte_reader_get_remaining_inline(const GstByteReader * reader)390 _gst_byte_reader_get_remaining_inline (const GstByteReader * reader)
391 {
392   g_return_val_if_fail (reader != NULL, 0);
393 
394   return _gst_byte_reader_get_remaining_unchecked (reader);
395 }
396 
397 static inline guint
_gst_byte_reader_get_size_inline(const GstByteReader * reader)398 _gst_byte_reader_get_size_inline (const GstByteReader * reader)
399 {
400   g_return_val_if_fail (reader != NULL, 0);
401 
402   return _gst_byte_reader_get_size_unchecked (reader);
403 }
404 
405 #define __GST_BYTE_READER_GET_PEEK_BITS_INLINE(bits,type,name) \
406 \
407 static inline gboolean \
408 _gst_byte_reader_peek_##name##_inline (const GstByteReader * reader, type * val) \
409 { \
410   g_return_val_if_fail (reader != NULL, FALSE); \
411   g_return_val_if_fail (val != NULL, FALSE); \
412   \
413   if (_gst_byte_reader_get_remaining_unchecked (reader) < (bits / 8)) \
414     return FALSE; \
415 \
416   *val = gst_byte_reader_peek_##name##_unchecked (reader); \
417   return TRUE; \
418 } \
419 \
420 static inline gboolean \
421 _gst_byte_reader_get_##name##_inline (GstByteReader * reader, type * val) \
422 { \
423   g_return_val_if_fail (reader != NULL, FALSE); \
424   g_return_val_if_fail (val != NULL, FALSE); \
425   \
426   if (_gst_byte_reader_get_remaining_unchecked (reader) < (bits / 8)) \
427     return FALSE; \
428 \
429   *val = gst_byte_reader_get_##name##_unchecked (reader); \
430   return TRUE; \
431 }
432 
433 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(8,guint8,uint8)
434 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(8,gint8,int8)
435 
436 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,guint16,uint16_le)
437 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,guint16,uint16_be)
438 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,gint16,int16_le)
439 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(16,gint16,int16_be)
440 
441 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,guint32,uint32_le)
442 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,guint32,uint32_be)
443 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gint32,int32_le)
444 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gint32,int32_be)
445 
446 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,guint32,uint24_le)
447 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,guint32,uint24_be)
448 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,gint32,int24_le)
449 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(24,gint32,int24_be)
450 
451 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,guint64,uint64_le)
452 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,guint64,uint64_be)
453 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gint64,int64_le)
454 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gint64,int64_be)
455 
456 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gfloat,float32_le)
457 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(32,gfloat,float32_be)
458 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gdouble,float64_le)
459 __GST_BYTE_READER_GET_PEEK_BITS_INLINE(64,gdouble,float64_be)
460 
461 #undef __GST_BYTE_READER_GET_PEEK_BITS_INLINE
462 
463 #ifndef GST_BYTE_READER_DISABLE_INLINES
464 
465 #define gst_byte_reader_init(reader,data,size) \
466     _gst_byte_reader_init_inline(reader,data,size)
467 
468 #define gst_byte_reader_get_remaining(reader) \
469     _gst_byte_reader_get_remaining_inline(reader)
470 
471 #define gst_byte_reader_get_size(reader) \
472     _gst_byte_reader_get_size_inline(reader)
473 
474 #define gst_byte_reader_get_pos(reader) \
475     _gst_byte_reader_get_pos_inline(reader)
476 
477 /* we use defines here so we can add the G_LIKELY() */
478 #define gst_byte_reader_get_uint8(reader,val) \
479     G_LIKELY(_gst_byte_reader_get_uint8_inline(reader,val))
480 #define gst_byte_reader_get_int8(reader,val) \
481     G_LIKELY(_gst_byte_reader_get_int8_inline(reader,val))
482 #define gst_byte_reader_get_uint16_le(reader,val) \
483     G_LIKELY(_gst_byte_reader_get_uint16_le_inline(reader,val))
484 #define gst_byte_reader_get_int16_le(reader,val) \
485     G_LIKELY(_gst_byte_reader_get_int16_le_inline(reader,val))
486 #define gst_byte_reader_get_uint16_be(reader,val) \
487     G_LIKELY(_gst_byte_reader_get_uint16_be_inline(reader,val))
488 #define gst_byte_reader_get_int16_be(reader,val) \
489     G_LIKELY(_gst_byte_reader_get_int16_be_inline(reader,val))
490 #define gst_byte_reader_get_uint24_le(reader,val) \
491     G_LIKELY(_gst_byte_reader_get_uint24_le_inline(reader,val))
492 #define gst_byte_reader_get_int24_le(reader,val) \
493     G_LIKELY(_gst_byte_reader_get_int24_le_inline(reader,val))
494 #define gst_byte_reader_get_uint24_be(reader,val) \
495     G_LIKELY(_gst_byte_reader_get_uint24_be_inline(reader,val))
496 #define gst_byte_reader_get_int24_be(reader,val) \
497     G_LIKELY(_gst_byte_reader_get_int24_be_inline(reader,val))
498 #define gst_byte_reader_get_uint32_le(reader,val) \
499     G_LIKELY(_gst_byte_reader_get_uint32_le_inline(reader,val))
500 #define gst_byte_reader_get_int32_le(reader,val) \
501     G_LIKELY(_gst_byte_reader_get_int32_le_inline(reader,val))
502 #define gst_byte_reader_get_uint32_be(reader,val) \
503     G_LIKELY(_gst_byte_reader_get_uint32_be_inline(reader,val))
504 #define gst_byte_reader_get_int32_be(reader,val) \
505     G_LIKELY(_gst_byte_reader_get_int32_be_inline(reader,val))
506 #define gst_byte_reader_get_uint64_le(reader,val) \
507     G_LIKELY(_gst_byte_reader_get_uint64_le_inline(reader,val))
508 #define gst_byte_reader_get_int64_le(reader,val) \
509     G_LIKELY(_gst_byte_reader_get_int64_le_inline(reader,val))
510 #define gst_byte_reader_get_uint64_be(reader,val) \
511     G_LIKELY(_gst_byte_reader_get_uint64_be_inline(reader,val))
512 #define gst_byte_reader_get_int64_be(reader,val) \
513     G_LIKELY(_gst_byte_reader_get_int64_be_inline(reader,val))
514 
515 #define gst_byte_reader_peek_uint8(reader,val) \
516     G_LIKELY(_gst_byte_reader_peek_uint8_inline(reader,val))
517 #define gst_byte_reader_peek_int8(reader,val) \
518     G_LIKELY(_gst_byte_reader_peek_int8_inline(reader,val))
519 #define gst_byte_reader_peek_uint16_le(reader,val) \
520     G_LIKELY(_gst_byte_reader_peek_uint16_le_inline(reader,val))
521 #define gst_byte_reader_peek_int16_le(reader,val) \
522     G_LIKELY(_gst_byte_reader_peek_int16_le_inline(reader,val))
523 #define gst_byte_reader_peek_uint16_be(reader,val) \
524     G_LIKELY(_gst_byte_reader_peek_uint16_be_inline(reader,val))
525 #define gst_byte_reader_peek_int16_be(reader,val) \
526     G_LIKELY(_gst_byte_reader_peek_int16_be_inline(reader,val))
527 #define gst_byte_reader_peek_uint24_le(reader,val) \
528     G_LIKELY(_gst_byte_reader_peek_uint24_le_inline(reader,val))
529 #define gst_byte_reader_peek_int24_le(reader,val) \
530     G_LIKELY(_gst_byte_reader_peek_int24_le_inline(reader,val))
531 #define gst_byte_reader_peek_uint24_be(reader,val) \
532     G_LIKELY(_gst_byte_reader_peek_uint24_be_inline(reader,val))
533 #define gst_byte_reader_peek_int24_be(reader,val) \
534     G_LIKELY(_gst_byte_reader_peek_int24_be_inline(reader,val))
535 #define gst_byte_reader_peek_uint32_le(reader,val) \
536     G_LIKELY(_gst_byte_reader_peek_uint32_le_inline(reader,val))
537 #define gst_byte_reader_peek_int32_le(reader,val) \
538     G_LIKELY(_gst_byte_reader_peek_int32_le_inline(reader,val))
539 #define gst_byte_reader_peek_uint32_be(reader,val) \
540     G_LIKELY(_gst_byte_reader_peek_uint32_be_inline(reader,val))
541 #define gst_byte_reader_peek_int32_be(reader,val) \
542     G_LIKELY(_gst_byte_reader_peek_int32_be_inline(reader,val))
543 #define gst_byte_reader_peek_uint64_le(reader,val) \
544     G_LIKELY(_gst_byte_reader_peek_uint64_le_inline(reader,val))
545 #define gst_byte_reader_peek_int64_le(reader,val) \
546     G_LIKELY(_gst_byte_reader_peek_int64_le_inline(reader,val))
547 #define gst_byte_reader_peek_uint64_be(reader,val) \
548     G_LIKELY(_gst_byte_reader_peek_uint64_be_inline(reader,val))
549 #define gst_byte_reader_peek_int64_be(reader,val) \
550     G_LIKELY(_gst_byte_reader_peek_int64_be_inline(reader,val))
551 
552 #define gst_byte_reader_get_float32_le(reader,val) \
553     G_LIKELY(_gst_byte_reader_get_float32_le_inline(reader,val))
554 #define gst_byte_reader_get_float32_be(reader,val) \
555     G_LIKELY(_gst_byte_reader_get_float32_be_inline(reader,val))
556 #define gst_byte_reader_get_float64_le(reader,val) \
557     G_LIKELY(_gst_byte_reader_get_float64_le_inline(reader,val))
558 #define gst_byte_reader_get_float64_be(reader,val) \
559     G_LIKELY(_gst_byte_reader_get_float64_be_inline(reader,val))
560 #define gst_byte_reader_peek_float32_le(reader,val) \
561     G_LIKELY(_gst_byte_reader_peek_float32_le_inline(reader,val))
562 #define gst_byte_reader_peek_float32_be(reader,val) \
563     G_LIKELY(_gst_byte_reader_peek_float32_be_inline(reader,val))
564 #define gst_byte_reader_peek_float64_le(reader,val) \
565     G_LIKELY(_gst_byte_reader_peek_float64_le_inline(reader,val))
566 #define gst_byte_reader_peek_float64_be(reader,val) \
567     G_LIKELY(_gst_byte_reader_peek_float64_be_inline(reader,val))
568 
569 #endif /* GST_BYTE_READER_DISABLE_INLINES */
570 
571 static inline void
_gst_byte_reader_init_inline(GstByteReader * reader,const guint8 * data,guint size)572 _gst_byte_reader_init_inline (GstByteReader * reader, const guint8 * data, guint size)
573 {
574   g_return_if_fail (reader != NULL);
575 
576   reader->data = data;
577   reader->size = size;
578   reader->byte = 0;
579 }
580 
581 static inline gboolean
_gst_byte_reader_peek_sub_reader_inline(GstByteReader * reader,GstByteReader * sub_reader,guint size)582 _gst_byte_reader_peek_sub_reader_inline (GstByteReader * reader,
583     GstByteReader * sub_reader, guint size)
584 {
585   g_return_val_if_fail (reader != NULL, FALSE);
586   g_return_val_if_fail (sub_reader != NULL, FALSE);
587 
588   if (_gst_byte_reader_get_remaining_unchecked (reader) < size)
589     return FALSE;
590 
591   sub_reader->data = reader->data + reader->byte;
592   sub_reader->byte = 0;
593   sub_reader->size = size;
594   return TRUE;
595 }
596 
597 static inline gboolean
_gst_byte_reader_get_sub_reader_inline(GstByteReader * reader,GstByteReader * sub_reader,guint size)598 _gst_byte_reader_get_sub_reader_inline (GstByteReader * reader,
599     GstByteReader * sub_reader, guint size)
600 {
601   if (!_gst_byte_reader_peek_sub_reader_inline (reader, sub_reader, size))
602     return FALSE;
603   gst_byte_reader_skip_unchecked (reader, size);
604   return TRUE;
605 }
606 
607 static inline gboolean
_gst_byte_reader_dup_data_inline(GstByteReader * reader,guint size,guint8 ** val)608 _gst_byte_reader_dup_data_inline (GstByteReader * reader, guint size, guint8 ** val)
609 {
610   g_return_val_if_fail (reader != NULL, FALSE);
611   g_return_val_if_fail (val != NULL, FALSE);
612 
613   if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
614     return FALSE;
615 
616   *val = gst_byte_reader_dup_data_unchecked (reader, size);
617   return TRUE;
618 }
619 
620 static inline gboolean
_gst_byte_reader_get_data_inline(GstByteReader * reader,guint size,const guint8 ** val)621 _gst_byte_reader_get_data_inline (GstByteReader * reader, guint size, const guint8 ** val)
622 {
623   g_return_val_if_fail (reader != NULL, FALSE);
624   g_return_val_if_fail (val != NULL, FALSE);
625 
626   if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
627     return FALSE;
628 
629   *val = gst_byte_reader_get_data_unchecked (reader, size);
630   return TRUE;
631 }
632 
633 static inline gboolean
_gst_byte_reader_peek_data_inline(const GstByteReader * reader,guint size,const guint8 ** val)634 _gst_byte_reader_peek_data_inline (const GstByteReader * reader, guint size, const guint8 ** val)
635 {
636   g_return_val_if_fail (reader != NULL, FALSE);
637   g_return_val_if_fail (val != NULL, FALSE);
638 
639   if (G_UNLIKELY (size > reader->size || _gst_byte_reader_get_remaining_unchecked (reader) < size))
640     return FALSE;
641 
642   *val = gst_byte_reader_peek_data_unchecked (reader);
643   return TRUE;
644 }
645 
646 static inline guint
_gst_byte_reader_get_pos_inline(const GstByteReader * reader)647 _gst_byte_reader_get_pos_inline (const GstByteReader * reader)
648 {
649   g_return_val_if_fail (reader != NULL, 0);
650 
651   return _gst_byte_reader_get_pos_unchecked (reader);
652 }
653 
654 static inline gboolean
_gst_byte_reader_skip_inline(GstByteReader * reader,guint nbytes)655 _gst_byte_reader_skip_inline (GstByteReader * reader, guint nbytes)
656 {
657   g_return_val_if_fail (reader != NULL, FALSE);
658 
659   if (G_UNLIKELY (_gst_byte_reader_get_remaining_unchecked (reader) < nbytes))
660     return FALSE;
661 
662   reader->byte += nbytes;
663   return TRUE;
664 }
665 
666 #ifndef GST_BYTE_READER_DISABLE_INLINES
667 
668 #define gst_byte_reader_dup_data(reader,size,val) \
669     G_LIKELY(_gst_byte_reader_dup_data_inline(reader,size,val))
670 #define gst_byte_reader_get_data(reader,size,val) \
671     G_LIKELY(_gst_byte_reader_get_data_inline(reader,size,val))
672 #define gst_byte_reader_peek_data(reader,size,val) \
673     G_LIKELY(_gst_byte_reader_peek_data_inline(reader,size,val))
674 #define gst_byte_reader_skip(reader,nbytes) \
675     G_LIKELY(_gst_byte_reader_skip_inline(reader,nbytes))
676 
677 #endif /* GST_BYTE_READER_DISABLE_INLINES */
678 
679 G_END_DECLS
680 
681 #endif /* __GST_BYTE_READER_H__ */
682