libbin 1.0.7 → 1.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2d6b93ee63ec0916ee685a6b1b646a4fb6a742e31158049bc46f387db3a4ee27
4
- data.tar.gz: dc8c1ea1218694f5b4ad8a53baa60e721a7b533474db9674939b40d25cb7ee06
3
+ metadata.gz: ac7b79d2e9bfeed5936680b7b192091988b66bebf8b7a9606468212f176929ae
4
+ data.tar.gz: 273e0156acc7f86fb799f7b5aafc99c3fb428ac69bcbe5fbda2a265d9543fb04
5
5
  SHA512:
6
- metadata.gz: 808407aad8f8de68723199114b84434027b3a936360496785574cfdb34567c6cf6bcffcfb044c02885c9211794bd34b25fb916323724cedfd69dfddd34cf0254
7
- data.tar.gz: 005fb654400e4b7eaa5c9137aa7ea55d30f61b62d9c4c6f13b385046118b5dcbddda3347331397d1f1cb6cf217c3aef3a50ebd493dc123ea1c8a8f792d6fcb69
6
+ metadata.gz: 1268f8a9247714f2f2dac82b929f559eba7a8561b75f6fa89474e8a3d12b88723d37a6d065b679c41861dd3454a7a19b6d4e41f415a76f8fb77fa5ae3fed1a7d
7
+ data.tar.gz: e9dd37966771af9750ec9a302048cd14e156d7fd1f4c82c5336f1db50a96e00b9a1b5d04627a21abec24f725556c8fd1dbb9808be567bf09ba429c7b66d5e13a
@@ -0,0 +1,466 @@
1
+ #include "ruby.h"
2
+ #include "./libbin_c.h"
3
+
4
+ VALUE cDataShape;
5
+ VALUE cScalar;
6
+
7
+ static ID id_read, id_write;
8
+
9
+ /* size(value, previous_offset = 0, parent = nil, index = nil, length = nil)*/
10
+ #define MAKE_TYPE_SIZE(CLASS, MAPPED_TYPE) \
11
+ static VALUE CLASS ## _size(int argc, VALUE* argv, VALUE self) { \
12
+ (void)self; \
13
+ VALUE length; \
14
+ rb_scan_args(argc, argv, "14", NULL, NULL, NULL, NULL, &length); \
15
+ if (RTEST(length)) \
16
+ return ULL2NUM(sizeof(MAPPED_TYPE)*NUM2ULL(length)); \
17
+ else \
18
+ return INT2FIX(sizeof(MAPPED_TYPE)); \
19
+ }
20
+
21
+ /* shape(value, previous_offset = 0, parent = nil, index = nil, kind = DataShape, length = nil) */
22
+ #define MAKE_TYPE_SHAPE(CLASS, MAPPED_TYPE) \
23
+ static VALUE CLASS ## _shape(int argc, VALUE* argv, VALUE self) { \
24
+ (void)self; \
25
+ VALUE previous_offset; \
26
+ VALUE kind; \
27
+ VALUE length; \
28
+ rb_scan_args(argc, argv, "15", NULL, &previous_offset, NULL, NULL, &kind, &length); \
29
+ if (NIL_P(previous_offset)) \
30
+ previous_offset = INT2FIX(0); \
31
+ if (NIL_P(kind)) \
32
+ kind = cDataShape; \
33
+ if (NIL_P(length)) \
34
+ length = INT2FIX(1); \
35
+ VALUE args[] = { previous_offset, \
36
+ LL2NUM(NUM2LL(previous_offset) - 1 + NUM2LL(length) * (ptrdiff_t)sizeof(MAPPED_TYPE)) }; \
37
+ return rb_class_new_instance(2, args, kind); \
38
+ }
39
+
40
+ #define MAKE_LOAD_LOOP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT) \
41
+ do { \
42
+ if (RTEST(length)) { \
43
+ res = rb_ary_new_capa(n); \
44
+ long i = 0; \
45
+ for (MAPPED_TYPE *p = data; p != data + n; p++, i++) \
46
+ rb_ary_store(res, i, RUBY_CONVERT(NATIVE_CONVERT(*p))); \
47
+ } else \
48
+ res = RUBY_CONVERT(NATIVE_CONVERT(*data)); \
49
+ } while (0)
50
+
51
+ #define MAKE_LOAD_ENDIAN(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT) \
52
+ do { \
53
+ if (little) \
54
+ MAKE_LOAD_LOOP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT ## _ ## le ); \
55
+ else \
56
+ MAKE_LOAD_LOOP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT ## _ ## be ); \
57
+ } while (0)
58
+
59
+ #define MAKE_LOAD(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT) \
60
+ MAKE_LOAD_LOOP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT)
61
+
62
+ /* load(input, input_big = LibBin::default_big?, parent = nil, index = nil, length = nil) */
63
+ #define MAKE_TYPE_LOAD(CLASS, MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT, LOAD) \
64
+ static VALUE CLASS ## _load(int argc, VALUE* argv, VALUE self) { \
65
+ (void)self; \
66
+ VALUE input; \
67
+ VALUE input_big; \
68
+ VALUE length; \
69
+ rb_scan_args(argc, argv, "14", &input, &input_big, NULL, NULL, &length); \
70
+ if (NIL_P(input_big)) \
71
+ input_big = rb_funcall(mLibBin, rb_intern("default_big?"), 0); \
72
+ unsigned little = RTEST(input_big) ? 0 : 1; \
73
+ long n = RTEST(length) ? NUM2LONG(length) : 1; \
74
+ size_t cnt = sizeof(MAPPED_TYPE) * n; \
75
+ VALUE res; \
76
+ VALUE str = rb_funcall(input, id_read, 1, ULL2NUM(cnt)); \
77
+ if (NIL_P(str) || RSTRING_LEN(str) < (long)cnt) \
78
+ rb_raise(rb_eRuntimeError, \
79
+ "could not read enough data: got %ld needed %zu", \
80
+ NIL_P(str) ? 0 : RSTRING_LEN(str), cnt); \
81
+ MAPPED_TYPE *data = (MAPPED_TYPE *)RSTRING_PTR(str); \
82
+ LOAD(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT); \
83
+ RB_GC_GUARD(str); \
84
+ return res; \
85
+ }
86
+
87
+ #define MAKE_DUMP_LOOP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT) \
88
+ do { \
89
+ if (RTEST(length)) \
90
+ for (long i = 0; i < n; i++) { \
91
+ MAPPED_TYPE v = NATIVE_CONVERT(RUBY_CONVERT(rb_ary_entry(value, i))); \
92
+ rb_str_cat(str, (char *)&v, sizeof(MAPPED_TYPE)); \
93
+ } \
94
+ else { \
95
+ MAPPED_TYPE v = NATIVE_CONVERT(RUBY_CONVERT(value)); \
96
+ rb_str_cat(str, (char *)&v, sizeof(MAPPED_TYPE)); \
97
+ } \
98
+ } while (0)
99
+
100
+ #define MAKE_DUMP_ENDIAN(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT) \
101
+ do { \
102
+ if (little) \
103
+ MAKE_DUMP_LOOP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT ## _ ## le ); \
104
+ else \
105
+ MAKE_DUMP_LOOP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT ## _ ## be ); \
106
+ } while (0)
107
+
108
+ #define MAKE_DUMP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT) \
109
+ MAKE_DUMP_LOOP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT)
110
+
111
+ /* dump(value, output, output_big = LibBin::default_big?, parent = nil, index = nil, length = nil) */
112
+ #define MAKE_TYPE_DUMP(CLASS, MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT, DUMP) \
113
+ static VALUE CLASS ## _dump(int argc, VALUE* argv, VALUE self) { \
114
+ (void)self; \
115
+ VALUE value; \
116
+ VALUE output; \
117
+ VALUE output_big; \
118
+ VALUE length; \
119
+ rb_scan_args(argc, argv, "24", &value, &output, &output_big, NULL, NULL, &length); \
120
+ if (NIL_P(output_big)) \
121
+ output_big = rb_funcall(mLibBin, rb_intern("default_big?"), 0); \
122
+ unsigned little = RTEST(output_big) ? 0 : 1; \
123
+ long n = RTEST(length) ? NUM2LONG(length) : 1; \
124
+ size_t cnt = sizeof(MAPPED_TYPE) * n; \
125
+ VALUE str = rb_str_buf_new((long)cnt); \
126
+ DUMP(MAPPED_TYPE, RUBY_CONVERT, NATIVE_CONVERT); \
127
+ rb_funcall(output, id_write, 1, str); \
128
+ return Qnil; \
129
+ }
130
+
131
+ #define MAKE_CONVERT_LOOP(MAPPED_TYPE, MAPPED_SWAP, SWAP_COND, RUBY_CONVERT, NATIVE_CONVERT) \
132
+ do { \
133
+ if (RTEST(length)) { \
134
+ res = rb_ary_new_capa(n); \
135
+ long i = 0; \
136
+ for (MAPPED_TYPE *p = data; p != data + n; p++, i++) { \
137
+ rb_ary_store(res, i, RUBY_CONVERT(NATIVE_CONVERT(*p))); \
138
+ if (SWAP_COND) \
139
+ *p = MAPPED_SWAP(*p); \
140
+ } \
141
+ } else { \
142
+ res = RUBY_CONVERT(NATIVE_CONVERT(*data)); \
143
+ if (SWAP_COND) \
144
+ *data = MAPPED_SWAP(*data); \
145
+ } \
146
+ } while(0)
147
+
148
+ #define MAKE_CONVERT_ENDIAN(MAPPED_TYPE, MAPPED_SWAP, RUBY_CONVERT, NATIVE_CONVERT) \
149
+ do { \
150
+ if (little_input) \
151
+ MAKE_CONVERT_LOOP(MAPPED_TYPE, MAPPED_SWAP, !little_output, RUBY_CONVERT, NATIVE_CONVERT ## _ ## le ); \
152
+ else \
153
+ MAKE_CONVERT_LOOP(MAPPED_TYPE, MAPPED_SWAP, little_output, RUBY_CONVERT, NATIVE_CONVERT ## _ ## be ); \
154
+ } while (0)
155
+
156
+ #define MAKE_CONVERT(MAPPED_TYPE, MAPPED_SWAP, RUBY_CONVERT, NATIVE_CONVERT) \
157
+ MAKE_CONVERT_LOOP(MAPPED_TYPE, MAPPED_SWAP, 0, RUBY_CONVERT, NATIVE_CONVERT)
158
+
159
+
160
+ /* convert(input, output, input_big = LibBin::default_big?, output_big = !input_big, parent = nil, index = nil, length = nil) */
161
+ #define MAKE_TYPE_CONVERT(CLASS, MAPPED_TYPE, MAPPED_SWAP, RUBY_CONVERT, NATIVE_CONVERT, CONVERT) \
162
+ static VALUE CLASS ## _convert(int argc, VALUE* argv, VALUE self) { \
163
+ (void)self; \
164
+ VALUE input; \
165
+ VALUE output; \
166
+ VALUE input_big; \
167
+ VALUE output_big; \
168
+ VALUE length; \
169
+ rb_scan_args(argc, argv, "25", &input, &output, &input_big, &output_big, NULL, NULL, &length); \
170
+ if (NIL_P(input_big)) \
171
+ input_big = rb_funcall(mLibBin, rb_intern("default_big?"), 0); \
172
+ unsigned little_input = RTEST(input_big) ? 0 : 1; \
173
+ if (NIL_P(output_big)) \
174
+ output_big = little_input ? Qtrue : Qfalse; \
175
+ unsigned little_output = RTEST(output_big) ? 0 : 1; \
176
+ long n = RTEST(length) ? NUM2LONG(length) : 1; \
177
+ size_t cnt = sizeof(MAPPED_TYPE) * n; \
178
+ VALUE res; \
179
+ VALUE str = rb_funcall(input, id_read, 1, ULL2NUM(cnt)); \
180
+ if (NIL_P(str) || RSTRING_LEN(str) < (long)cnt) \
181
+ rb_raise(rb_eRuntimeError, "could not read enough data: got %ld needed %zu", \
182
+ NIL_P(str) ? 0 : RSTRING_LEN(str), cnt); \
183
+ MAPPED_TYPE *data = (MAPPED_TYPE *)RSTRING_PTR(str); \
184
+ CONVERT(MAPPED_TYPE, MAPPED_SWAP, RUBY_CONVERT, NATIVE_CONVERT); \
185
+ rb_funcall(output, id_write, 1, str); \
186
+ return res; \
187
+ }
188
+
189
+ #define MAKE_CLASS_DEFINE(CLASS_NAME, CLASS) \
190
+ static void define_ ## CLASS() { \
191
+ CLASS = rb_define_class_under(cDataConverter, #CLASS_NAME, cScalar); \
192
+ rb_define_singleton_method(CLASS, "size", CLASS ## _size, -1); \
193
+ rb_define_singleton_method(CLASS, "shape", CLASS ## _shape, -1); \
194
+ rb_define_singleton_method(CLASS, "load", CLASS ## _load, -1); \
195
+ rb_define_singleton_method(CLASS, "dump", CLASS ## _dump, -1); \
196
+ rb_define_singleton_method(CLASS, "convert", CLASS ## _convert, -1); \
197
+ }
198
+
199
+ #define MAKE_STATIC_OBJECT(CLASS) \
200
+ static VALUE CLASS;
201
+
202
+ #define MAKE_CLASS_TYPE_ENDIAN_EX(CLASS_NAME, CLASS, MAPPED_TYPE, MAPPED_SWAP, RUBY_CONVERT_TO, RUBY_CONVERT_FROM, NATIVE_CONVERT_TO, NATIVE_CONVERT_FROM, ENDIAN) \
203
+ MAKE_STATIC_OBJECT(CLASS) \
204
+ MAKE_TYPE_SIZE(CLASS, MAPPED_TYPE) \
205
+ MAKE_TYPE_SHAPE(CLASS, MAPPED_TYPE) \
206
+ MAKE_TYPE_LOAD(CLASS, MAPPED_TYPE, RUBY_CONVERT_TO, NATIVE_CONVERT_TO, MAKE_LOAD ## ENDIAN) \
207
+ MAKE_TYPE_DUMP(CLASS, MAPPED_TYPE, RUBY_CONVERT_FROM, NATIVE_CONVERT_FROM, MAKE_DUMP ## ENDIAN) \
208
+ MAKE_TYPE_CONVERT(CLASS, MAPPED_TYPE, MAPPED_SWAP, RUBY_CONVERT_TO, NATIVE_CONVERT_TO, MAKE_CONVERT ## ENDIAN) \
209
+ MAKE_CLASS_DEFINE(CLASS_NAME, CLASS)
210
+
211
+ #define MAKE_CLASS_TYPE_ENDIAN(CLASS_NAME, CLASS, MAPPED_TYPE, MAPPED_SWAP, RUBY_CONVERT_TO, RUBY_CONVERT_FROM, NATIVE_CONVERT_TO, NATIVE_CONVERT_FROM, ENDIAN) \
212
+ MAKE_CLASS_TYPE_ENDIAN_EX(CLASS_NAME, CLASS, MAPPED_TYPE, MAPPED_SWAP, RUBY_CONVERT_TO, RUBY_CONVERT_FROM, NATIVE_CONVERT_TO, NATIVE_CONVERT_FROM, ENDIAN)
213
+
214
+ #define ENDIAN_little
215
+ #define ENDIAN_big
216
+ #define ENDIAN_nil _ENDIAN
217
+ #define ENDIAN_suffix_little _le
218
+ #define ENDIAN_suffix_big _be
219
+ #define ENDIAN_suffix_nil
220
+ #define ENDIAN_SUFFIX_little _LE
221
+ #define ENDIAN_SUFFIX_big _BE
222
+ #define ENDIAN_SUFFIX_nil
223
+
224
+ #define MAKE_ENDIAN(ENDIAN) ENDIAN_ ## ENDIAN
225
+ #define MAKE_ENDIAN_suffix(ENDIAN) ENDIAN_suffix_ ## ENDIAN
226
+ #define MAKE_ENDIAN_SUFFIX(ENDIAN) ENDIAN_SUFFIX_ ## ENDIAN
227
+ #define MAKE_CONVERT_NAME_SUFFIX_EX(NAME, SUFFIX) NAME ## SUFFIX
228
+ #define MAKE_CONVERT_NAME_SUFFIX(NAME, SUFFIX) MAKE_CONVERT_NAME_SUFFIX_EX(NAME, SUFFIX)
229
+ #define MAKE_CONVERT_NAME_MAKE_SUFFIX(NAME, ENDIAN, MAKE_SUFFIX) MAKE_CONVERT_NAME_SUFFIX(NAME, MAKE_SUFFIX(ENDIAN))
230
+ #define MAKE_CLASS_NAME(CLASS_NAME, ENDIAN) MAKE_CONVERT_NAME_MAKE_SUFFIX(CLASS_NAME, ENDIAN, MAKE_ENDIAN_SUFFIX)
231
+ #define MAKE_C_CLASS_NAME(CLASS_NAME, ENDIAN) MAKE_CONVERT_NAME_MAKE_SUFFIX(c ## CLASS_NAME, ENDIAN, MAKE_ENDIAN_SUFFIX)
232
+ #define MAKE_CONVERT_NAME(NAME, ENDIAN) MAKE_CONVERT_NAME_MAKE_SUFFIX(NAME, ENDIAN, MAKE_ENDIAN_suffix)
233
+
234
+ #define MAKE_CLASS(CLASS_NAME, SIZE, RUBY_CONVERT_TO, RUBY_CONVERT_FROM, NATIVE_CONVERT_TO, NATIVE_CONVERT_FROM, ENDIAN) \
235
+ MAKE_CLASS_TYPE_ENDIAN(MAKE_CLASS_NAME(CLASS_NAME, ENDIAN), \
236
+ MAKE_C_CLASS_NAME(CLASS_NAME, ENDIAN), \
237
+ uint ## SIZE ## _t, \
238
+ bswap_uint ## SIZE, \
239
+ RUBY_CONVERT_TO, \
240
+ RUBY_CONVERT_FROM, \
241
+ MAKE_CONVERT_NAME(NATIVE_CONVERT_TO, ENDIAN), \
242
+ MAKE_CONVERT_NAME(NATIVE_CONVERT_FROM, ENDIAN), \
243
+ MAKE_ENDIAN(ENDIAN))
244
+
245
+ #define MAKE_CLASSES(CLASS_NAME, SIZE, RUBY_CONVERT_TO, RUBY_CONVERT_FROM, NATIVE_CONVERT_TO, NATIVE_CONVERT_FROM) \
246
+ MAKE_CLASS(CLASS_NAME, SIZE, RUBY_CONVERT_TO, RUBY_CONVERT_FROM, NATIVE_CONVERT_TO, NATIVE_CONVERT_FROM, nil) \
247
+ MAKE_CLASS(CLASS_NAME, SIZE, RUBY_CONVERT_TO, RUBY_CONVERT_FROM, NATIVE_CONVERT_TO, NATIVE_CONVERT_FROM, little) \
248
+ MAKE_CLASS(CLASS_NAME, SIZE, RUBY_CONVERT_TO, RUBY_CONVERT_FROM, NATIVE_CONVERT_TO, NATIVE_CONVERT_FROM, big)
249
+
250
+ #define MAKE_CALL_DEFINE(CLASS_NAME) \
251
+ do { \
252
+ define_ ## CLASS_NAME(); \
253
+ } while (0)
254
+
255
+ #define MAKE_CALL_DEFINE_EX(CLASS_NAME) \
256
+ MAKE_CALL_DEFINE(CLASS_NAME)
257
+
258
+ #define MAKE_CALL_DEFINES(CLASS_NAME) \
259
+ do { \
260
+ MAKE_CALL_DEFINE_EX(MAKE_C_CLASS_NAME(CLASS_NAME, nil)); \
261
+ MAKE_CALL_DEFINE_EX(MAKE_C_CLASS_NAME(CLASS_NAME, little)); \
262
+ MAKE_CALL_DEFINE_EX(MAKE_C_CLASS_NAME(CLASS_NAME, big)); \
263
+ } while (0)
264
+
265
+ static inline float half_to_float_le(uint16_t val) {
266
+ val = unpack_half_le(val);
267
+ union float_u u;
268
+ u.i = half_to_float(val);
269
+ return u.f;
270
+ }
271
+
272
+ static inline float half_to_float_be(uint16_t val) {
273
+ val = unpack_half_be(val);
274
+ union float_u u;
275
+ u.i = half_to_float(val);
276
+ return u.f;
277
+ }
278
+
279
+ static inline uint16_t float_to_half_le(float f) {
280
+ uint16_t res;
281
+ union float_u u;
282
+ u.f = f;
283
+ res = half_from_float(u.i);
284
+ res = pack_half_le(res);
285
+ return res;
286
+ }
287
+
288
+ static inline uint16_t float_to_half_be(float f) {
289
+ uint16_t res;
290
+ union float_u u;
291
+ u.f = f;
292
+ res = half_from_float(u.i);
293
+ res = pack_half_be(res);
294
+ return res;
295
+ }
296
+
297
+
298
+ MAKE_CLASSES(Half, 16, DBL2NUM, NUM2DBL, half_to_float, float_to_half)
299
+
300
+ static inline float pghalf_to_float_le(uint16_t val) {
301
+ val = unpack_pghalf_le(val);
302
+ union float_u u;
303
+ u.i = pghalf_to_float(val);
304
+ return u.f;
305
+ }
306
+
307
+ static inline float pghalf_to_float_be(uint16_t val) {
308
+ val = unpack_pghalf_be(val);
309
+ union float_u u;
310
+ u.i = pghalf_to_float(val);
311
+ return u.f;
312
+ }
313
+
314
+ static inline uint16_t float_to_pghalf_le(float f) {
315
+ uint16_t res;
316
+ union float_u u;
317
+ u.f = f;
318
+ res = pghalf_from_float(u.i);
319
+ res = pack_pghalf_le(res);
320
+ return res;
321
+ }
322
+
323
+ static inline uint16_t float_to_pghalf_be(float f) {
324
+ uint16_t res;
325
+ union float_u u;
326
+ u.f = f;
327
+ res = pghalf_from_float(u.i);
328
+ res = pack_pghalf_be(res);
329
+ return res;
330
+ }
331
+
332
+ MAKE_CLASSES(PGHalf, 16, DBL2NUM, NUM2DBL, pghalf_to_float, float_to_pghalf)
333
+
334
+ MAKE_CLASSES(Int8, 8, INT2FIX, NUM2SHORT, unpack_int8, pack_int8)
335
+ MAKE_CLASSES(UInt8, 8, USHORT2NUM, NUM2USHORT, unpack_uint8, pack_uint8)
336
+ MAKE_CLASSES(Int16, 16, INT2FIX, NUM2SHORT, unpack_int16, pack_int16)
337
+ MAKE_CLASSES(UInt16, 16, USHORT2NUM, NUM2USHORT, unpack_uint16, pack_uint16)
338
+ MAKE_CLASSES(Int32, 32, INT2NUM, NUM2INT, unpack_int32, pack_int32)
339
+ MAKE_CLASSES(UInt32, 32, UINT2NUM, NUM2UINT, unpack_uint32, pack_uint32)
340
+ MAKE_CLASSES(Int64, 64, LL2NUM, NUM2LL, unpack_int64, pack_int64)
341
+ MAKE_CLASSES(UInt64, 64, ULL2NUM, NUM2ULL, unpack_uint64, pack_uint64)
342
+ MAKE_CLASSES(Flt, 32, DBL2NUM, NUM2DBL, unpack_float, pack_float)
343
+ MAKE_CLASSES(Double, 64, DBL2NUM, NUM2DBL, unpack_double, pack_double)
344
+
345
+ static VALUE cStr;
346
+
347
+ static VALUE cStr_size(int argc, VALUE* argv, VALUE self) {
348
+ (void)self;
349
+ VALUE value;
350
+ VALUE length;
351
+ rb_scan_args(argc, argv, "14", &value, NULL, NULL, NULL, &length);
352
+ if (RTEST(length))
353
+ return length;
354
+ else
355
+ return rb_funcall(value, rb_intern("bytesize"), 0);
356
+ }
357
+
358
+ static VALUE cStr_shape(int argc, VALUE* argv, VALUE self) {
359
+ (void)self;
360
+ VALUE value;
361
+ VALUE previous_offset;
362
+ VALUE kind;
363
+ VALUE length;
364
+ rb_scan_args(argc, argv, "15", &value, &previous_offset, NULL, NULL, &kind, &length);
365
+ if (NIL_P(previous_offset))
366
+ previous_offset = INT2FIX(0);
367
+ if (NIL_P(kind))
368
+ kind = cDataShape;
369
+ if (NIL_P(length)) {
370
+ VALUE args[] = { previous_offset, LL2NUM(NUM2LL(previous_offset) - 1 + RSTRING_LEN(value)) };
371
+ return rb_class_new_instance(2, args, kind);
372
+ } else {
373
+ VALUE args[] = { previous_offset, LL2NUM(NUM2LL(previous_offset) - 1 + NUM2LL(length)) };
374
+ return rb_class_new_instance(2, args, kind);
375
+ }
376
+ }
377
+
378
+ static VALUE cStr_load(int argc, VALUE* argv, VALUE self) {
379
+ (void)self;
380
+ VALUE input;
381
+ VALUE length;
382
+ rb_scan_args(argc, argv, "14", &input, NULL, NULL, NULL, &length);
383
+ if (NIL_P(length))
384
+ return rb_funcall(input, rb_intern("readline"), 1, rb_str_new_static("", 1));
385
+ else {
386
+ VALUE str = rb_funcall(input, id_read, 1, length);
387
+ if (NIL_P(str) || RSTRING_LEN(str) < NUM2LONG(length))
388
+ rb_raise(rb_eRuntimeError,
389
+ "could not read enough data: got %ld needed %zu", RSTRING_LEN(str), NUM2LONG(length));
390
+ return str;
391
+ }
392
+ }
393
+
394
+ static VALUE cStr_dump(int argc, VALUE* argv, VALUE self) {
395
+ (void)self;
396
+ VALUE value;
397
+ VALUE output;
398
+ VALUE length;
399
+ rb_scan_args(argc, argv, "24", &value, &output, NULL, NULL, NULL, &length);
400
+ if (NIL_P(length))
401
+ rb_funcall(output, id_write, 1, value);
402
+ else {
403
+ long l = NUM2LONG(length);
404
+ long vl = RSTRING_LEN(value);
405
+ VALUE str;
406
+ if (vl > l)
407
+ str = rb_str_new(RSTRING_PTR(value), l);
408
+ else {
409
+ str = rb_str_buf_new(l);
410
+ rb_str_cat(str, RSTRING_PTR(value), vl);
411
+ for (long i = 0; i < l - vl; i++)
412
+ rb_str_cat(str, "", 1);
413
+ }
414
+ rb_funcall(output, id_write, 1, str);
415
+ }
416
+ return Qnil;
417
+ }
418
+
419
+ static VALUE cStr_convert(int argc, VALUE* argv, VALUE self) {
420
+ (void)self;
421
+ VALUE input;
422
+ VALUE output;
423
+ VALUE length;
424
+ rb_scan_args(argc, argv, "25", &input, &output, NULL, NULL, NULL, NULL, &length);
425
+ VALUE str;
426
+ if (NIL_P(length))
427
+ str = rb_funcall(input, rb_intern("readline"), 1, rb_str_new_static("", 1));
428
+ else {
429
+ str = rb_funcall(input, id_read, 1, length);
430
+ if (NIL_P(str) || RSTRING_LEN(str) < NUM2LONG(length))
431
+ rb_raise(rb_eRuntimeError,
432
+ "could not read enough data: got %ld needed %zu", RSTRING_LEN(str), NUM2LONG(length));
433
+ }
434
+ rb_funcall(output, id_write, 1, str);
435
+ return str;
436
+ }
437
+
438
+ static void define_cStr() {
439
+ cStr = rb_define_class_under(cDataConverter, "Str", cScalar);
440
+ rb_define_singleton_method(cStr, "size", cStr_size, -1);
441
+ rb_define_singleton_method(cStr, "shape", cStr_shape, -1);
442
+ rb_define_singleton_method(cStr, "load", cStr_load, -1);
443
+ rb_define_singleton_method(cStr, "dump", cStr_dump, -1);
444
+ rb_define_singleton_method(cStr, "convert", cStr_convert, -1);
445
+ }
446
+
447
+ void define_cScalar() {
448
+ id_read = rb_intern("read");
449
+ id_write = rb_intern("write");
450
+ cScalar = rb_define_class_under(cDataConverter, "Scalar", rb_cObject);
451
+ MAKE_CALL_DEFINES(Half);
452
+ MAKE_CALL_DEFINES(PGHalf);
453
+ MAKE_CALL_DEFINES(Int8);
454
+ MAKE_CALL_DEFINES(UInt8);
455
+ MAKE_CALL_DEFINES(Int16);
456
+ MAKE_CALL_DEFINES(UInt16);
457
+ MAKE_CALL_DEFINES(Int32);
458
+ MAKE_CALL_DEFINES(UInt32);
459
+ MAKE_CALL_DEFINES(Int64);
460
+ MAKE_CALL_DEFINES(UInt64);
461
+ MAKE_CALL_DEFINES(Flt);
462
+ MAKE_CALL_DEFINES(Double);
463
+ define_cStr();
464
+ }
465
+
466
+
@@ -0,0 +1,15 @@
1
+ #ifndef DATA_TYPES_H__
2
+ #define DATA_TYPES_H__
3
+
4
+ union float_u {
5
+ float f;
6
+ uint32_t i;
7
+ };
8
+
9
+ extern VALUE cScalar;
10
+ extern VALUE cDataShape;
11
+ extern VALUE cDataConverter;
12
+
13
+ void define_cScalar();
14
+
15
+ #endif