File Coverage

include/pdfmake_tokenizer.h
Criterion Covered Total %
statement 2 2 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 2 2 100.0


line stmt bran cond sub pod time code
1             /*
2             * pdfmake_tokenizer.h — PDF lexical tokenizer per §7.2
3             *
4             * Splits a raw PDF byte buffer into tokens:
5             * (kind, start_offset, length, payload)
6             *
7             * This is the innermost hot loop of parsing — keep it fast and tight.
8             */
9              
10             #ifndef PDFMAKE_TOKENIZER_H
11             #define PDFMAKE_TOKENIZER_H
12              
13             #include
14             #include
15             #include "pdfmake_types.h"
16              
17             /*============================================================================
18             * Token kinds — per §7.2 lexical conventions
19             *==========================================================================*/
20              
21             typedef enum {
22             PDFMAKE_TOK_EOF = 0, /* End of input */
23             PDFMAKE_TOK_WS, /* Whitespace (§7.2.2) */
24             PDFMAKE_TOK_COMMENT, /* Comment % through EOL (§7.2.3) */
25              
26             /* Scalars */
27             PDFMAKE_TOK_INT, /* Integer: optional sign + digits */
28             PDFMAKE_TOK_REAL, /* Real: fixed-point with decimal point */
29             PDFMAKE_TOK_NAME, /* /Name (§7.3.5) */
30             PDFMAKE_TOK_LSTR, /* Literal string (string) (§7.3.4.2) */
31             PDFMAKE_TOK_HSTR, /* Hex string (§7.3.4.3) */
32              
33             /* Delimiters */
34             PDFMAKE_TOK_ARR_OPEN, /* [ */
35             PDFMAKE_TOK_ARR_CLOSE, /* ] */
36             PDFMAKE_TOK_DICT_OPEN, /* << */
37             PDFMAKE_TOK_DICT_CLOSE, /* >> */
38              
39             /* Keywords */
40             PDFMAKE_TOK_KW_NULL, /* null */
41             PDFMAKE_TOK_KW_TRUE, /* true */
42             PDFMAKE_TOK_KW_FALSE, /* false */
43             PDFMAKE_TOK_KW_OBJ, /* obj */
44             PDFMAKE_TOK_KW_ENDOBJ, /* endobj */
45             PDFMAKE_TOK_KW_STREAM, /* stream (followed by stream body) */
46             PDFMAKE_TOK_KW_ENDSTREAM, /* endstream */
47             PDFMAKE_TOK_KW_R, /* R (indirect reference marker) */
48             PDFMAKE_TOK_KW_XREF, /* xref */
49             PDFMAKE_TOK_KW_TRAILER, /* trailer */
50             PDFMAKE_TOK_KW_STARTXREF, /* startxref */
51              
52             /* Error */
53             PDFMAKE_TOK_ERROR /* Unexpected byte / malformed token */
54             } pdfmake_tok_kind_t;
55              
56             /*============================================================================
57             * Token structure — keep small (fits in register pair)
58             *==========================================================================*/
59              
60             typedef struct {
61             pdfmake_tok_kind_t kind; /* Token type */
62             size_t offset; /* Byte offset in source buffer */
63             size_t length; /* Byte length of token */
64             /* For STREAM tokens, payload is offset where stream body starts */
65             /* For numbers, the raw bytes can be re-parsed from offset/length */
66             union {
67             int64_t int_val; /* Parsed integer value */
68             double real_val; /* Parsed real value */
69             size_t body_offset; /* Stream body start offset */
70             } payload;
71             } pdfmake_tok_t;
72              
73             /*============================================================================
74             * Tokenizer state
75             *==========================================================================*/
76              
77             typedef struct {
78             const uint8_t *buf; /* Source buffer (not owned) */
79             size_t pos; /* Current position */
80             size_t len; /* Buffer length */
81              
82             /* Peek state (for O(1) lookahead) */
83             pdfmake_tok_t peeked;
84             int has_peeked;
85             } pdfmake_tokenizer_t;
86              
87             /*============================================================================
88             * API
89             *==========================================================================*/
90              
91             /*
92             * Initialize tokenizer with a byte buffer.
93             * The buffer is not copied — caller must keep it alive.
94             */
95             void pdfmake_tokenizer_init(pdfmake_tokenizer_t *t,
96             const uint8_t *buf, size_t len);
97              
98             /*
99             * Get the next token.
100             * Returns PDFMAKE_TOK_EOF when no more tokens.
101             */
102             pdfmake_tok_t pdfmake_tok_next(pdfmake_tokenizer_t *t);
103              
104             /*
105             * Peek at the next token without consuming it.
106             * O(1) — caches the result.
107             */
108             void pdfmake_tok_peek(pdfmake_tokenizer_t *t, pdfmake_tok_t *out);
109              
110             /*
111             * Get next significant token (skips whitespace and comments).
112             */
113             pdfmake_tok_t pdfmake_tok_next_significant(pdfmake_tokenizer_t *t);
114              
115             /*
116             * Peek at next significant token.
117             */
118             void pdfmake_tok_peek_significant(pdfmake_tokenizer_t *t, pdfmake_tok_t *out);
119              
120             /*
121             * Get token kind name for debugging.
122             */
123             const char *pdfmake_tok_kind_name(pdfmake_tok_kind_t kind);
124              
125             /*
126             * Skip to position (for seeking after reading stream body).
127             */
128             void pdfmake_tokenizer_seek(pdfmake_tokenizer_t *t, size_t pos);
129              
130             /*============================================================================
131             * Character classification (exported for tests)
132             *==========================================================================*/
133              
134             /* Character class bits */
135             #define PDFMAKE_CC_REGULAR 0x00 /* Regular character */
136             #define PDFMAKE_CC_WHITESPACE 0x01 /* NUL, TAB, LF, FF, CR, SPACE (§7.2.2) */
137             #define PDFMAKE_CC_DELIMITER 0x02 /* ( ) < > [ ] { } / % (§7.2.2) */
138             #define PDFMAKE_CC_DIGIT 0x04 /* 0-9 */
139             #define PDFMAKE_CC_HEX 0x08 /* 0-9 A-F a-f */
140             #define PDFMAKE_CC_ALPHA 0x10 /* A-Z a-z */
141             #define PDFMAKE_CC_SIGN 0x20 /* + - */
142              
143             /* Character class lookup table */
144             extern const uint8_t pdfmake_char_class[256];
145              
146             /* Inline helpers */
147 14581           static PDFMAKE_INLINE int pdfmake_is_whitespace(uint8_t c) {
148 14581           return (pdfmake_char_class[c] & PDFMAKE_CC_WHITESPACE) != 0;
149             }
150              
151             static PDFMAKE_INLINE int pdfmake_is_delimiter(uint8_t c) {
152             return (pdfmake_char_class[c] & PDFMAKE_CC_DELIMITER) != 0;
153             }
154              
155             static PDFMAKE_INLINE int pdfmake_is_digit(uint8_t c) {
156             return (pdfmake_char_class[c] & PDFMAKE_CC_DIGIT) != 0;
157             }
158              
159             static PDFMAKE_INLINE int pdfmake_is_hex(uint8_t c) {
160             return (pdfmake_char_class[c] & PDFMAKE_CC_HEX) != 0;
161             }
162              
163             static PDFMAKE_INLINE int pdfmake_is_regular(uint8_t c) {
164             return (pdfmake_char_class[c] & (PDFMAKE_CC_WHITESPACE | PDFMAKE_CC_DELIMITER)) == 0;
165             }
166              
167             #endif /* PDFMAKE_TOKENIZER_H */