libbin 1.0.7 → 1.0.8

Sign up to get free protection for your applications and to get access to all the features.
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