+/* Helpers:
+ * They ensure that invalid reads will not create problems.
+ * They are expansion safe
+ * They make the following assumptions:
+ * const uint8_t *p_peek exists and points to the start of a buffer
+ * int i_peek gives the size of the buffer pointed by p_peek
+ * const uint8_t *p_data exits and points to the data inside p_peek to be read.
+ */
+/* ASF_HAVE(n):
+ * Check that n bytes can be read */
+static inline bool AsfObjectHelperHave( const uint8_t *p_peek, int i_peek, const uint8_t *p_current, int i_wanted )
+{
+ if( i_wanted < 0 || i_wanted > i_peek )
+ return false;
+ return &p_current[i_wanted] <= &p_peek[i_peek];
+}
+#define ASF_HAVE(n) AsfObjectHelperHave( p_peek, i_peek, p_data, n )
+
+/* ASF_SKIP(n)
+ * Skip n bytes if possible */
+static inline void AsfObjectHelperSkip( const uint8_t *p_peek, int i_peek, uint8_t **pp_data, int i_wanted )
+{
+ if( AsfObjectHelperHave( p_peek, i_peek, *pp_data, i_wanted ) )
+ *pp_data += i_wanted;
+ else
+ *pp_data = (uint8_t*)&p_peek[i_peek];
+}
+#define ASF_SKIP(n) AsfObjectHelperSkip( p_peek, i_peek, (uint8_t**)&p_data, n )
+
+/* ASF_READX()
+ * Read X byte if possible, else return 0 */
+#define ASF_FUNCTION_READ_X(type, x, cmd ) \
+static inline type AsfObjectHelperRead##x( const uint8_t *p_peek, int i_peek, uint8_t **pp_data ) { \
+ uint8_t *p_data = *pp_data; \
+ type i_ret = 0; \
+ if( ASF_HAVE(x) ) \
+ i_ret = cmd; \
+ ASF_SKIP(x); \
+ *pp_data = p_data; \
+ return i_ret; }
+ASF_FUNCTION_READ_X( uint8_t, 1, *p_data )
+ASF_FUNCTION_READ_X( uint16_t, 2, GetWLE(p_data) )
+ASF_FUNCTION_READ_X( uint32_t, 4, GetDWLE(p_data) )
+ASF_FUNCTION_READ_X( uint64_t, 8, GetQWLE(p_data) )
+#define ASF_READ1() AsfObjectHelperRead1( p_peek, i_peek, (uint8_t**)&p_data )
+#define ASF_READ2() AsfObjectHelperRead2( p_peek, i_peek, (uint8_t**)&p_data )
+#define ASF_READ4() AsfObjectHelperRead4( p_peek, i_peek, (uint8_t**)&p_data )
+#define ASF_READ8() AsfObjectHelperRead8( p_peek, i_peek, (uint8_t**)&p_data )
+
+/* ASF_READS(n)
+ * Read a string of n/2 wchar long ie n bytes. Do a stupid conversion (suppose latin1)
+ * Return allocated "" if not possible */
+static char *AsfObjectHelperReadString( const uint8_t *p_peek, int i_peek, uint8_t **pp_data, int i_size )
+{
+ uint8_t *p_data = *pp_data;
+ char *psz_string;
+ if( ASF_HAVE(i_size) )
+ {
+ psz_string = calloc( i_size/2 + 1, sizeof( char ) );
+ if( psz_string )
+ {
+ int i;
+ for( i = 0; i < i_size/2; i++ )
+ psz_string[i] = GetWLE( &p_data[2*i] );
+ psz_string[i_size/2] = '\0'; \
+ }
+ }
+ else
+ {
+ psz_string = strdup("");
+ }
+ ASF_SKIP(i_size);
+ *pp_data = p_data;
+ return psz_string;
+}
+#define ASF_READS(n) AsfObjectHelperReadString( p_peek, i_peek, (uint8_t**)&p_data, n )
+