hikari_buffer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +15 -0
- data/CODE_OF_CONDUCT.md +10 -0
- data/LICENSE.txt +21 -0
- data/README.md +146 -0
- data/Rakefile +44 -0
- data/bench/growth_stress.rb +17 -0
- data/bench/marshal.rb +33 -0
- data/bench/mixed_workload.rb +31 -0
- data/bench/protocol.rb +21 -0
- data/bench/read_bytes.rb +16 -0
- data/bench/read_string.rb +16 -0
- data/bench/sequential_packet.rb +31 -0
- data/bench/stringio.rb +23 -0
- data/bench/write_bytes.rb +21 -0
- data/bench/write_string.rb +21 -0
- data/bench/write_u32.rb +14 -0
- data/ext/hikari_buffer/buffer.c +517 -0
- data/ext/hikari_buffer/buffer.h +15 -0
- data/ext/hikari_buffer/convert.c +141 -0
- data/ext/hikari_buffer/convert.h +38 -0
- data/ext/hikari_buffer/extconf.rb +10 -0
- data/ext/hikari_buffer/hikari_buffer.c +12 -0
- data/ext/hikari_buffer/hikari_buffer.h +9 -0
- data/ext/hikari_buffer/io.c +64 -0
- data/ext/hikari_buffer/io.h +12 -0
- data/lib/hikari_buffer/version.rb +5 -0
- data/lib/hikari_buffer.rb +9 -0
- data/sig/hikari_buffer.rbs +4 -0
- metadata +74 -0
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
#include "buffer.h"
|
|
2
|
+
#include "convert.h"
|
|
3
|
+
#include "io.h"
|
|
4
|
+
#include <ruby/encoding.h>
|
|
5
|
+
static VALUE
|
|
6
|
+
buffer_alloc(VALUE klass);
|
|
7
|
+
|
|
8
|
+
#define BUFFER_INITIAL_CAPACITY 1024
|
|
9
|
+
|
|
10
|
+
#define DEFINE_WRITE_METHOD(NAME, TYPE, CONVERTER) \
|
|
11
|
+
static VALUE \
|
|
12
|
+
buffer_write_##NAME(VALUE self, VALUE val) \
|
|
13
|
+
{ \
|
|
14
|
+
Buffer *buffer = get_buffer_struct(self); \
|
|
15
|
+
TYPE value = CONVERTER(val); \
|
|
16
|
+
\
|
|
17
|
+
buffer_write( \
|
|
18
|
+
buffer, \
|
|
19
|
+
&value, \
|
|
20
|
+
sizeof(value)); \
|
|
21
|
+
\
|
|
22
|
+
return self; \
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
#define DEFINE_READ_METHOD(NAME, TYPE, CONVERTER) \
|
|
26
|
+
static VALUE \
|
|
27
|
+
buffer_read_##NAME(VALUE self) \
|
|
28
|
+
{ \
|
|
29
|
+
Buffer *buffer = get_buffer_struct(self); \
|
|
30
|
+
TYPE value; \
|
|
31
|
+
\
|
|
32
|
+
buffer_read( \
|
|
33
|
+
buffer, \
|
|
34
|
+
&value, \
|
|
35
|
+
sizeof(value)); \
|
|
36
|
+
\
|
|
37
|
+
return CONVERTER(value); \
|
|
38
|
+
}
|
|
39
|
+
#define DEFINE_PEEK_METHOD(NAME, TYPE, CONVERTER) \
|
|
40
|
+
static VALUE \
|
|
41
|
+
buffer_peek_##NAME(VALUE self) \
|
|
42
|
+
{ \
|
|
43
|
+
Buffer *buffer = get_buffer_struct(self); \
|
|
44
|
+
TYPE value; \
|
|
45
|
+
\
|
|
46
|
+
buffer_peek( \
|
|
47
|
+
buffer, \
|
|
48
|
+
&value, \
|
|
49
|
+
sizeof(value)); \
|
|
50
|
+
\
|
|
51
|
+
return CONVERTER(value); \
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#define DEFINE_WRITE(NAME) \
|
|
55
|
+
rb_define_method(rb_cBuffer, "write_" #NAME, buffer_write_##NAME, 1)
|
|
56
|
+
|
|
57
|
+
#define DEFINE_READ(NAME) \
|
|
58
|
+
rb_define_method(rb_cBuffer, "read_" #NAME, buffer_read_##NAME, 0)
|
|
59
|
+
|
|
60
|
+
#define DEFINE_PEEK(NAME) \
|
|
61
|
+
rb_define_method(rb_cBuffer, "peek_" #NAME, buffer_peek_##NAME, 0)
|
|
62
|
+
|
|
63
|
+
static void
|
|
64
|
+
buffer_mark(void *ptr)
|
|
65
|
+
{
|
|
66
|
+
(void)ptr; // No Ruby objects to mark
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
static void
|
|
70
|
+
buffer_free(void *ptr)
|
|
71
|
+
{
|
|
72
|
+
Buffer *buffer = ptr;
|
|
73
|
+
if (buffer == NULL)
|
|
74
|
+
return;
|
|
75
|
+
xfree(buffer->data);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static const rb_data_type_t buffer_type = {
|
|
79
|
+
.wrap_struct_name = "Hikari::Buffer",
|
|
80
|
+
.function = {
|
|
81
|
+
.dmark = buffer_mark,
|
|
82
|
+
.dfree = buffer_free,
|
|
83
|
+
.dsize = NULL},
|
|
84
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY};
|
|
85
|
+
|
|
86
|
+
static inline Buffer *
|
|
87
|
+
get_buffer_struct(VALUE self)
|
|
88
|
+
{
|
|
89
|
+
Buffer *buffer;
|
|
90
|
+
TypedData_Get_Struct(
|
|
91
|
+
self,
|
|
92
|
+
Buffer,
|
|
93
|
+
&buffer_type,
|
|
94
|
+
buffer);
|
|
95
|
+
return buffer;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static VALUE
|
|
99
|
+
buffer_initialize(int argc, VALUE *argv, VALUE self)
|
|
100
|
+
{
|
|
101
|
+
|
|
102
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
103
|
+
size_t capacity = BUFFER_INITIAL_CAPACITY;
|
|
104
|
+
if (argc > 1)
|
|
105
|
+
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 0 or 1)", argc);
|
|
106
|
+
if (argc == 1)
|
|
107
|
+
capacity = NUM2SIZET(argv[0]);
|
|
108
|
+
if (capacity == 0)
|
|
109
|
+
rb_raise(rb_eArgError, "capacity must be greater than 0");
|
|
110
|
+
buffer->capacity = capacity;
|
|
111
|
+
buffer->size = 0;
|
|
112
|
+
buffer->cursor = 0;
|
|
113
|
+
buffer->data = ALLOC_N(uint8_t, capacity);
|
|
114
|
+
return Qnil;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
static VALUE
|
|
118
|
+
buffer_alloc(VALUE klass)
|
|
119
|
+
{
|
|
120
|
+
Buffer *buffer;
|
|
121
|
+
|
|
122
|
+
VALUE obj = TypedData_Make_Struct(
|
|
123
|
+
klass,
|
|
124
|
+
Buffer,
|
|
125
|
+
&buffer_type,
|
|
126
|
+
buffer);
|
|
127
|
+
buffer->data = NULL;
|
|
128
|
+
buffer->size = 0;
|
|
129
|
+
buffer->cursor = 0;
|
|
130
|
+
buffer->capacity = 0;
|
|
131
|
+
return obj;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
static VALUE
|
|
135
|
+
buffer_capacity(VALUE self)
|
|
136
|
+
{
|
|
137
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
138
|
+
|
|
139
|
+
return SIZET2NUM(buffer->capacity);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
static VALUE
|
|
143
|
+
buffer_size(VALUE self)
|
|
144
|
+
{
|
|
145
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
146
|
+
|
|
147
|
+
return SIZET2NUM(buffer->size);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
static VALUE
|
|
151
|
+
buffer_cursor(VALUE self)
|
|
152
|
+
{
|
|
153
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
154
|
+
|
|
155
|
+
return SIZET2NUM(buffer->cursor);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static VALUE
|
|
159
|
+
buffer_clear(VALUE self)
|
|
160
|
+
{
|
|
161
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
162
|
+
|
|
163
|
+
buffer->size = 0;
|
|
164
|
+
buffer->cursor = 0;
|
|
165
|
+
|
|
166
|
+
return self;
|
|
167
|
+
}
|
|
168
|
+
static VALUE
|
|
169
|
+
buffer_rewind(VALUE self)
|
|
170
|
+
{
|
|
171
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
172
|
+
|
|
173
|
+
buffer->cursor = 0;
|
|
174
|
+
|
|
175
|
+
return self;
|
|
176
|
+
}
|
|
177
|
+
static VALUE
|
|
178
|
+
buffer_tell(VALUE self)
|
|
179
|
+
{
|
|
180
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
181
|
+
|
|
182
|
+
return SIZET2NUM(buffer->cursor);
|
|
183
|
+
}
|
|
184
|
+
static VALUE
|
|
185
|
+
buffer_remaining(VALUE self)
|
|
186
|
+
{
|
|
187
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
188
|
+
|
|
189
|
+
return SIZET2NUM(buffer->size - buffer->cursor);
|
|
190
|
+
}
|
|
191
|
+
static VALUE
|
|
192
|
+
buffer_seek(VALUE self, VALUE pos)
|
|
193
|
+
{
|
|
194
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
195
|
+
size_t position = NUM2SIZET(pos);
|
|
196
|
+
if (position > buffer->size)
|
|
197
|
+
{
|
|
198
|
+
rb_raise(
|
|
199
|
+
rb_eRangeError,
|
|
200
|
+
"seek position %zu exceeds buffer size %zu",
|
|
201
|
+
position,
|
|
202
|
+
buffer->size);
|
|
203
|
+
}
|
|
204
|
+
buffer->cursor = position;
|
|
205
|
+
return self;
|
|
206
|
+
}
|
|
207
|
+
static VALUE
|
|
208
|
+
buffer_skip(VALUE self, VALUE len)
|
|
209
|
+
{
|
|
210
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
211
|
+
|
|
212
|
+
size_t length = NUM2SIZET(len);
|
|
213
|
+
|
|
214
|
+
buffer_check_read_bounds(buffer, length);
|
|
215
|
+
|
|
216
|
+
buffer->cursor += length;
|
|
217
|
+
|
|
218
|
+
return self;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
DEFINE_WRITE_METHOD(u8, uint8_t, rb_value_to_u8)
|
|
222
|
+
DEFINE_WRITE_METHOD(u16, uint16_t, rb_value_to_u16)
|
|
223
|
+
DEFINE_WRITE_METHOD(u32, uint32_t, rb_value_to_u32)
|
|
224
|
+
DEFINE_WRITE_METHOD(u64, uint64_t, rb_value_to_u64)
|
|
225
|
+
|
|
226
|
+
DEFINE_READ_METHOD(u8, uint8_t, rb_u8_to_value)
|
|
227
|
+
DEFINE_READ_METHOD(u16, uint16_t, rb_u16_to_value)
|
|
228
|
+
DEFINE_READ_METHOD(u32, uint32_t, rb_u32_to_value)
|
|
229
|
+
DEFINE_READ_METHOD(u64, uint64_t, rb_u64_to_value)
|
|
230
|
+
|
|
231
|
+
DEFINE_PEEK_METHOD(u8, uint8_t, rb_u8_to_value)
|
|
232
|
+
DEFINE_PEEK_METHOD(u16, uint16_t, rb_u16_to_value)
|
|
233
|
+
DEFINE_PEEK_METHOD(u32, uint32_t, rb_u32_to_value)
|
|
234
|
+
DEFINE_PEEK_METHOD(u64, uint64_t, rb_u64_to_value)
|
|
235
|
+
|
|
236
|
+
DEFINE_WRITE_METHOD(i8, int8_t, rb_value_to_i8)
|
|
237
|
+
DEFINE_WRITE_METHOD(i16, int16_t, rb_value_to_i16)
|
|
238
|
+
DEFINE_WRITE_METHOD(i32, int32_t, rb_value_to_i32)
|
|
239
|
+
DEFINE_WRITE_METHOD(i64, int64_t, rb_value_to_i64)
|
|
240
|
+
|
|
241
|
+
DEFINE_READ_METHOD(i8, int8_t, rb_i8_to_value)
|
|
242
|
+
DEFINE_READ_METHOD(i16, int16_t, rb_i16_to_value)
|
|
243
|
+
DEFINE_READ_METHOD(i32, int32_t, rb_i32_to_value)
|
|
244
|
+
DEFINE_READ_METHOD(i64, int64_t, rb_i64_to_value)
|
|
245
|
+
|
|
246
|
+
DEFINE_PEEK_METHOD(i8, int8_t, rb_i8_to_value)
|
|
247
|
+
DEFINE_PEEK_METHOD(i16, int16_t, rb_i16_to_value)
|
|
248
|
+
DEFINE_PEEK_METHOD(i32, int32_t, rb_i32_to_value)
|
|
249
|
+
DEFINE_PEEK_METHOD(i64, int64_t, rb_i64_to_value)
|
|
250
|
+
|
|
251
|
+
DEFINE_WRITE_METHOD(f32, float, rb_value_to_f32)
|
|
252
|
+
DEFINE_WRITE_METHOD(f64, double, rb_value_to_f64)
|
|
253
|
+
DEFINE_READ_METHOD(f32, float, rb_f32_to_value)
|
|
254
|
+
DEFINE_READ_METHOD(f64, double, rb_f64_to_value)
|
|
255
|
+
|
|
256
|
+
DEFINE_PEEK_METHOD(f32, float, rb_f32_to_value)
|
|
257
|
+
DEFINE_PEEK_METHOD(f64, double, rb_f64_to_value)
|
|
258
|
+
|
|
259
|
+
static VALUE
|
|
260
|
+
buffer_write_bytes(VALUE self, VALUE str)
|
|
261
|
+
{
|
|
262
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
263
|
+
Check_Type(str, T_STRING);
|
|
264
|
+
buffer_write(
|
|
265
|
+
buffer,
|
|
266
|
+
RSTRING_PTR(str),
|
|
267
|
+
RSTRING_LEN(str));
|
|
268
|
+
return self;
|
|
269
|
+
}
|
|
270
|
+
static VALUE
|
|
271
|
+
buffer_read_bytes(VALUE self, VALUE len)
|
|
272
|
+
{
|
|
273
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
274
|
+
size_t length = NUM2SIZET(len);
|
|
275
|
+
|
|
276
|
+
VALUE str = rb_str_new(NULL, length);
|
|
277
|
+
buffer_read(
|
|
278
|
+
buffer,
|
|
279
|
+
RSTRING_PTR(str),
|
|
280
|
+
length);
|
|
281
|
+
return str;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
static VALUE
|
|
285
|
+
buffer_write_string(VALUE self, VALUE str)
|
|
286
|
+
{
|
|
287
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
288
|
+
|
|
289
|
+
Check_Type(str, T_STRING);
|
|
290
|
+
|
|
291
|
+
size_t len = RSTRING_LEN(str);
|
|
292
|
+
|
|
293
|
+
if (len > UINT32_MAX)
|
|
294
|
+
{
|
|
295
|
+
rb_raise(
|
|
296
|
+
rb_eRangeError,
|
|
297
|
+
"string is too large");
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
uint32_t length = (uint32_t)len;
|
|
301
|
+
|
|
302
|
+
buffer_write(
|
|
303
|
+
buffer,
|
|
304
|
+
&length,
|
|
305
|
+
sizeof(length));
|
|
306
|
+
|
|
307
|
+
buffer_write(
|
|
308
|
+
buffer,
|
|
309
|
+
RSTRING_PTR(str),
|
|
310
|
+
len);
|
|
311
|
+
|
|
312
|
+
return self;
|
|
313
|
+
}
|
|
314
|
+
static VALUE
|
|
315
|
+
buffer_read_string(VALUE self)
|
|
316
|
+
{
|
|
317
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
318
|
+
|
|
319
|
+
uint32_t length = 0;
|
|
320
|
+
|
|
321
|
+
buffer_read(
|
|
322
|
+
buffer,
|
|
323
|
+
&length,
|
|
324
|
+
sizeof(length));
|
|
325
|
+
|
|
326
|
+
VALUE str = rb_str_new(NULL, length);
|
|
327
|
+
rb_enc_associate(
|
|
328
|
+
str,
|
|
329
|
+
rb_utf8_encoding());
|
|
330
|
+
|
|
331
|
+
buffer_read(
|
|
332
|
+
buffer,
|
|
333
|
+
RSTRING_PTR(str),
|
|
334
|
+
length);
|
|
335
|
+
|
|
336
|
+
return str;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
static VALUE
|
|
340
|
+
buffer_write_bool(VALUE self, VALUE val)
|
|
341
|
+
{
|
|
342
|
+
if (val != Qtrue && val != Qfalse)
|
|
343
|
+
rb_raise(rb_eTypeError, "expected a boolean value");
|
|
344
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
345
|
+
uint8_t value = (val == Qtrue);
|
|
346
|
+
buffer_write(
|
|
347
|
+
buffer,
|
|
348
|
+
&value,
|
|
349
|
+
sizeof(value));
|
|
350
|
+
return self;
|
|
351
|
+
}
|
|
352
|
+
static VALUE
|
|
353
|
+
buffer_read_bool(VALUE self)
|
|
354
|
+
{
|
|
355
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
356
|
+
uint8_t value;
|
|
357
|
+
buffer_read(
|
|
358
|
+
buffer,
|
|
359
|
+
&value,
|
|
360
|
+
sizeof(value));
|
|
361
|
+
return value ? Qtrue : Qfalse;
|
|
362
|
+
}
|
|
363
|
+
static VALUE
|
|
364
|
+
buffer_peek_bool(VALUE self)
|
|
365
|
+
{
|
|
366
|
+
Buffer *buffer = get_buffer_struct(self);
|
|
367
|
+
uint8_t value;
|
|
368
|
+
buffer_peek(
|
|
369
|
+
buffer,
|
|
370
|
+
&value,
|
|
371
|
+
sizeof(value));
|
|
372
|
+
return value ? Qtrue : Qfalse;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
void Init_hikari_buffer_class(void)
|
|
376
|
+
{
|
|
377
|
+
rb_cBuffer = rb_define_class_under(
|
|
378
|
+
rb_mHikari,
|
|
379
|
+
"Buffer",
|
|
380
|
+
rb_cObject);
|
|
381
|
+
|
|
382
|
+
rb_define_alloc_func(
|
|
383
|
+
rb_cBuffer,
|
|
384
|
+
buffer_alloc);
|
|
385
|
+
rb_define_method(
|
|
386
|
+
rb_cBuffer,
|
|
387
|
+
"initialize",
|
|
388
|
+
buffer_initialize,
|
|
389
|
+
-1);
|
|
390
|
+
rb_define_method(
|
|
391
|
+
rb_cBuffer,
|
|
392
|
+
"capacity",
|
|
393
|
+
buffer_capacity,
|
|
394
|
+
0);
|
|
395
|
+
rb_define_method(
|
|
396
|
+
rb_cBuffer,
|
|
397
|
+
"size",
|
|
398
|
+
buffer_size,
|
|
399
|
+
0);
|
|
400
|
+
rb_define_method(
|
|
401
|
+
rb_cBuffer,
|
|
402
|
+
"cursor",
|
|
403
|
+
buffer_cursor,
|
|
404
|
+
0);
|
|
405
|
+
rb_define_method(
|
|
406
|
+
rb_cBuffer,
|
|
407
|
+
"clear",
|
|
408
|
+
buffer_clear,
|
|
409
|
+
0);
|
|
410
|
+
rb_define_method(
|
|
411
|
+
rb_cBuffer,
|
|
412
|
+
"rewind",
|
|
413
|
+
buffer_rewind,
|
|
414
|
+
0);
|
|
415
|
+
rb_define_method(
|
|
416
|
+
rb_cBuffer,
|
|
417
|
+
"tell",
|
|
418
|
+
buffer_tell,
|
|
419
|
+
0);
|
|
420
|
+
rb_define_method(
|
|
421
|
+
rb_cBuffer,
|
|
422
|
+
"seek",
|
|
423
|
+
buffer_seek,
|
|
424
|
+
1);
|
|
425
|
+
rb_define_method(
|
|
426
|
+
rb_cBuffer,
|
|
427
|
+
"remaining",
|
|
428
|
+
buffer_remaining,
|
|
429
|
+
0);
|
|
430
|
+
rb_define_method(
|
|
431
|
+
rb_cBuffer,
|
|
432
|
+
"skip",
|
|
433
|
+
buffer_skip,
|
|
434
|
+
1);
|
|
435
|
+
DEFINE_WRITE(u8);
|
|
436
|
+
DEFINE_WRITE(u16);
|
|
437
|
+
DEFINE_WRITE(u32);
|
|
438
|
+
DEFINE_WRITE(u64);
|
|
439
|
+
|
|
440
|
+
DEFINE_READ(u8);
|
|
441
|
+
DEFINE_READ(u16);
|
|
442
|
+
DEFINE_READ(u32);
|
|
443
|
+
DEFINE_READ(u64);
|
|
444
|
+
|
|
445
|
+
DEFINE_PEEK(u8);
|
|
446
|
+
DEFINE_PEEK(u16);
|
|
447
|
+
DEFINE_PEEK(u32);
|
|
448
|
+
DEFINE_PEEK(u64);
|
|
449
|
+
|
|
450
|
+
DEFINE_WRITE(i8);
|
|
451
|
+
DEFINE_WRITE(i16);
|
|
452
|
+
DEFINE_WRITE(i32);
|
|
453
|
+
DEFINE_WRITE(i64);
|
|
454
|
+
|
|
455
|
+
DEFINE_READ(i8);
|
|
456
|
+
DEFINE_READ(i16);
|
|
457
|
+
DEFINE_READ(i32);
|
|
458
|
+
DEFINE_READ(i64);
|
|
459
|
+
|
|
460
|
+
DEFINE_PEEK(i8);
|
|
461
|
+
DEFINE_PEEK(i16);
|
|
462
|
+
DEFINE_PEEK(i32);
|
|
463
|
+
DEFINE_PEEK(i64);
|
|
464
|
+
|
|
465
|
+
DEFINE_WRITE(f32);
|
|
466
|
+
DEFINE_WRITE(f64);
|
|
467
|
+
DEFINE_READ(f32);
|
|
468
|
+
DEFINE_READ(f64);
|
|
469
|
+
DEFINE_PEEK(f32);
|
|
470
|
+
DEFINE_PEEK(f64);
|
|
471
|
+
|
|
472
|
+
rb_define_method(
|
|
473
|
+
rb_cBuffer,
|
|
474
|
+
"write_bytes",
|
|
475
|
+
buffer_write_bytes,
|
|
476
|
+
1);
|
|
477
|
+
rb_define_method(
|
|
478
|
+
rb_cBuffer,
|
|
479
|
+
"read_bytes",
|
|
480
|
+
buffer_read_bytes,
|
|
481
|
+
1);
|
|
482
|
+
rb_define_method(
|
|
483
|
+
rb_cBuffer,
|
|
484
|
+
"write_string",
|
|
485
|
+
buffer_write_string,
|
|
486
|
+
1);
|
|
487
|
+
rb_define_method(
|
|
488
|
+
rb_cBuffer,
|
|
489
|
+
"read_string",
|
|
490
|
+
buffer_read_string,
|
|
491
|
+
0);
|
|
492
|
+
|
|
493
|
+
rb_define_method(
|
|
494
|
+
rb_cBuffer,
|
|
495
|
+
"write_bool",
|
|
496
|
+
buffer_write_bool,
|
|
497
|
+
1);
|
|
498
|
+
rb_define_method(
|
|
499
|
+
rb_cBuffer,
|
|
500
|
+
"read_bool",
|
|
501
|
+
buffer_read_bool,
|
|
502
|
+
0);
|
|
503
|
+
rb_define_method(
|
|
504
|
+
rb_cBuffer,
|
|
505
|
+
"peek_bool",
|
|
506
|
+
buffer_peek_bool,
|
|
507
|
+
0);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
#undef DEFINE_WRITE_METHOD
|
|
511
|
+
#undef DEFINE_READ_METHOD
|
|
512
|
+
|
|
513
|
+
#undef DEFINE_WRITE
|
|
514
|
+
#undef DEFINE_READ
|
|
515
|
+
|
|
516
|
+
#undef DEFINE_PEEK_METHOD
|
|
517
|
+
#undef DEFINE_PEEK
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#ifndef HIKARI_BUFFER_BUFFER_H
|
|
2
|
+
#define HIKARI_BUFFER_BUFFER_H
|
|
3
|
+
|
|
4
|
+
#include "hikari_buffer.h"
|
|
5
|
+
|
|
6
|
+
typedef struct {
|
|
7
|
+
uint8_t * data;
|
|
8
|
+
size_t size;
|
|
9
|
+
size_t capacity;
|
|
10
|
+
size_t cursor;
|
|
11
|
+
} Buffer;
|
|
12
|
+
|
|
13
|
+
void Init_hikari_buffer_class(void);
|
|
14
|
+
|
|
15
|
+
#endif //HIKARI_BUFFER_BUFFER_H
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#include "convert.h"
|
|
2
|
+
|
|
3
|
+
uint8_t
|
|
4
|
+
rb_value_to_u8(VALUE value)
|
|
5
|
+
{
|
|
6
|
+
unsigned int n = NUM2UINT(value);
|
|
7
|
+
|
|
8
|
+
if (n > UINT8_MAX) {
|
|
9
|
+
rb_raise(
|
|
10
|
+
rb_eRangeError,
|
|
11
|
+
"value %u is out of range for u8",
|
|
12
|
+
n
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return (uint8_t)n;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
uint16_t
|
|
20
|
+
rb_value_to_u16(VALUE value)
|
|
21
|
+
{
|
|
22
|
+
unsigned int n = NUM2UINT(value);
|
|
23
|
+
|
|
24
|
+
if (n > UINT16_MAX) {
|
|
25
|
+
rb_raise(
|
|
26
|
+
rb_eRangeError,
|
|
27
|
+
"value %u is out of range for u16",
|
|
28
|
+
n
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (uint16_t)n;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
uint32_t
|
|
36
|
+
rb_value_to_u32(VALUE value)
|
|
37
|
+
{
|
|
38
|
+
return (uint32_t)NUM2UINT(value);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
uint64_t
|
|
42
|
+
rb_value_to_u64(VALUE value)
|
|
43
|
+
{
|
|
44
|
+
return (uint64_t)NUM2ULL(value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
VALUE rb_u8_to_value(uint8_t value)
|
|
48
|
+
{
|
|
49
|
+
return UINT2NUM(value);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
VALUE rb_u16_to_value(uint16_t value)
|
|
53
|
+
{
|
|
54
|
+
return UINT2NUM(value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
VALUE rb_u32_to_value(uint32_t value)
|
|
58
|
+
{
|
|
59
|
+
return UINT2NUM(value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
VALUE rb_u64_to_value(uint64_t value)
|
|
63
|
+
{
|
|
64
|
+
return ULL2NUM(value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
int8_t
|
|
71
|
+
rb_value_to_i8(VALUE value)
|
|
72
|
+
{
|
|
73
|
+
long n = NUM2LONG(value);
|
|
74
|
+
if (n < INT8_MIN || n > INT8_MAX) {
|
|
75
|
+
rb_raise(
|
|
76
|
+
rb_eRangeError,
|
|
77
|
+
"value %ld is out of range for i8",
|
|
78
|
+
n
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return (int8_t)n;
|
|
82
|
+
}
|
|
83
|
+
int16_t
|
|
84
|
+
rb_value_to_i16(VALUE value)
|
|
85
|
+
{
|
|
86
|
+
long n = NUM2LONG(value);
|
|
87
|
+
if (n < INT16_MIN || n > INT16_MAX) {
|
|
88
|
+
rb_raise(
|
|
89
|
+
rb_eRangeError,
|
|
90
|
+
"value %ld is out of range for i16",
|
|
91
|
+
n
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
return (int16_t)n;
|
|
95
|
+
}
|
|
96
|
+
int32_t
|
|
97
|
+
rb_value_to_i32(VALUE value)
|
|
98
|
+
{
|
|
99
|
+
return (int32_t)NUM2INT(value);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
int64_t
|
|
103
|
+
rb_value_to_i64(VALUE value)
|
|
104
|
+
{
|
|
105
|
+
return (int64_t)NUM2LL(value);
|
|
106
|
+
}
|
|
107
|
+
VALUE rb_i8_to_value(int8_t value)
|
|
108
|
+
{
|
|
109
|
+
return INT2NUM(value);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
VALUE rb_i16_to_value(int16_t value)
|
|
113
|
+
{
|
|
114
|
+
return INT2NUM(value);
|
|
115
|
+
}
|
|
116
|
+
VALUE rb_i32_to_value(int32_t value)
|
|
117
|
+
{
|
|
118
|
+
return INT2NUM(value);
|
|
119
|
+
}
|
|
120
|
+
VALUE rb_i64_to_value(int64_t value)
|
|
121
|
+
{
|
|
122
|
+
return LL2NUM(value);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
float rb_value_to_f32(VALUE value)
|
|
126
|
+
{
|
|
127
|
+
return (float)NUM2DBL(value);
|
|
128
|
+
}
|
|
129
|
+
double rb_value_to_f64(VALUE value)
|
|
130
|
+
{
|
|
131
|
+
return NUM2DBL(value);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
VALUE rb_f32_to_value(float value)
|
|
135
|
+
{
|
|
136
|
+
return DBL2NUM((double)value);
|
|
137
|
+
}
|
|
138
|
+
VALUE rb_f64_to_value(double value)
|
|
139
|
+
{
|
|
140
|
+
return DBL2NUM(value);
|
|
141
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#ifndef HIKARI_CONVERT_H
|
|
2
|
+
#define HIKARI_CONVERT_H
|
|
3
|
+
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
#include <limits.h>
|
|
6
|
+
|
|
7
|
+
#include "ruby.h"
|
|
8
|
+
|
|
9
|
+
uint8_t rb_value_to_u8(VALUE value);
|
|
10
|
+
uint16_t rb_value_to_u16(VALUE value);
|
|
11
|
+
uint32_t rb_value_to_u32(VALUE value);
|
|
12
|
+
uint64_t rb_value_to_u64(VALUE value);
|
|
13
|
+
|
|
14
|
+
VALUE rb_u8_to_value(uint8_t value);
|
|
15
|
+
VALUE rb_u16_to_value(uint16_t value);
|
|
16
|
+
VALUE rb_u32_to_value(uint32_t value);
|
|
17
|
+
VALUE rb_u64_to_value(uint64_t value);
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
int8_t rb_value_to_i8(VALUE value);
|
|
21
|
+
int16_t rb_value_to_i16(VALUE value);
|
|
22
|
+
int32_t rb_value_to_i32(VALUE value);
|
|
23
|
+
int64_t rb_value_to_i64(VALUE value);
|
|
24
|
+
|
|
25
|
+
VALUE rb_i8_to_value(int8_t value);
|
|
26
|
+
VALUE rb_i16_to_value(int16_t value);
|
|
27
|
+
VALUE rb_i32_to_value(int32_t value);
|
|
28
|
+
VALUE rb_i64_to_value(int64_t value);
|
|
29
|
+
|
|
30
|
+
float rb_value_to_f32(VALUE value);
|
|
31
|
+
double rb_value_to_f64(VALUE value);
|
|
32
|
+
|
|
33
|
+
VALUE rb_f32_to_value(float value);
|
|
34
|
+
VALUE rb_f64_to_value(double value);
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
#endif
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "mkmf"
|
|
4
|
+
|
|
5
|
+
# Makes all symbols private by default to avoid unintended conflict
|
|
6
|
+
# with other gems. To explicitly export symbols you can use RUBY_FUNC_EXPORTED
|
|
7
|
+
# selectively, or entirely remove this flag.
|
|
8
|
+
append_cflags("-fvisibility=hidden")
|
|
9
|
+
|
|
10
|
+
create_makefile("hikari_buffer/hikari_buffer")
|