Blame


1 3448adb0 2022-11-02 op /* See LICENSE file for copyright and license details. */
2 3448adb0 2022-11-02 op #ifndef UTIL_H
3 3448adb0 2022-11-02 op #define UTIL_H
4 3448adb0 2022-11-02 op
5 3448adb0 2022-11-02 op #include <stdbool.h>
6 3448adb0 2022-11-02 op #include <stddef.h>
7 3448adb0 2022-11-02 op #include <stdint.h>
8 3448adb0 2022-11-02 op
9 3448adb0 2022-11-02 op #include "../gen/types.h"
10 3448adb0 2022-11-02 op #include "../grapheme.h"
11 3448adb0 2022-11-02 op
12 3448adb0 2022-11-02 op #undef MIN
13 3448adb0 2022-11-02 op #define MIN(x,y) ((x) < (y) ? (x) : (y))
14 3448adb0 2022-11-02 op #undef LEN
15 3448adb0 2022-11-02 op #define LEN(x) (sizeof(x) / sizeof(*(x)))
16 3448adb0 2022-11-02 op
17 3448adb0 2022-11-02 op #undef likely
18 3448adb0 2022-11-02 op #undef unlikely
19 3448adb0 2022-11-02 op #ifdef __has_builtin
20 3448adb0 2022-11-02 op #if __has_builtin(__builtin_expect)
21 3448adb0 2022-11-02 op #define likely(expr) __builtin_expect(!!(expr), 1)
22 3448adb0 2022-11-02 op #define unlikely(expr) __builtin_expect(!!(expr), 0)
23 3448adb0 2022-11-02 op #else
24 3448adb0 2022-11-02 op #define likely(expr) (expr)
25 3448adb0 2022-11-02 op #define unlikely(expr) (expr)
26 3448adb0 2022-11-02 op #endif
27 3448adb0 2022-11-02 op #else
28 3448adb0 2022-11-02 op #define likely(expr) (expr)
29 3448adb0 2022-11-02 op #define unlikely(expr) (expr)
30 3448adb0 2022-11-02 op #endif
31 3448adb0 2022-11-02 op
32 3448adb0 2022-11-02 op /*
33 3448adb0 2022-11-02 op * Herodotus, the ancient greek historian and geographer,
34 3448adb0 2022-11-02 op * was criticized for including legends and other fantastic
35 3448adb0 2022-11-02 op * accounts into his works, among others by his contemporary
36 3448adb0 2022-11-02 op * Thucydides.
37 3448adb0 2022-11-02 op *
38 3448adb0 2022-11-02 op * The Herodotus readers and writers are tailored towards the needs
39 3448adb0 2022-11-02 op * of the library interface, doing all the dirty work behind the
40 3448adb0 2022-11-02 op * scenes. While the reader is relatively faithful in his accounts,
41 3448adb0 2022-11-02 op * the Herodotus writer will never fail and always claim to write the
42 3448adb0 2022-11-02 op * data. Internally, it only writes as much as it can, and will simply
43 3448adb0 2022-11-02 op * keep account of the rest. This way, we can properly signal truncation.
44 3448adb0 2022-11-02 op *
45 3448adb0 2022-11-02 op * In this sense, explaining the naming, the writer is always a bit
46 3448adb0 2022-11-02 op * inaccurate in his accounts.
47 3448adb0 2022-11-02 op *
48 3448adb0 2022-11-02 op */
49 3448adb0 2022-11-02 op enum herodotus_status {
50 3448adb0 2022-11-02 op HERODOTUS_STATUS_SUCCESS,
51 3448adb0 2022-11-02 op HERODOTUS_STATUS_END_OF_BUFFER,
52 3448adb0 2022-11-02 op HERODOTUS_STATUS_SOFT_LIMIT_REACHED,
53 3448adb0 2022-11-02 op };
54 3448adb0 2022-11-02 op
55 3448adb0 2022-11-02 op enum herodotus_type {
56 3448adb0 2022-11-02 op HERODOTUS_TYPE_CODEPOINT,
57 3448adb0 2022-11-02 op HERODOTUS_TYPE_UTF8,
58 3448adb0 2022-11-02 op };
59 3448adb0 2022-11-02 op
60 3448adb0 2022-11-02 op typedef struct herodotus_reader {
61 3448adb0 2022-11-02 op enum herodotus_type type;
62 3448adb0 2022-11-02 op const void *src;
63 3448adb0 2022-11-02 op size_t srclen;
64 3448adb0 2022-11-02 op size_t off;
65 3448adb0 2022-11-02 op bool terminated_by_null;
66 3448adb0 2022-11-02 op size_t soft_limit[10];
67 3448adb0 2022-11-02 op } HERODOTUS_READER;
68 3448adb0 2022-11-02 op
69 3448adb0 2022-11-02 op typedef struct herodotus_writer {
70 3448adb0 2022-11-02 op enum herodotus_type type;
71 3448adb0 2022-11-02 op void *dest;
72 3448adb0 2022-11-02 op size_t destlen;
73 3448adb0 2022-11-02 op size_t off;
74 3448adb0 2022-11-02 op size_t first_unwritable_offset;
75 3448adb0 2022-11-02 op } HERODOTUS_WRITER;
76 3448adb0 2022-11-02 op
77 3448adb0 2022-11-02 op struct proper {
78 3448adb0 2022-11-02 op /*
79 3448adb0 2022-11-02 op * prev_prop[1] prev_prop[0] | next_prop[0] next_prop[1]
80 3448adb0 2022-11-02 op */
81 3448adb0 2022-11-02 op struct {
82 3448adb0 2022-11-02 op uint_least8_t prev_prop[2];
83 3448adb0 2022-11-02 op uint_least8_t next_prop[2];
84 3448adb0 2022-11-02 op } raw, skip;
85 3448adb0 2022-11-02 op HERODOTUS_READER mid_reader, raw_reader, skip_reader;
86 3448adb0 2022-11-02 op void *state;
87 3448adb0 2022-11-02 op uint_least8_t no_prop;
88 3448adb0 2022-11-02 op uint_least8_t (*get_break_prop)(uint_least32_t);
89 3448adb0 2022-11-02 op bool (*is_skippable_prop)(uint_least8_t);
90 3448adb0 2022-11-02 op void (*skip_shift_callback)(uint_least8_t, void *);
91 3448adb0 2022-11-02 op };
92 3448adb0 2022-11-02 op
93 3448adb0 2022-11-02 op void herodotus_reader_init(HERODOTUS_READER *, enum herodotus_type,
94 3448adb0 2022-11-02 op const void *, size_t);
95 3448adb0 2022-11-02 op void herodotus_reader_copy(const HERODOTUS_READER *, HERODOTUS_READER *);
96 3448adb0 2022-11-02 op void herodotus_reader_push_advance_limit(HERODOTUS_READER *, size_t);
97 3448adb0 2022-11-02 op void herodotus_reader_pop_limit(HERODOTUS_READER *);
98 3448adb0 2022-11-02 op size_t herodotus_reader_number_read(const HERODOTUS_READER *);
99 3448adb0 2022-11-02 op size_t herodotus_reader_next_word_break(const HERODOTUS_READER *);
100 3448adb0 2022-11-02 op size_t herodotus_reader_next_codepoint_break(const HERODOTUS_READER *);
101 3448adb0 2022-11-02 op enum herodotus_status herodotus_read_codepoint(HERODOTUS_READER *, bool, uint_least32_t *);
102 3448adb0 2022-11-02 op
103 3448adb0 2022-11-02 op void herodotus_writer_init(HERODOTUS_WRITER *, enum herodotus_type, void *,
104 3448adb0 2022-11-02 op size_t);
105 3448adb0 2022-11-02 op void herodotus_writer_nul_terminate(HERODOTUS_WRITER *);
106 3448adb0 2022-11-02 op size_t herodotus_writer_number_written(const HERODOTUS_WRITER *);
107 3448adb0 2022-11-02 op void herodotus_write_codepoint(HERODOTUS_WRITER *, uint_least32_t);
108 3448adb0 2022-11-02 op
109 3448adb0 2022-11-02 op void proper_init(const HERODOTUS_READER *, void *, uint_least8_t,
110 3448adb0 2022-11-02 op uint_least8_t (*get_break_prop)(uint_least32_t),
111 3448adb0 2022-11-02 op bool (*is_skippable_prop)(uint_least8_t),
112 3448adb0 2022-11-02 op void (*skip_shift_callback)(uint_least8_t, void *),
113 3448adb0 2022-11-02 op struct proper *);
114 3448adb0 2022-11-02 op int proper_advance(struct proper *);
115 3448adb0 2022-11-02 op
116 3448adb0 2022-11-02 op #endif /* UTIL_H */