gogyou 0.2.3 → 0.2.4
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 +4 -4
- data/HISTORY.ja.md +57 -0
- data/LICENSE +1 -1
- data/README.md +129 -44
- data/Rakefile +4 -1
- data/gemstub.rb +2 -2
- data/lib/gogyou.rb +66 -40
- data/lib/gogyou/accessor.rb +80 -57
- data/lib/gogyou/bytearray.rb +856 -0
- data/lib/gogyou/extensions.rb +477 -0
- data/lib/gogyou/ffi.rb +52 -0
- data/lib/gogyou/fiddle.rb +53 -0
- data/lib/gogyou/primitives.rb +160 -52
- data/lib/gogyou/typespec.rb +1 -1
- data/lib/gogyou/version.rb +1 -1
- data/mkprims.rb +74 -38
- data/test/test_loadstore.rb +65 -0
- data/test/test_packbin.rb +65 -0
- metadata +21 -8
- data/lib/gogyou/mixin.rb +0 -640
@@ -0,0 +1,477 @@
|
|
1
|
+
#vim set fileencoding:utf-8
|
2
|
+
|
3
|
+
require_relative "typespec"
|
4
|
+
require_relative "bytearray"
|
5
|
+
|
6
|
+
module Gogyou
|
7
|
+
module Aux
|
8
|
+
def self.define_pack_binary(mod, name, bitsize, exponent_bitsize, fraction_bitsize)
|
9
|
+
sign_bit = 1 << (fraction_bitsize + exponent_bitsize)
|
10
|
+
fraction_bitmask = ~(~0 << fraction_bitsize)
|
11
|
+
exponent_bitmask = ~(~0 << exponent_bitsize)
|
12
|
+
exponent_bias = (exponent_bitmask >> 1) - 1
|
13
|
+
exponent_max = (exponent_bitmask >> 1) + 2
|
14
|
+
exponent_min = -exponent_max
|
15
|
+
fraction_msb = 1 << fraction_bitsize
|
16
|
+
fraction_bias = 1 << (fraction_bitsize + 1)
|
17
|
+
nan = (exponent_bitmask << fraction_bitsize) | (fraction_msb >> 1)
|
18
|
+
infinity = (exponent_max + exponent_bias) << fraction_bitsize
|
19
|
+
|
20
|
+
mod.module_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
21
|
+
def #{name}
|
22
|
+
num = Float(self)
|
23
|
+
|
24
|
+
return #{nan} if num.nan?
|
25
|
+
|
26
|
+
n = (num < 0 || (1 / num) < 0) ? #{sign_bit} : 0
|
27
|
+
return n if num == 0
|
28
|
+
|
29
|
+
return n | #{infinity} if num.infinite?
|
30
|
+
|
31
|
+
num = -num unless n == 0
|
32
|
+
(coefficient, e) = Math.frexp(num)
|
33
|
+
case
|
34
|
+
when e > #{exponent_max}
|
35
|
+
n | #{infinity}
|
36
|
+
when e < #{exponent_min}
|
37
|
+
n
|
38
|
+
else
|
39
|
+
coefficient = (coefficient * #{fraction_bias}).to_i
|
40
|
+
n |= ((e + #{exponent_bias}) & #{exponent_bitmask}) << #{fraction_bitsize}
|
41
|
+
n | coefficient & #{fraction_bitmask}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
EOS
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.define_unpack_binary(mod, name, bitsize, exponent_bitsize, fraction_bitsize)
|
48
|
+
sign_bit = 1 << (fraction_bitsize + exponent_bitsize)
|
49
|
+
fraction_bitmask = ~(~0 << fraction_bitsize)
|
50
|
+
exponent_bitmask = ~(~0 << exponent_bitsize)
|
51
|
+
exponent_bias = (exponent_bitmask >> 1) - 1
|
52
|
+
fraction_msb = 1 << fraction_bitsize
|
53
|
+
fraction_bias = (1 << (fraction_bitsize + 1)).to_f
|
54
|
+
|
55
|
+
mod.module_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
56
|
+
def #{name}
|
57
|
+
n = self.to_i
|
58
|
+
e = (n >> #{fraction_bitsize}) & #{exponent_bitmask}
|
59
|
+
s = (n & #{sign_bit}) != 0
|
60
|
+
case e
|
61
|
+
when 0
|
62
|
+
return s ? -0.0 : 0.0
|
63
|
+
when #{exponent_bitmask}
|
64
|
+
if (n & #{fraction_bitmask}) != 0
|
65
|
+
return Float::NAN
|
66
|
+
else
|
67
|
+
return s ? -Float::INFINITY : Float::INFINITY
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
e -= #{exponent_bias}
|
72
|
+
c = ((n & #{fraction_bitmask}) | #{fraction_msb}) / #{fraction_bias}
|
73
|
+
num = Math.ldexp(c, e)
|
74
|
+
num = -num if s
|
75
|
+
|
76
|
+
num
|
77
|
+
end
|
78
|
+
EOS
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
module Extensions
|
83
|
+
module ObjectClass
|
84
|
+
end
|
85
|
+
|
86
|
+
module Object
|
87
|
+
def infect_from(*obj)
|
88
|
+
obj.each { |o| taint if o.tainted? }
|
89
|
+
self
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class ::Object
|
94
|
+
extend Gogyou::Extensions::ObjectClass
|
95
|
+
include Gogyou::Extensions::Object
|
96
|
+
end
|
97
|
+
|
98
|
+
UNIT_B = 1 << 0
|
99
|
+
UNIT_KiB = 1 << 10
|
100
|
+
UNIT_MiB = 1 << 20
|
101
|
+
UNIT_GiB = 1 << 30
|
102
|
+
UNIT_TiB = 1 << 40
|
103
|
+
UNIT_PiB = 1 << 50
|
104
|
+
UNIT_EiB = 1 << 60
|
105
|
+
UNIT_ZiB = 1 << 70
|
106
|
+
UNIT_YiB = 1 << 80
|
107
|
+
|
108
|
+
module NumericClass
|
109
|
+
end
|
110
|
+
|
111
|
+
module Numeric
|
112
|
+
def B
|
113
|
+
UNIT_B * self
|
114
|
+
end
|
115
|
+
|
116
|
+
def KiB
|
117
|
+
UNIT_KiB * self
|
118
|
+
end
|
119
|
+
|
120
|
+
def MiB
|
121
|
+
UNIT_MiB * self
|
122
|
+
end
|
123
|
+
|
124
|
+
def GiB
|
125
|
+
UNIT_GiB * self
|
126
|
+
end
|
127
|
+
|
128
|
+
def TiB
|
129
|
+
UNIT_TiB * self
|
130
|
+
end
|
131
|
+
|
132
|
+
def PiB
|
133
|
+
UNIT_PiB * self
|
134
|
+
end
|
135
|
+
|
136
|
+
def EiB
|
137
|
+
UNIT_EiB * self
|
138
|
+
end
|
139
|
+
|
140
|
+
def ZiB
|
141
|
+
UNIT_ZiB * self
|
142
|
+
end
|
143
|
+
|
144
|
+
def YiB
|
145
|
+
UNIT_YiB * self
|
146
|
+
end
|
147
|
+
|
148
|
+
def unit_floor(unit)
|
149
|
+
(self / unit).to_i
|
150
|
+
end
|
151
|
+
|
152
|
+
def unit_ceil(unit)
|
153
|
+
((self + (unit - 1)) / unit).to_i
|
154
|
+
end
|
155
|
+
|
156
|
+
def align_floor(unit)
|
157
|
+
((self / unit).to_i * unit).to_i
|
158
|
+
end
|
159
|
+
|
160
|
+
def align_ceil(unit)
|
161
|
+
(((self + (unit - 1)) / unit).to_i * unit).to_i
|
162
|
+
end
|
163
|
+
|
164
|
+
Aux.define_pack_binary(self, :pack_binary16, 16, 5, 10)
|
165
|
+
#
|
166
|
+
# pack to IEEE 754 Half precision (16 bits; 5 bit exponents, 10 bit fractions)
|
167
|
+
#
|
168
|
+
# SEE Gogyou::Aux.define_pack_binary FOR IMPLEMENTATION.
|
169
|
+
#
|
170
|
+
def pack_binary16
|
171
|
+
THIS IS FAKED IMPLEMENTATION FOR RDOC
|
172
|
+
end if false
|
173
|
+
|
174
|
+
Aux.define_pack_binary(self, :pack_binary32, 32, 8, 23)
|
175
|
+
#
|
176
|
+
# pack to IEEE 754 Single precision (32 bits; 8 bit exponents, 23 bit fractions)
|
177
|
+
#
|
178
|
+
# SEE Gogyou::Aux.define_pack_binary FOR IMPLEMENTATION.
|
179
|
+
#
|
180
|
+
def pack_binary32
|
181
|
+
THIS IS FAKED IMPLEMENTATION FOR RDOC
|
182
|
+
end if false
|
183
|
+
|
184
|
+
Aux.define_pack_binary(self, :pack_binary64, 64, 11, 52)
|
185
|
+
#
|
186
|
+
# pack to IEEE 754 Double precision (64 bits; 11 bit exponents, 52 bit fractions)
|
187
|
+
#
|
188
|
+
# SEE Gogyou::Aux.define_pack_binary FOR IMPLEMENTATION.
|
189
|
+
#
|
190
|
+
def pack_binary64
|
191
|
+
THIS IS FAKED IMPLEMENTATION FOR RDOC
|
192
|
+
end if false
|
193
|
+
|
194
|
+
Aux.define_unpack_binary(self, :unpack_binary16, 16, 5, 10)
|
195
|
+
#
|
196
|
+
# unpack to IEEE 754 Half precision (16 bits; 5 bit exponents, 10 bit fractions)
|
197
|
+
#
|
198
|
+
# SEE Gogyou::Aux.define_unpack_binary FOR IMPLEMENTATION.
|
199
|
+
#
|
200
|
+
def unpack_binary16
|
201
|
+
THIS IS FAKED IMPLEMENTATION FOR RDOC
|
202
|
+
end if false
|
203
|
+
|
204
|
+
Aux.define_unpack_binary(self, :unpack_binary32, 32, 8, 23)
|
205
|
+
#
|
206
|
+
# unpack to IEEE 754 Single precision (32 bits; 8 bit exponents, 23 bit fractions)
|
207
|
+
#
|
208
|
+
# SEE Gogyou::Aux.define_unpack_binary FOR IMPLEMENTATION.
|
209
|
+
#
|
210
|
+
def unpack_binary32
|
211
|
+
THIS IS FAKED IMPLEMENTATION FOR RDOC
|
212
|
+
end if false
|
213
|
+
|
214
|
+
Aux.define_unpack_binary(self, :unpack_binary64, 64, 11, 52)
|
215
|
+
#
|
216
|
+
# unpack to IEEE 754 Double precision (64 bits; 11 bit exponents, 52 bit fractions)
|
217
|
+
#
|
218
|
+
# SEE Gogyou::Aux.define_unpack_binary FOR IMPLEMENTATION.
|
219
|
+
#
|
220
|
+
def unpack_binary64
|
221
|
+
THIS IS FAKED IMPLEMENTATION FOR RDOC
|
222
|
+
end if false
|
223
|
+
end
|
224
|
+
|
225
|
+
class ::Numeric
|
226
|
+
extend Gogyou::Extensions::NumericClass
|
227
|
+
include Gogyou::Extensions::Numeric
|
228
|
+
end
|
229
|
+
|
230
|
+
module IntegerClass
|
231
|
+
module_function
|
232
|
+
def bitmask(shift, bits)
|
233
|
+
~(~0 << bits) << shift
|
234
|
+
end
|
235
|
+
|
236
|
+
public :bitmask
|
237
|
+
public_class_method :bitmask
|
238
|
+
end
|
239
|
+
|
240
|
+
module Integer
|
241
|
+
extend IntegerClass
|
242
|
+
|
243
|
+
def getbit(shift, bits)
|
244
|
+
(self >> shift) & Integer.bitmask(0, bits)
|
245
|
+
end
|
246
|
+
|
247
|
+
def getbits(shift, bits)
|
248
|
+
getbit(shift, bits).extendsign(bits)
|
249
|
+
end
|
250
|
+
|
251
|
+
def getbitset(*bitsize)
|
252
|
+
shift = 0
|
253
|
+
list = []
|
254
|
+
bitsize.each do |bits|
|
255
|
+
if bits > 0
|
256
|
+
list << getbit(shift, bits)
|
257
|
+
shift += bits
|
258
|
+
else
|
259
|
+
list << 0
|
260
|
+
end
|
261
|
+
end
|
262
|
+
list
|
263
|
+
end
|
264
|
+
|
265
|
+
def setbit(shift, bits, num)
|
266
|
+
mask = Integer.bitmask(shift, bits)
|
267
|
+
(self & ~mask) | ((num << shift) & mask)
|
268
|
+
end
|
269
|
+
|
270
|
+
def extendsign(bits)
|
271
|
+
n = self & Integer.bitmask(0, bits)
|
272
|
+
if (n >> (bits - 1)) == 0
|
273
|
+
n
|
274
|
+
else
|
275
|
+
n | (~0 << bits)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def extendsign_char
|
280
|
+
((self & 0xff) ^ 0x80) - 0x80
|
281
|
+
end
|
282
|
+
|
283
|
+
def swapbyte(bytesize)
|
284
|
+
num = 0
|
285
|
+
bytesize.times do |i|
|
286
|
+
num <<= 8
|
287
|
+
num |= (self >> (i * 8)) & 0xff
|
288
|
+
end
|
289
|
+
num
|
290
|
+
end
|
291
|
+
|
292
|
+
def swap16
|
293
|
+
n = self & 0xffff
|
294
|
+
((n >> 8) & 0xff) | ((n & 0xff) << 8)
|
295
|
+
end
|
296
|
+
|
297
|
+
def swap16s
|
298
|
+
n = self & 0xffff
|
299
|
+
((n >> 8) & 0xff) | ((n & 0xff).extendsign_char << 8)
|
300
|
+
end
|
301
|
+
|
302
|
+
def swap24
|
303
|
+
n = self & 0xffffff
|
304
|
+
((n >> 16) & 0xff) |
|
305
|
+
(n & 0xff00) |
|
306
|
+
((n & 0xff) << 16)
|
307
|
+
end
|
308
|
+
|
309
|
+
def swap24s
|
310
|
+
n = self & 0xffffff
|
311
|
+
((n >> 16) & 0xff) |
|
312
|
+
(n & 0xff00) |
|
313
|
+
((n & 0xff).extendsign_char << 16)
|
314
|
+
end
|
315
|
+
|
316
|
+
def swap32
|
317
|
+
n = self & 0xffffffff
|
318
|
+
((n >> 24) & 0xff) |
|
319
|
+
((n >> 8) & 0xff00) |
|
320
|
+
((n & 0xff00) << 8) |
|
321
|
+
((n & 0xff) << 24)
|
322
|
+
end
|
323
|
+
|
324
|
+
def swap32s
|
325
|
+
n = self & 0xffffffff
|
326
|
+
((n >> 24) & 0xff) |
|
327
|
+
((n >> 8) & 0xff00) |
|
328
|
+
((n & 0xff00) << 8) |
|
329
|
+
((n & 0xff).extendsign_char << 24)
|
330
|
+
end
|
331
|
+
|
332
|
+
def swap48
|
333
|
+
n = self & 0xffffffffffff
|
334
|
+
((n >> 40) & 0xff) |
|
335
|
+
((n >> 24) & 0xff00) |
|
336
|
+
((n >> 8) & 0xff0000) |
|
337
|
+
((n & 0xff0000) << 8) |
|
338
|
+
((n & 0xff00) << 24) |
|
339
|
+
((n & 0xff) << 40)
|
340
|
+
end
|
341
|
+
|
342
|
+
def swap48s
|
343
|
+
n = self & 0xffffffffffff
|
344
|
+
((n >> 40) & 0xff) |
|
345
|
+
((n >> 24) & 0xff00) |
|
346
|
+
((n >> 8) & 0xff0000) |
|
347
|
+
((n & 0xff0000) << 8) |
|
348
|
+
((n & 0xff00) << 24) |
|
349
|
+
((n & 0xff).extendsign_char << 40)
|
350
|
+
end
|
351
|
+
|
352
|
+
def swap64
|
353
|
+
n = self & 0xffffffffffffffff
|
354
|
+
((n >> 56) & 0xff) |
|
355
|
+
((n >> 40) & 0xff00) |
|
356
|
+
((n >> 24) & 0xff0000) |
|
357
|
+
((n >> 8) & 0xff000000) |
|
358
|
+
((n & 0xff000000) << 8) |
|
359
|
+
((n & 0xff0000) << 24) |
|
360
|
+
((n & 0xff00) << 40) |
|
361
|
+
((n & 0xff) << 56)
|
362
|
+
end
|
363
|
+
|
364
|
+
def swap64s
|
365
|
+
n = self & 0xffffffffffffffff
|
366
|
+
((n >> 56) & 0xff) |
|
367
|
+
((n >> 40) & 0xff00) |
|
368
|
+
((n >> 24) & 0xff0000) |
|
369
|
+
((n >> 8) & 0xff000000) |
|
370
|
+
((n & 0xff000000) << 8) |
|
371
|
+
((n & 0xff0000) << 24) |
|
372
|
+
((n & 0xff00) << 40) |
|
373
|
+
((n & 0xff).extendsign_char << 56)
|
374
|
+
end
|
375
|
+
|
376
|
+
def swap96
|
377
|
+
(swap48 << 48) | (self >> 48).swap48
|
378
|
+
end
|
379
|
+
|
380
|
+
def swap96s
|
381
|
+
(swap48s << 48) | (self >> 48).swap48
|
382
|
+
end
|
383
|
+
|
384
|
+
def swap128
|
385
|
+
(swap64 << 64) | (self >> 64).swap64
|
386
|
+
end
|
387
|
+
|
388
|
+
def swap128s
|
389
|
+
(swap64s << 64) | (self >> 64).swap64
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
class ::Integer
|
394
|
+
extend Gogyou::Extensions::IntegerClass
|
395
|
+
include Gogyou::Extensions::Integer
|
396
|
+
end
|
397
|
+
|
398
|
+
module StringClass
|
399
|
+
BITS_PER_BYTE = 8
|
400
|
+
|
401
|
+
module_function
|
402
|
+
def malloc(bytesize)
|
403
|
+
?\0.force_encoding(Encoding::BINARY) * bytesize
|
404
|
+
end
|
405
|
+
|
406
|
+
public :malloc
|
407
|
+
|
408
|
+
alias alloc malloc
|
409
|
+
|
410
|
+
class << self
|
411
|
+
alias alloc malloc
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
module String
|
416
|
+
def to_address
|
417
|
+
[self].pack("p").load_sizet(0)
|
418
|
+
end
|
419
|
+
|
420
|
+
alias to_ptr to_address
|
421
|
+
|
422
|
+
def binary_operation
|
423
|
+
enc = encoding
|
424
|
+
force_encoding(Encoding::BINARY)
|
425
|
+
begin
|
426
|
+
yield
|
427
|
+
ensure
|
428
|
+
force_encoding(enc) rescue nil if enc
|
429
|
+
end
|
430
|
+
end
|
431
|
+
|
432
|
+
def resize(newsize)
|
433
|
+
binary_operation do
|
434
|
+
left = newsize - bytesize
|
435
|
+
case
|
436
|
+
when left > 0
|
437
|
+
while left >= ZERO_BUFFER.bytesize
|
438
|
+
concat(ZERO_BUFFER)
|
439
|
+
left -= ZERO_BUFFER.bytesize
|
440
|
+
end
|
441
|
+
if left > 0
|
442
|
+
zero = ZERO_BUFFER[ZERO_BUFFER.bytesize - left, left] # make shared string
|
443
|
+
concat(zero)
|
444
|
+
end
|
445
|
+
when left < 0
|
446
|
+
left = - left
|
447
|
+
self[bytesize - left, left] = ""
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
self
|
452
|
+
end
|
453
|
+
|
454
|
+
def setbinary(index, mem, offset = 0, size = mem.bytesize)
|
455
|
+
offset = offset.to_i
|
456
|
+
size = size.to_i
|
457
|
+
size1 = mem.bytesize - offset
|
458
|
+
size = size1 if size > size1
|
459
|
+
if size > 0
|
460
|
+
binary_operation do
|
461
|
+
self[index.to_i, size] = mem.byteslice(offset, size)
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
self
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
ZERO_BUFFER = StringClass.malloc(64.KiB).freeze
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
class ::String
|
474
|
+
extend Gogyou::Extensions::StringClass
|
475
|
+
include Gogyou::Extensions::String
|
476
|
+
include Gogyou::Extensions::ByteArray
|
477
|
+
end
|