ruxml 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/ruxml/array.cpp +71 -0
- data/ext/ruxml/array.hpp +35 -0
- data/ext/ruxml/extconf.rb +5 -0
- data/ext/ruxml/memory.cpp +222 -0
- data/ext/ruxml/memory.hpp +112 -0
- data/ext/ruxml/parser.cpp +490 -0
- data/ext/ruxml/parser.hpp +140 -0
- data/ext/ruxml/ruxml.cpp +273 -0
- data/ext/ruxml/str.cpp +216 -0
- data/ext/ruxml/str.hpp +111 -0
- data/lib/ruxml.rb +6 -0
- data/lib/ruxml/parse_error.rb +9 -0
- data/lib/ruxml/parser.rb +25 -0
- data/lib/ruxml/version.rb +3 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3312e4cba85d6ff2f87e2b93666d238b847a7ae5e2b3bc4c7f35d5c1ec4e032d
|
4
|
+
data.tar.gz: 779aceed144556171266de69e7c25da243e4aceb2ef420e9403364c202b19df9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0c43d9ca1e0ccfdb9572eda68b44a5a64200e414c310180ae23540b7322c5fa12ccee400b54ceb421e2ab1631bc27b824292d287a4081bc8c38dcfaaa2b42ba7
|
7
|
+
data.tar.gz: dd53724faed49fb93ff1caaa643575f4cc438b76d4bdf0366578abbe974a110681bb22dd5ad3dcb24927291f5b2911d151bafb6b778239a945dbf916d9f8b409
|
data/ext/ruxml/array.cpp
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#include <cassert>
|
2
|
+
#include <cstring>
|
3
|
+
|
4
|
+
#include "array.hpp"
|
5
|
+
|
6
|
+
void aclear(void* array) {
|
7
|
+
if (array) ahdr((array))->len = 0;
|
8
|
+
}
|
9
|
+
|
10
|
+
void *ainit_(void *array, Allocator *allocator) {
|
11
|
+
if (array) {
|
12
|
+
ahdr(array)->allocator = allocator;
|
13
|
+
return array;
|
14
|
+
} else {
|
15
|
+
auto hdr = allocate_type(allocator, ArrayHeader);
|
16
|
+
hdr->allocator = allocator;
|
17
|
+
hdr->len = 0;
|
18
|
+
hdr->cap = 0;
|
19
|
+
return &hdr->buffer;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
void afree_(void *array) {
|
24
|
+
if (array) allocate_free(ahdr(array)->allocator, ahdr(array));
|
25
|
+
}
|
26
|
+
|
27
|
+
void *asetcap_(void *array, uint32_t new_cap, uint32_t element_size) {
|
28
|
+
auto hdr = array ? ahdr(array) : nullptr;
|
29
|
+
|
30
|
+
uint32_t new_len = hdr ? (hdr->len < new_cap ? hdr->len : new_cap) : 0;
|
31
|
+
uint32_t mem_size = sizeof(ArrayHeader) + new_cap * element_size;
|
32
|
+
|
33
|
+
if (array) {
|
34
|
+
auto old_hdr = hdr;
|
35
|
+
hdr = (ArrayHeader *) allocate_size(old_hdr->allocator, mem_size);
|
36
|
+
hdr->allocator = old_hdr->allocator;
|
37
|
+
hdr->len = new_len;
|
38
|
+
hdr->cap = new_cap;
|
39
|
+
memcpy(&hdr->buffer, array, new_len * element_size);
|
40
|
+
allocate_free(hdr->allocator, old_hdr);
|
41
|
+
} else {
|
42
|
+
hdr = (ArrayHeader *) allocate_size(nullptr, sizeof(ArrayHeader) + new_cap * element_size);
|
43
|
+
hdr->allocator = nullptr;
|
44
|
+
hdr->len = new_len;
|
45
|
+
hdr->cap = new_cap;
|
46
|
+
}
|
47
|
+
|
48
|
+
return &hdr->buffer;
|
49
|
+
}
|
50
|
+
|
51
|
+
void *afit_(void *array, uint32_t count, uint32_t element_size) {
|
52
|
+
uint32_t capacity = acap(array);
|
53
|
+
if (count <= capacity) return array;
|
54
|
+
|
55
|
+
uint32_t new_capacity = capacity >= 6 ? (capacity + (capacity >> 1U)) : 8;
|
56
|
+
if (new_capacity < count) new_capacity = count;
|
57
|
+
|
58
|
+
return asetcap_(array, new_capacity, element_size);
|
59
|
+
}
|
60
|
+
|
61
|
+
void *acat_(void *array, void *other, uint32_t element_size) {
|
62
|
+
if (!other) return array;
|
63
|
+
if (!array) return other;
|
64
|
+
|
65
|
+
auto len = ahdr(array)->len;
|
66
|
+
auto other_len = ahdr(other)->len;
|
67
|
+
array = afit_(array, len + other_len, element_size);
|
68
|
+
memcpy((char *) array + len * element_size, other, other_len * element_size);
|
69
|
+
ahdr(array)->len += other_len;
|
70
|
+
return array;
|
71
|
+
}
|
data/ext/ruxml/array.hpp
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <cstdint>
|
4
|
+
#include <cstdlib>
|
5
|
+
#include <cstddef>
|
6
|
+
|
7
|
+
#include "memory.hpp"
|
8
|
+
|
9
|
+
struct ArrayHeader {
|
10
|
+
Allocator *allocator;
|
11
|
+
uint32_t len;
|
12
|
+
uint32_t cap;
|
13
|
+
char *buffer[1];
|
14
|
+
};
|
15
|
+
|
16
|
+
#define ahdr(array) ((ArrayHeader *)((char *)(array) - offsetof(ArrayHeader, buffer)))
|
17
|
+
#define alen(array) ((array) ? ahdr((array))->len : 0)
|
18
|
+
#define acap(array) ((array) ? ahdr((array))->cap : 0)
|
19
|
+
|
20
|
+
void aclear(void *array);
|
21
|
+
void *ainit_(void *array, Allocator *allocator = nullptr);
|
22
|
+
void afree_(void *array);
|
23
|
+
void *afit_(void *array, uint32_t count, uint32_t element_size);
|
24
|
+
void *asetcap_(void *array, uint32_t new_cap, uint32_t element_size);
|
25
|
+
void *acat_(void *array, void *other, uint32_t element_size);
|
26
|
+
|
27
|
+
#define ainit(array, ...) ((array) = (decltype(array))ainit_(array, __VA_ARGS__))
|
28
|
+
#define afree(array) (afree_((array)), (array) = nullptr)
|
29
|
+
#define asetcap(array, new_cap) ((array) = (decltype(array))asetcap_((array), (new_cap), sizeof(*(array))))
|
30
|
+
#define ashrink(array) ((array) = (decltype(array))asetcap_((array), alen((array)), sizeof(*(array))))
|
31
|
+
#define asetlen(array, new_len) ((array) = (decltype(array))afit_((array), new_len, sizeof(*array)), ahdr(array)->len = new_len)
|
32
|
+
#define aempty(array) (ahdr(array)->len = 0)
|
33
|
+
#define apush(array, item) ((array) = (decltype(array))afit_((array), alen(array) + 1, sizeof(*array)), array[ahdr(array)->len++] = (item))
|
34
|
+
#define adel(array, index) ((array)[(index)] = (array)[--ahdr((array))->len])
|
35
|
+
#define acat(array, other) ((array) = (decltype(array))acat_((array), (other), sizeof(*array)))
|
@@ -0,0 +1,222 @@
|
|
1
|
+
#include <cstring>
|
2
|
+
#include <cstdarg>
|
3
|
+
#include <cstdio>
|
4
|
+
|
5
|
+
#include "memory.hpp"
|
6
|
+
#include "str.hpp"
|
7
|
+
|
8
|
+
Allocator* temp_allocator = nullptr;
|
9
|
+
|
10
|
+
void *allocate_size_(void *data, size_t size) {
|
11
|
+
if (data) {
|
12
|
+
return ((Allocator *) data)->alloc(data, size);
|
13
|
+
} else {
|
14
|
+
return raw_allocate_size(size);
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
void allocate_free_(void *data, void *ptr) {
|
19
|
+
if (data) {
|
20
|
+
((Allocator *) data)->free(data, ptr);
|
21
|
+
} else {
|
22
|
+
raw_free(ptr);
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
#ifdef MEMORY_DEBUG2
|
27
|
+
void *alloc_size_(void *data, size_t size, const char *file, int line) {
|
28
|
+
printf("%s:%i ALLOC : %li\n", file, line, size);
|
29
|
+
alloc_size_(data, size);
|
30
|
+
}
|
31
|
+
|
32
|
+
void alloc_free_(void *data, void *ptr, const char *file, int line) {
|
33
|
+
printf("%s:%i FREE\n", file, line);
|
34
|
+
alloc_free_(data, ptr);
|
35
|
+
}
|
36
|
+
#endif
|
37
|
+
|
38
|
+
void arena_init(MemoryArena *arena, const char *name, Allocator *allocator) {
|
39
|
+
#ifdef MEMORY_DEBUG
|
40
|
+
arena->name = name;
|
41
|
+
printf("Arena init: %s\n", name);
|
42
|
+
#endif
|
43
|
+
|
44
|
+
arena->allocator.alloc = allocator_arena_alloc;
|
45
|
+
arena->allocator.free = allocator_noop_free;
|
46
|
+
arena->base_allocator = allocator;
|
47
|
+
arena->min_block_size = 8 * 1024 * 1024;
|
48
|
+
arena->block_first = nullptr;
|
49
|
+
arena->block_last = nullptr;
|
50
|
+
arena->free = nullptr;
|
51
|
+
}
|
52
|
+
|
53
|
+
void arena_clear(MemoryArena *arena) {
|
54
|
+
#ifdef MEMORY_INFO
|
55
|
+
arena->memory_allocated = 0;
|
56
|
+
#endif
|
57
|
+
|
58
|
+
if (arena->block_first) {
|
59
|
+
assert(arena->block_last);
|
60
|
+
arena->block_last->next = arena->free;
|
61
|
+
arena->free = arena->block_first;
|
62
|
+
arena->block_first = nullptr;
|
63
|
+
arena->block_last = nullptr;
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
void arena_destroy(MemoryArena *arena) {
|
68
|
+
#ifdef MEMORY_DEBUG
|
69
|
+
printf("Arena destroy: %s\n", arena->name);
|
70
|
+
#endif
|
71
|
+
while (arena->block_first) {
|
72
|
+
void *mem = arena->block_first;
|
73
|
+
arena->block_first = arena->block_first->next;
|
74
|
+
allocate_free(arena->base_allocator, mem);
|
75
|
+
}
|
76
|
+
|
77
|
+
while (arena->free) {
|
78
|
+
void *mem = arena->free;
|
79
|
+
arena->free = arena->free->next;
|
80
|
+
allocate_free(arena->base_allocator, mem);
|
81
|
+
}
|
82
|
+
|
83
|
+
arena->block_last = nullptr;
|
84
|
+
}
|
85
|
+
|
86
|
+
void arena_stats(MemoryArena *arena, uint64_t *allocated_ptr, uint64_t *used_ptr) {
|
87
|
+
uint64_t allocated = 0;
|
88
|
+
uint64_t used = 0;
|
89
|
+
|
90
|
+
auto block = arena->block_first;
|
91
|
+
while (block) {
|
92
|
+
allocated += block->size;
|
93
|
+
used += block->used;
|
94
|
+
block = block->next;
|
95
|
+
}
|
96
|
+
|
97
|
+
*allocated_ptr = allocated;
|
98
|
+
*used_ptr = used;
|
99
|
+
}
|
100
|
+
|
101
|
+
TempSection begin_temp_section(MemoryArena *arena) {
|
102
|
+
TempSection section = {};
|
103
|
+
|
104
|
+
if (!arena->block_first) {
|
105
|
+
arena_alloc_block(arena, 0);
|
106
|
+
}
|
107
|
+
|
108
|
+
auto block = arena->block_first;
|
109
|
+
block->temp_count++;
|
110
|
+
|
111
|
+
section.arena = arena;
|
112
|
+
section.block = block;
|
113
|
+
section.mark = block->used;
|
114
|
+
return section;
|
115
|
+
}
|
116
|
+
|
117
|
+
void end_temp_section(TempSection section) {
|
118
|
+
MemoryArena *arena = section.arena;
|
119
|
+
|
120
|
+
while (arena->block_first != section.block) {
|
121
|
+
assert(arena->block_first);
|
122
|
+
assert(arena->block_first->temp_count == 1);
|
123
|
+
void *mem = arena->block_first;
|
124
|
+
arena->block_first = arena->block_first->next;
|
125
|
+
free(mem);
|
126
|
+
}
|
127
|
+
assert(arena->block_first == section.block);
|
128
|
+
|
129
|
+
arena->block_first->used = section.mark;
|
130
|
+
arena->block_first->temp_count--;
|
131
|
+
}
|
132
|
+
|
133
|
+
void arena_alloc_block(MemoryArena *arena, size_t size) {
|
134
|
+
auto cur_block = arena->free;
|
135
|
+
MemoryArenaBlock *prev_block = nullptr;
|
136
|
+
while (cur_block) {
|
137
|
+
if (cur_block->size >= size) {
|
138
|
+
if (arena->free == cur_block) arena->free = cur_block->next;
|
139
|
+
if (prev_block) prev_block->next = cur_block->next;
|
140
|
+
cur_block->next = arena->block_first;
|
141
|
+
cur_block->used = 0;
|
142
|
+
if (arena->block_first) {
|
143
|
+
cur_block->temp_count = arena->block_first->temp_count;
|
144
|
+
} else {
|
145
|
+
arena->block_last = cur_block;
|
146
|
+
}
|
147
|
+
|
148
|
+
arena->block_first = cur_block;
|
149
|
+
return;
|
150
|
+
}
|
151
|
+
prev_block = cur_block;
|
152
|
+
cur_block = cur_block->next;
|
153
|
+
}
|
154
|
+
|
155
|
+
size_t required_size = arena->min_block_size > size ? arena->min_block_size : size;
|
156
|
+
|
157
|
+
size_t size_with_header = sizeof(MemoryArenaBlock) + required_size;
|
158
|
+
auto mem = (uint8_t *) raw_allocate_size_zero(size_with_header);
|
159
|
+
auto header = (MemoryArenaBlock *) mem;
|
160
|
+
header->data = mem + sizeof(MemoryArenaBlock);
|
161
|
+
header->size = required_size;
|
162
|
+
|
163
|
+
if (arena->block_first) {
|
164
|
+
header->temp_count = arena->block_first->temp_count;
|
165
|
+
}
|
166
|
+
|
167
|
+
header->next = arena->block_first;
|
168
|
+
arena->block_first = header;
|
169
|
+
if (!arena->block_last) arena->block_last = arena->block_first;
|
170
|
+
}
|
171
|
+
|
172
|
+
void *arena_alloc(MemoryArena *arena, size_t size) {
|
173
|
+
#ifdef MEMORY_INFO
|
174
|
+
arena->memory_allocated += size;
|
175
|
+
#endif
|
176
|
+
|
177
|
+
if (!arena->block_first || (arena->block_first->used + size > arena->block_first->size)) {
|
178
|
+
arena_alloc_block(arena, size);
|
179
|
+
}
|
180
|
+
assert(arena->block_first);
|
181
|
+
assert(arena->block_last);
|
182
|
+
assert(arena->block_first->used + size <= arena->block_first->size);
|
183
|
+
|
184
|
+
auto mem = arena->block_first->data + arena->block_first->used;
|
185
|
+
arena->block_first->used += size;
|
186
|
+
|
187
|
+
return mem;
|
188
|
+
}
|
189
|
+
|
190
|
+
char *zstr_dup(Allocator *allocator, const char *str, int64_t size) {
|
191
|
+
auto *buffer = (char *) allocate_size(allocator, size + 1);
|
192
|
+
memcpy(buffer, str, sizeof(char) * size);
|
193
|
+
return buffer;
|
194
|
+
}
|
195
|
+
|
196
|
+
char *zstr_dup(Allocator *allocator, const char *str) {
|
197
|
+
return zstr_dup(allocator, str, zstr_length(str));
|
198
|
+
}
|
199
|
+
|
200
|
+
char *zstr_print(Allocator *allocator, const char *fmt, ...) {
|
201
|
+
char buffer[1024];
|
202
|
+
const size_t buffer_size = array_size(buffer);
|
203
|
+
|
204
|
+
va_list v;
|
205
|
+
va_start(v, fmt);
|
206
|
+
auto res = vsnprintf(buffer, buffer_size, fmt, v);
|
207
|
+
va_end(v);
|
208
|
+
assert(res >= 0);
|
209
|
+
if (res < buffer_size) {
|
210
|
+
buffer[res] = 0;
|
211
|
+
return zstr_dup(allocator, buffer, res + 1);
|
212
|
+
}
|
213
|
+
|
214
|
+
auto long_size = static_cast<size_t>(res + 1);
|
215
|
+
auto long_buffer = (char *) allocate_size(allocator, long_size);
|
216
|
+
va_start(v, fmt);
|
217
|
+
vsnprintf(long_buffer, long_size, fmt, v);
|
218
|
+
va_end(v);
|
219
|
+
|
220
|
+
long_buffer[res] = 0;
|
221
|
+
return long_buffer;
|
222
|
+
}
|
@@ -0,0 +1,112 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <cstdlib>
|
4
|
+
#include <cassert>
|
5
|
+
#include <cstdint>
|
6
|
+
#include <cstdio>
|
7
|
+
|
8
|
+
#define array_size(_arr) ((int)(sizeof(_arr)/sizeof(*(_arr))))
|
9
|
+
|
10
|
+
#define raw_allocate_size(size) (malloc(size))
|
11
|
+
#define raw_allocate_size_zero(size) (calloc(1, size))
|
12
|
+
#define raw_allocate_type(type) ((type *) malloc(sizeof(type)))
|
13
|
+
#define raw_allocate_type_zero(type) ((type *) calloc(1, sizeof(type)))
|
14
|
+
#define raw_allocate_array(type, size) ((type *) malloc(sizeof(type) * size))
|
15
|
+
#define raw_allocate_string(size) ((char *) malloc(sizeof(char)*size))
|
16
|
+
#define raw_allocate_string_zt(size) ((char *) calloc(1, sizeof(char)*(size+1)))
|
17
|
+
#define raw_free(ptr) (free(ptr))
|
18
|
+
|
19
|
+
/// ALLOCATOR
|
20
|
+
|
21
|
+
using AllocatorAllocFunc = void *(*)(void *data, size_t size);
|
22
|
+
using AllocatorFreeFunc = void (*)(void *data, void *ptr);
|
23
|
+
|
24
|
+
struct Allocator {
|
25
|
+
AllocatorAllocFunc alloc;
|
26
|
+
AllocatorFreeFunc free;
|
27
|
+
};
|
28
|
+
|
29
|
+
inline void *allocator_raw_alloc(void *data, size_t size) {
|
30
|
+
return raw_allocate_size(size);
|
31
|
+
}
|
32
|
+
|
33
|
+
inline void allocator_raw_free(void *data, void *ptr) {
|
34
|
+
raw_free(ptr);
|
35
|
+
}
|
36
|
+
|
37
|
+
inline void allocator_noop_free(void *data, void *ptr) {
|
38
|
+
}
|
39
|
+
|
40
|
+
static Allocator raw_allocator = {allocator_raw_alloc, allocator_raw_free};
|
41
|
+
|
42
|
+
inline Allocator *make_raw_allocator() { return &raw_allocator; }
|
43
|
+
|
44
|
+
void *allocate_size_(void *data, size_t size);
|
45
|
+
void allocate_free_(void *data, void *ptr);
|
46
|
+
|
47
|
+
#define allocate_size(allocator, size) (allocate_size_(allocator, size))
|
48
|
+
#define allocate_type(allocator, type) ((type*)allocate_size_(allocator, sizeof(type)))
|
49
|
+
#define allocate_array(allocator, type, count) ((type*)allocate_size_(allocator, sizeof(type) * (count)))
|
50
|
+
#define allocate_string(allocator, size) ((char *)allocate_size_(allocator, size))
|
51
|
+
#define allocate_zstring(allocator, size) ((char *)allocate_size_(allocator, size + 1))
|
52
|
+
#define allocate_free(allocator, ptr) (allocate_free_(allocator, ptr))
|
53
|
+
|
54
|
+
/// ARENA
|
55
|
+
|
56
|
+
struct MemoryArenaBlock {
|
57
|
+
size_t used;
|
58
|
+
size_t size;
|
59
|
+
MemoryArenaBlock *next;
|
60
|
+
|
61
|
+
uint8_t temp_count;
|
62
|
+
uint8_t *data;
|
63
|
+
};
|
64
|
+
|
65
|
+
struct MemoryArena {
|
66
|
+
Allocator allocator;
|
67
|
+
Allocator *base_allocator;
|
68
|
+
size_t min_block_size;
|
69
|
+
MemoryArenaBlock *block_first;
|
70
|
+
MemoryArenaBlock *block_last;
|
71
|
+
MemoryArenaBlock *free;
|
72
|
+
|
73
|
+
#ifdef MEMORY_INFO
|
74
|
+
size_t memory_allocated;
|
75
|
+
#endif
|
76
|
+
|
77
|
+
#ifdef MEMORY_DEBUG
|
78
|
+
const char *name;
|
79
|
+
#endif
|
80
|
+
};
|
81
|
+
|
82
|
+
struct TempSection {
|
83
|
+
MemoryArena *arena;
|
84
|
+
MemoryArenaBlock *block;
|
85
|
+
size_t mark;
|
86
|
+
};
|
87
|
+
|
88
|
+
void arena_init(MemoryArena *arena, const char *name, Allocator *allocator = make_raw_allocator());
|
89
|
+
void arena_clear(MemoryArena *arena);
|
90
|
+
void arena_destroy(MemoryArena *arena);
|
91
|
+
void arena_stats(MemoryArena *arena, uint64_t *allocated_ptr, uint64_t *used_ptr);
|
92
|
+
void arena_alloc_block(MemoryArena *arena, size_t size);
|
93
|
+
void *arena_alloc(MemoryArena *arena, size_t size);
|
94
|
+
|
95
|
+
#define arena_alloc_type(allocator, type) ((type*)arena_alloc(allocator, sizeof(type)))
|
96
|
+
|
97
|
+
inline Allocator *arena_allocator(MemoryArena *arena) { return (Allocator *) (void *) arena; }
|
98
|
+
|
99
|
+
TempSection begin_temp_section(MemoryArena *arena);
|
100
|
+
void end_temp_section(TempSection section);
|
101
|
+
|
102
|
+
inline void *allocator_arena_alloc(void *data, size_t size) {
|
103
|
+
return arena_alloc((MemoryArena *) data, size);
|
104
|
+
}
|
105
|
+
|
106
|
+
extern Allocator* temp_allocator;
|
107
|
+
|
108
|
+
/// STRING
|
109
|
+
|
110
|
+
char *zstr_dup(Allocator *allocator, const char *str, int64_t size);
|
111
|
+
char *zstr_dup(Allocator *allocator, const char *str);
|
112
|
+
char *zstr_print(Allocator *allocator, const char *fmt, ...);
|