Difference between revisions of "LEX (File Format)/C example"
Jump to navigation
Jump to search
(Created page with "This page shows example code in C for »LEX (File Format)« __TOC__ == Structures == === lex_header_t === <pre> typedef struct lex_header_t { char magic[4]; // always...") |
m |
||
(7 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
+ | [[File:LE-CODE Logo (Vertical).png|right]] | ||
This page shows example code in C for »LEX (File Format)« | This page shows example code in C for »LEX (File Format)« | ||
Line 14: | Line 15: | ||
u16 minor_version; // usually LEX_MINOR_VERSION | u16 minor_version; // usually LEX_MINOR_VERSION | ||
u32 size; // size of this file (header+streams) | u32 size; // size of this file (header+streams) | ||
− | u32 | + | u32 element_off; // offset of first lex_element_t, 32-bit aligned |
} | } | ||
__attribute__ ((packed)) lex_header_t; | __attribute__ ((packed)) lex_header_t; | ||
Line 25: | Line 26: | ||
{ | { | ||
u32 magic; // identification of section | u32 magic; // identification of section | ||
− | + | u32 size; // size of 'data' (this header excluded) | |
u8 data[]; // section data, 32-bit aligned | u8 data[]; // section data, 32-bit aligned | ||
} | } | ||
Line 34: | Line 35: | ||
<pre> | <pre> | ||
+ | #define LEX_MAJOR_VERSION 1 | ||
+ | #define LEX_MINOR_VERSION 0 | ||
+ | #define LEX_BIN_MAGIC "LE-X" | ||
typedef enumError (*lex_stream_func) | typedef enumError (*lex_stream_func) | ||
Line 91: | Line 95: | ||
const uint size = ntohl(s->size); | const uint size = ntohl(s->size); | ||
off += sizeof(lex_element_t) + size; | off += sizeof(lex_element_t) + size; | ||
− | if ( | + | if ( (size&3) || off > data_size ) |
return ERR_INVALID_DATA; | return ERR_INVALID_DATA; | ||
− | |||
if (func) | if (func) | ||
{ | { |
Revision as of 03:34, 26 March 2021
This page shows example code in C for »LEX (File Format)«
Structures
lex_header_t
typedef struct lex_header_t { char magic[4]; // always LEX_BIN_MAGIC u16 major_version; // usually LEX_MAJOR_VERSION u16 minor_version; // usually LEX_MINOR_VERSION u32 size; // size of this file (header+streams) u32 element_off; // offset of first lex_element_t, 32-bit aligned } __attribute__ ((packed)) lex_header_t;
lex_element_t
typedef struct lex_element_t { u32 magic; // identification of section u32 size; // size of 'data' (this header excluded) u8 data[]; // section data, 32-bit aligned } __attribute__ ((packed)) lex_element_t;
Function Headers
#define LEX_MAJOR_VERSION 1 #define LEX_MINOR_VERSION 0 #define LEX_BIN_MAGIC "LE-X" typedef enumError (*lex_stream_func) ( u32 magic, const u8 *data, uint size, cvp user_ptr ); enumError ScanLexFile ( const void *data, uint data_size, lex_stream_func func, const void *user_ptr ); enumError ScanLexStream ( const void *data, uint data_size, lex_stream_func func, const void *user_ptr );
Scanning Functions
ScanLexFile()
enumError ScanLexFile ( const void *data, uint data_size, lex_stream_func func, const void *user_ptr ) { if ( !data || data_size < sizeof(lex_header_t) ) return ERR_INVALID_DATA; const lex_header_t *hd = (lex_header_t*)data; if (memcmp(hd->magic,LEX_BIN_MAGIC,4)) return ERR_INVALID_DATA; if ( ntohs(hd->major_version) != LEX_MAJOR_VERSION ) return ERR_INVALID_VERSION; const uint size = ntohl(hd->size); const uint off = ntohl(hd->stream_off); if ( (size&3) || size > data_size || (off&3) || off + 4 > size ) return ERR_INVALID_DATA; return ScanLexElements((u8*)data+off,size-off,func,user_ptr); }
ScanLexElements()
enumError ScanLexElements ( const void *data, uint data_size, lex_stream_func func, const void *user_ptr ) { if ( !data || !data_size || (data_size&3) ) return ERR_INVALID_DATA; enumError max_err = ERR_OK; uint off = 0; while ( off < data_size ) { const lex_element_t *s = (lex_element_t*)( (u8*)data + off ); const u32 magic = ntohl(s->magic); if (!magic) break; const uint size = ntohl(s->size); off += sizeof(lex_element_t) + size; if ( (size&3) || off > data_size ) return ERR_INVALID_DATA; if (func) { const int err = func(magic,s->data,size,user_ptr); if (err<0) return -err; if ( max_err < err ) max_err = err; } } return max_err; }