1 /*
2 * Copyright (C) 2018 Alexander Borisov
3 *
4 * Author: Alexander Borisov <borisov@lexbor.com>
5 */
6
7 #ifndef LEXBOR_IN_H
8 #define LEXBOR_IN_H
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 #include "lexbor/core/base.h"
15 #include "lexbor/core/dobject.h"
16
17
18 typedef struct lexbor_in_node lexbor_in_node_t;
19 typedef int lexbor_in_opt_t;
20
21 enum lexbor_in_opt {
22 LEXBOR_IN_OPT_UNDEF = 0x00,
23 LEXBOR_IN_OPT_READONLY = 0x01,
24 LEXBOR_IN_OPT_DONE = 0x02,
25 LEXBOR_IN_OPT_FAKE = 0x04,
26 LEXBOR_IN_OPT_ALLOC = 0x08
27 };
28
29 typedef struct {
30 lexbor_dobject_t *nodes;
31 }
32 lexbor_in_t;
33
34 struct lexbor_in_node {
35 size_t offset;
36 lexbor_in_opt_t opt;
37
38 const lxb_char_t *begin;
39 const lxb_char_t *end;
40 const lxb_char_t *use;
41
42 lexbor_in_node_t *next;
43 lexbor_in_node_t *prev;
44
45 lexbor_in_t *incoming;
46 };
47
48
49 LXB_API lexbor_in_t *
50 lexbor_in_create(void);
51
52 LXB_API lxb_status_t
53 lexbor_in_init(lexbor_in_t *incoming, size_t chunk_size);
54
55 LXB_API void
56 lexbor_in_clean(lexbor_in_t *incoming);
57
58 LXB_API lexbor_in_t *
59 lexbor_in_destroy(lexbor_in_t *incoming, bool self_destroy);
60
61
62 LXB_API lexbor_in_node_t *
63 lexbor_in_node_make(lexbor_in_t *incoming, lexbor_in_node_t *last_node,
64 const lxb_char_t *buf, size_t buf_size);
65
66 LXB_API void
67 lexbor_in_node_clean(lexbor_in_node_t *node);
68
69 LXB_API lexbor_in_node_t *
70 lexbor_in_node_destroy(lexbor_in_t *incoming,
71 lexbor_in_node_t *node, bool self_destroy);
72
73
74 LXB_API lexbor_in_node_t *
75 lexbor_in_node_split(lexbor_in_node_t *node, const lxb_char_t *pos);
76
77 LXB_API lexbor_in_node_t *
78 lexbor_in_node_find(lexbor_in_node_t *node, const lxb_char_t *pos);
79
80 /**
81 * Get position by `offset`.
82 * If position outside of nodes return `begin` position of first node
83 * in nodes chain.
84 */
85 LXB_API const lxb_char_t *
86 lexbor_in_node_pos_up(lexbor_in_node_t *node, lexbor_in_node_t **return_node,
87 const lxb_char_t *pos, size_t offset);
88
89 /**
90 * Get position by `offset`.
91 * If position outside of nodes return `end`
92 * position of last node in nodes chain.
93 */
94 LXB_API const lxb_char_t *
95 lexbor_in_node_pos_down(lexbor_in_node_t *node, lexbor_in_node_t **return_node,
96 const lxb_char_t *pos, size_t offset);
97
98 /*
99 * Inline functions
100 */
101 lxb_inline const lxb_char_t *
lexbor_in_node_begin(const lexbor_in_node_t * node)102 lexbor_in_node_begin(const lexbor_in_node_t *node)
103 {
104 return node->begin;
105 }
106
107 lxb_inline const lxb_char_t *
lexbor_in_node_end(const lexbor_in_node_t * node)108 lexbor_in_node_end(const lexbor_in_node_t *node)
109 {
110 return node->end;
111 }
112
113 lxb_inline size_t
lexbor_in_node_offset(const lexbor_in_node_t * node)114 lexbor_in_node_offset(const lexbor_in_node_t *node)
115 {
116 return node->offset;
117 }
118
119 lxb_inline lexbor_in_node_t *
lexbor_in_node_next(const lexbor_in_node_t * node)120 lexbor_in_node_next(const lexbor_in_node_t *node)
121 {
122 return node->next;
123 }
124
125 lxb_inline lexbor_in_node_t *
lexbor_in_node_prev(const lexbor_in_node_t * node)126 lexbor_in_node_prev(const lexbor_in_node_t *node)
127 {
128 return node->prev;
129 }
130
131 lxb_inline lexbor_in_t *
lexbor_in_node_in(const lexbor_in_node_t * node)132 lexbor_in_node_in(const lexbor_in_node_t *node)
133 {
134 return node->incoming;
135 }
136
137 lxb_inline bool
lexbor_in_segment(const lexbor_in_node_t * node,const lxb_char_t * data)138 lexbor_in_segment(const lexbor_in_node_t *node, const lxb_char_t *data)
139 {
140 return node->begin <= data && node->end >= data;
141 }
142
143 /*
144 * No inline functions for ABI.
145 */
146 LXB_API const lxb_char_t *
147 lexbor_in_node_begin_noi(const lexbor_in_node_t *node);
148
149 LXB_API const lxb_char_t *
150 lexbor_in_node_end_noi(const lexbor_in_node_t *node);
151
152 LXB_API size_t
153 lexbor_in_node_offset_noi(const lexbor_in_node_t *node);
154
155 LXB_API lexbor_in_node_t *
156 lexbor_in_node_next_noi(const lexbor_in_node_t *node);
157
158 LXB_API lexbor_in_node_t *
159 lexbor_in_node_prev_noi(const lexbor_in_node_t *node);
160
161 LXB_API lexbor_in_t *
162 lexbor_in_node_in_noi(const lexbor_in_node_t *node);
163
164 LXB_API bool
165 lexbor_in_segment_noi(const lexbor_in_node_t *node, const lxb_char_t *data);
166
167
168 #ifdef __cplusplus
169 } /* extern "C" */
170 #endif
171
172 #endif /* LEXBOR_IN_H */
173