cstruct 1.0.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.
- data/doc/documents.html +572 -0
- data/doc/examples/anonymous_struct.rb.html +94 -0
- data/doc/examples/anonymous_union.rb.html +93 -0
- data/doc/examples/array_member.rb.html +79 -0
- data/doc/examples/file_io.rb.html +87 -0
- data/doc/examples/first_example.rb.html +104 -0
- data/doc/examples/get_system_info.rb.html +114 -0
- data/doc/examples/get_versionex.rb.html +97 -0
- data/doc/examples/global_memory.rb.html +102 -0
- data/doc/examples/inner_struct.rb.html +79 -0
- data/doc/examples/inner_union.rb.html +77 -0
- data/doc/examples/namespace.rb.html +80 -0
- data/doc/examples/show_processes.rb.html +95 -0
- data/doc/examples/struct_member.rb.html +128 -0
- data/doc/examples.html +42 -0
- data/doc/images/Thumbs.db +0 -0
- data/doc/images/examples.png +0 -0
- data/doc/images/excample1.png +0 -0
- data/doc/images/excample2.png +0 -0
- data/doc/images/green-point.png +0 -0
- data/doc/images/learnmore.png +0 -0
- data/doc/images/logo.png +0 -0
- data/doc/images/news.png +0 -0
- data/doc/images/point.png +0 -0
- data/doc/images/start.png +0 -0
- data/doc/images/synopsish.png +0 -0
- data/doc/index.html +149 -0
- data/doc/stylesheets/coderay.css +34 -0
- data/doc/stylesheets/ie.css +9 -0
- data/doc/stylesheets/style.css +216 -0
- data/examples/anonymous_struct.rb +43 -0
- data/examples/anonymous_union.rb +42 -0
- data/examples/array_member.rb +29 -0
- data/examples/file_io.rb +49 -0
- data/examples/first_example.rb +53 -0
- data/examples/inner_struct.rb +28 -0
- data/examples/inner_union.rb +26 -0
- data/examples/namespace.rb +29 -0
- data/examples/struct_member.rb +77 -0
- data/examples/win32/get_system_info.rb +64 -0
- data/examples/win32/get_versionex.rb +47 -0
- data/examples/win32/global_memory.rb +51 -0
- data/examples/win32/show_processes.rb +45 -0
- data/lib/cstruct.rb +523 -0
- data/lib/win32struct.rb +90 -0
- data/lib/win64struct.rb +13 -0
- metadata +109 -0
data/lib/cstruct.rb
ADDED
@@ -0,0 +1,523 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2010 Wang Yong
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
###############################################
|
25
|
+
# CStruct
|
26
|
+
# Author: Wang Yong (skandhas)
|
27
|
+
# CStruct Homepage: cstruct.rubyforge.org
|
28
|
+
# E-Mail: skandhas@163.com
|
29
|
+
###############################################
|
30
|
+
|
31
|
+
require 'enumerator'
|
32
|
+
|
33
|
+
class CStruct
|
34
|
+
|
35
|
+
VERSION = '1.0.0'
|
36
|
+
|
37
|
+
public
|
38
|
+
def self.options opt_hash
|
39
|
+
raise 'Data Type Error!' unless opt_hash.is_a? Hash
|
40
|
+
@endian = opt_hash[:endian] if opt_hash.has_key?:endian
|
41
|
+
raise 'Unsupported Endian!' if @endian!=:little and @endian!=:big
|
42
|
+
@align = opt_hash[:align] if opt_hash.has_key?:align
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.endian
|
46
|
+
@endian
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.align
|
50
|
+
@align
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.field_hash
|
54
|
+
@fields
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def self.init_class_var
|
60
|
+
@size = 0
|
61
|
+
@fields = {}
|
62
|
+
@endian = :little # :little or :big
|
63
|
+
@align = 1 # Unsupport in this version
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.field symbol,fsize,fsign,dimension = nil
|
67
|
+
if dimension.is_a? Array
|
68
|
+
do_arrayfield symbol,fsize,fsign,dimension
|
69
|
+
else
|
70
|
+
do_field symbol,fsize,fsign
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.structfield symbol,sclass,ssize,dimension = nil
|
75
|
+
if dimension.is_a? Array
|
76
|
+
do_arraystructfield symbol,sclass,ssize,dimension
|
77
|
+
else
|
78
|
+
do_structfield symbol,sclass,ssize
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.inherited clazz
|
83
|
+
clazz.init_class_var
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.method_missing(method, *args)
|
87
|
+
sclass = method_to_class_by_class self,method
|
88
|
+
sclass = method_to_class_by_class Object,method unless sclass
|
89
|
+
sclass = method_to_class_by_namespace method unless sclass
|
90
|
+
sclass = method_to_class method unless sclass
|
91
|
+
super unless sclass
|
92
|
+
is_cstruct = sclass.ancestors.select{|x| x == CStruct }
|
93
|
+
if is_cstruct
|
94
|
+
symbol,dimension = *args
|
95
|
+
structfield symbol,sclass,sclass.size,dimension
|
96
|
+
else
|
97
|
+
super
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.method_to_class_by_class clazz,method
|
102
|
+
in_object_class = false
|
103
|
+
if RUBY_VERSION < '1.9'
|
104
|
+
in_object_class = clazz.constants.include? method.to_s
|
105
|
+
else
|
106
|
+
in_object_class = clazz.constants.include? method
|
107
|
+
end
|
108
|
+
return nil unless in_object_class
|
109
|
+
clazz.const_get method
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
# X::Y::A
|
114
|
+
def self.method_to_class_by_namespace method
|
115
|
+
sclass = nil
|
116
|
+
class_name_array = self.to_s.split('::')
|
117
|
+
return nil if class_name_array.size < 2
|
118
|
+
class_array = []
|
119
|
+
class_name_array.pop
|
120
|
+
class_name_array.inject(self){|m,class_name| class_array << m.const_get(class_name.to_sym); class_array.last }
|
121
|
+
class_array.reverse_each do |clazz|
|
122
|
+
if clazz.const_defined?(method)
|
123
|
+
sclass = clazz.const_get(method)
|
124
|
+
break
|
125
|
+
end
|
126
|
+
end
|
127
|
+
sclass
|
128
|
+
end
|
129
|
+
|
130
|
+
# X_Y_A
|
131
|
+
def self.method_to_class method
|
132
|
+
|
133
|
+
super_namespace = nil
|
134
|
+
class_name_array = self.to_s.split('::')
|
135
|
+
|
136
|
+
if class_name_array.size < 2
|
137
|
+
super_namespace = Object
|
138
|
+
else
|
139
|
+
class_name_array.pop
|
140
|
+
super_namespace = class_name_array.inject(Object) {|m,class_name| m.const_get(class_name.to_sym) }
|
141
|
+
end
|
142
|
+
|
143
|
+
namespace_name_array = method.to_s.split('_')
|
144
|
+
return nil if namespace_name_array.size < 2
|
145
|
+
sclass = namespace_name_array.inject(super_namespace) {|m,class_name| m.const_get(class_name.to_sym) }
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.do_field symbol,fsize,fsign
|
149
|
+
foffset = @size
|
150
|
+
@size += fsize
|
151
|
+
@fields[symbol] = [fsize,foffset,fsign,nil]
|
152
|
+
|
153
|
+
define_method(symbol) { normal_field_to_value(symbol) }
|
154
|
+
define_method("#{symbol}=") { |value| value_to_field(symbol,value) }
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.do_arrayfield symbol,fsize,fsign,dimension
|
158
|
+
bytesize = fsize * dimension.inject(1){|m,i| m*=i}
|
159
|
+
foffset = @size
|
160
|
+
@size += bytesize
|
161
|
+
@fields[symbol] = [fsize,foffset,fsign,dimension,bytesize]
|
162
|
+
|
163
|
+
define_method(symbol) { array_field_to_value(symbol) }
|
164
|
+
define_method("#{symbol}=") { |value| value_to_arrayfield(symbol,value) }
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.do_structfield symbol,sclass,ssize
|
168
|
+
foffset = @size
|
169
|
+
@size += ssize
|
170
|
+
@fields[symbol] = [ssize,foffset,:ignore,nil]
|
171
|
+
|
172
|
+
define_method(symbol) { struct_field_to_value(symbol,sclass)}
|
173
|
+
define_method("#{symbol}=") { |value| value_to_struct_field(symbol,sclass,value)}
|
174
|
+
end
|
175
|
+
|
176
|
+
def self.do_arraystructfield symbol,sclass,ssize,dimension
|
177
|
+
bytesize= ssize * dimension.inject(1){|m,i| m*=i}
|
178
|
+
foffset = @size
|
179
|
+
@size += bytesize
|
180
|
+
@fields[symbol] = [ssize,foffset,:ignore,dimension,bytesize]
|
181
|
+
|
182
|
+
define_method(symbol) { array_struct_field_to_value(symbol,sclass) }
|
183
|
+
define_method("#{symbol}=") { |value| value_to_array_struct_field(symbol,sclass,value) }
|
184
|
+
end
|
185
|
+
|
186
|
+
def self.unsigned symbol,fsize,dimension
|
187
|
+
field symbol,fsize,:unsigned,dimension
|
188
|
+
end
|
189
|
+
|
190
|
+
def self.signed symbol,fsize,dimension
|
191
|
+
field symbol,fsize,:signed,dimension
|
192
|
+
end
|
193
|
+
|
194
|
+
public
|
195
|
+
|
196
|
+
def self.size
|
197
|
+
@size
|
198
|
+
end
|
199
|
+
|
200
|
+
class<<self
|
201
|
+
alias_method :__size__, :size
|
202
|
+
|
203
|
+
[1,2,4,8].each do |i|
|
204
|
+
define_method "unsigned_#{i}byte" do |*args| # |symbol,dimension=nil|
|
205
|
+
symbol,dimension = args
|
206
|
+
unsigned symbol,i,dimension
|
207
|
+
end
|
208
|
+
define_method "signed_#{i}byte" do |*args| # |symbol,dimension=nil|
|
209
|
+
symbol,dimension = args
|
210
|
+
signed symbol,i,dimension
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def float(*args) # |symbol,dimension=nil|
|
215
|
+
symbol,dimension = args
|
216
|
+
field symbol,4,:float,dimension
|
217
|
+
end
|
218
|
+
def double(*args) # |symbol,dimension=nil|
|
219
|
+
symbol,dimension = args
|
220
|
+
field symbol,8,:double,dimension
|
221
|
+
end
|
222
|
+
|
223
|
+
alias uint64 unsigned_8byte
|
224
|
+
alias uint32 unsigned_4byte
|
225
|
+
alias uint16 unsigned_2byte
|
226
|
+
alias uint8 unsigned_1byte
|
227
|
+
alias uchar unsigned_1byte
|
228
|
+
|
229
|
+
alias int64 signed_8byte
|
230
|
+
alias int32 signed_4byte
|
231
|
+
alias int16 signed_2byte
|
232
|
+
alias int8 signed_1byte
|
233
|
+
alias char signed_1byte
|
234
|
+
end
|
235
|
+
|
236
|
+
# call init_class_var
|
237
|
+
init_class_var
|
238
|
+
|
239
|
+
# module Utils
|
240
|
+
module Utils #:nodoc: all
|
241
|
+
UnpackFormat =
|
242
|
+
{
|
243
|
+
:little => { 1=>'C',2=>'v',4=>'V',8=>'Q',:float=>'e',:double=>'E'},
|
244
|
+
:big => { 1=>'C',2=>'n',4=>'N',8=>'Q',:float=>'g',:double=>'G'}, #8=>'Q'? 'Q' is native endian
|
245
|
+
}
|
246
|
+
SigedMaxValue = { 1 => 0x7F, 2 => 0x7FFF, 4 => 0x7FFFFFFF, 8 => 0x7FFFFFFFFFFFFFFF }
|
247
|
+
UnsigedMaxValue = { 1 => 0xFF, 2 => 0xFFFF, 4 => 0xFFFFFFFF, 8 => 0xFFFFFFFFFFFFFFFF }
|
248
|
+
|
249
|
+
# buffer is a String's object
|
250
|
+
def self.unpack buffer,struct_endian,fsize,fsign
|
251
|
+
value =nil
|
252
|
+
if fsign==:float or fsign ==:double
|
253
|
+
format = UnpackFormat[struct_endian][fsign]
|
254
|
+
value = buffer.unpack(format)[0]
|
255
|
+
else
|
256
|
+
format = UnpackFormat[struct_endian][fsize]
|
257
|
+
value = buffer.unpack(format)[0]
|
258
|
+
if fsign == :signed
|
259
|
+
value = unsigned_to_signed value,fsize
|
260
|
+
end
|
261
|
+
end
|
262
|
+
value
|
263
|
+
end
|
264
|
+
|
265
|
+
# buffer is a Array's object
|
266
|
+
def self.pack buffer,struct_endian,fsize,fsign
|
267
|
+
if fsign==:float or fsign ==:double
|
268
|
+
format = UnpackFormat[struct_endian][fsign]
|
269
|
+
else
|
270
|
+
format = UnpackFormat[struct_endian][fsize]
|
271
|
+
end
|
272
|
+
buffer.pack format
|
273
|
+
end
|
274
|
+
|
275
|
+
# dosen't use monkey patch~
|
276
|
+
def self.string_setbyte string ,index,value
|
277
|
+
if RUBY_VERSION < "1.9"
|
278
|
+
string[index] = value
|
279
|
+
else
|
280
|
+
string.setbyte index,value
|
281
|
+
end
|
282
|
+
end
|
283
|
+
def self.string_getbyte string ,index
|
284
|
+
if RUBY_VERSION < "1.9"
|
285
|
+
string[index]
|
286
|
+
else
|
287
|
+
string.getbyte index
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
def self.unsigned_to_signed value,value_size
|
292
|
+
if value>SigedMaxValue[value_size]
|
293
|
+
ret = value - UnsigedMaxValue[value_size]-1
|
294
|
+
else
|
295
|
+
ret = value
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|
299
|
+
def self.buffer_setbytes(target,source,targetindex)
|
300
|
+
source.enum_for(:each_byte).each_with_index do |byte,index|
|
301
|
+
string_setbyte(target,targetindex + index,byte)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end # module Utils
|
305
|
+
|
306
|
+
public
|
307
|
+
# instance methods
|
308
|
+
attr_accessor:owner
|
309
|
+
def initialize
|
310
|
+
@data = "\0"*self.class.size
|
311
|
+
@owner = []
|
312
|
+
@data.encode!("BINARY") if RUBY_VERSION >= '1.9'
|
313
|
+
|
314
|
+
yield self if block_given?
|
315
|
+
end
|
316
|
+
|
317
|
+
def data
|
318
|
+
@data
|
319
|
+
end
|
320
|
+
|
321
|
+
def reset
|
322
|
+
(0...self.class.size).each do |i|
|
323
|
+
CStruct::Utils.string_setbyte @data,i, 0
|
324
|
+
end
|
325
|
+
sync_to_owner
|
326
|
+
end
|
327
|
+
|
328
|
+
def data= bindata
|
329
|
+
raise 'Data Type Error!' unless bindata.is_a? String
|
330
|
+
self << bindata
|
331
|
+
end
|
332
|
+
|
333
|
+
def << bindata
|
334
|
+
count = @data.size < bindata.size ? @data.size : bindata.size
|
335
|
+
(0...count).each do |i|
|
336
|
+
CStruct::Utils.string_setbyte @data,i, CStruct::Utils.string_getbyte(bindata,i)
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
def sync_to_owner
|
341
|
+
return if @owner.empty?
|
342
|
+
final_offset = @owner.inject(0) do |sum,owner_value|
|
343
|
+
_,foffset,_ = owner_value
|
344
|
+
sum+= foffset
|
345
|
+
end
|
346
|
+
onwerdata,_,_ = @owner.last
|
347
|
+
CStruct::Utils.buffer_setbytes onwerdata,@data,final_offset
|
348
|
+
end
|
349
|
+
|
350
|
+
alias __data__ data
|
351
|
+
alias __reset__ reset
|
352
|
+
alias __data__= data=
|
353
|
+
|
354
|
+
private
|
355
|
+
|
356
|
+
def normal_field_to_value symbol
|
357
|
+
make_normal_field(self.class.field_hash[symbol],self.class.endian)
|
358
|
+
end
|
359
|
+
|
360
|
+
def array_field_to_value symbol
|
361
|
+
make_array_normal_field(self.class.field_hash[symbol],self.class.endian)
|
362
|
+
end
|
363
|
+
|
364
|
+
def struct_field_to_value symbol,sclass
|
365
|
+
make_struct_field(self.class.field_hash[symbol],self.class.endian,sclass)
|
366
|
+
end
|
367
|
+
def array_struct_field_to_value symbol,sclass
|
368
|
+
make_array_struct_field(self.class.field_hash[symbol],self.class.endian,sclass)
|
369
|
+
end
|
370
|
+
|
371
|
+
def value_to_field symbol,value
|
372
|
+
dataref = @data
|
373
|
+
onwerref = @owner
|
374
|
+
self.class.class_eval do
|
375
|
+
fsize,foffset,fsign = *@fields[symbol]
|
376
|
+
bin_string = CStruct::Utils::pack [value],@endian,fsize,fsign
|
377
|
+
CStruct::Utils.buffer_setbytes dataref,bin_string,foffset
|
378
|
+
end
|
379
|
+
sync_to_owner
|
380
|
+
end
|
381
|
+
|
382
|
+
|
383
|
+
def value_to_arrayfield symbol,value
|
384
|
+
|
385
|
+
fsize,foffset,fsign,dimension,array_bytesize = *self.class.field_hash[symbol]
|
386
|
+
array_length = array_bytesize/fsize
|
387
|
+
|
388
|
+
if (fsize==1) && (value.is_a? String)
|
389
|
+
if value.length >= array_length
|
390
|
+
puts "WARNING: \"#{value}\".length(#{value.length}) >= #{symbol}.length(#{dimension})!!"
|
391
|
+
end
|
392
|
+
value = value[0...array_length-1]
|
393
|
+
CStruct::Utils.buffer_setbytes @data,value,foffset
|
394
|
+
sync_to_owner
|
395
|
+
else
|
396
|
+
raise "No Implement!(CStruct,version:#{CStruct::VERSION})"
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
def value_to_struct_field symbol,sclass,value
|
401
|
+
raise "No Implement!(CStruct,version:#{CStruct::VERSION})"
|
402
|
+
end
|
403
|
+
|
404
|
+
def value_to_array_struct_field symbol,sclass,value
|
405
|
+
raise "No Implement!(CStruct,version:#{CStruct::VERSION})"
|
406
|
+
end
|
407
|
+
|
408
|
+
def make_normal_field finfo,sendian,sclass = nil # finfo =[fsize,foffset,fsign,dimension,array_bytesize]
|
409
|
+
fsize,foffset,fsign = finfo
|
410
|
+
CStruct::Utils::unpack(@data[foffset,fsize],sendian,fsize,fsign)
|
411
|
+
end
|
412
|
+
|
413
|
+
def make_struct_field finfo,sendian,sclass # finfo =[fsize,foffset,fsign,dimension,array_bytesize]
|
414
|
+
value = sclass.new
|
415
|
+
ssize,foffset,ignore = finfo
|
416
|
+
value << @data[foffset,ssize]
|
417
|
+
value.owner << [@data,foffset,ssize]
|
418
|
+
if self.owner.size > 0
|
419
|
+
value.owner += self.owner
|
420
|
+
end
|
421
|
+
value
|
422
|
+
end
|
423
|
+
|
424
|
+
def make_array_normal_field finfo,sendian,sclass = nil # finfo =[fsize,foffset,fsign,dimension,array_bytesize]
|
425
|
+
dataref = @data
|
426
|
+
objref = self
|
427
|
+
value = buffer_to_values finfo,sendian
|
428
|
+
def value.metaclass
|
429
|
+
class<<self; self; end
|
430
|
+
end
|
431
|
+
|
432
|
+
value.metaclass.__send__ :define_method,:[]= do |i,v|
|
433
|
+
fsize,foffset,fsign = finfo
|
434
|
+
bin_string = CStruct::Utils::pack [v],sendian,fsize,fsign
|
435
|
+
CStruct::Utils.buffer_setbytes dataref,bin_string,foffset + i * fsize
|
436
|
+
objref.sync_to_owner
|
437
|
+
end
|
438
|
+
|
439
|
+
value.metaclass.__send__ :define_method,:to_cstr do value.pack("C#{value.index(0)}") end if finfo[0] == 1
|
440
|
+
|
441
|
+
if RUBY_VERSION > "1.9"
|
442
|
+
utf_endian = {:little=>"LE",:big=>"BE"}
|
443
|
+
value.metaclass.__send__ :define_method,:to_wstr do
|
444
|
+
value.pack("S#{value.index(0)}").force_encoding("UTF-16#{utf_endian[sendian]}")
|
445
|
+
end if finfo[0] == 2
|
446
|
+
|
447
|
+
value.metaclass.__send__ :define_method,:to_wstr do
|
448
|
+
value.pack("L#{value.index(0)}").force_encoding("UTF-32#{utf_endian[sendian]}")
|
449
|
+
end if finfo[0] == 4
|
450
|
+
end
|
451
|
+
|
452
|
+
value
|
453
|
+
end
|
454
|
+
|
455
|
+
def make_array_struct_field finfo,sendian,sclass # finfo =[fsize,foffset,fsign,dimension,array_bytesize]
|
456
|
+
value = buffer_to_structs finfo,sendian,sclass
|
457
|
+
end
|
458
|
+
|
459
|
+
def buffer_to_single_value fsize,foffset,iterator,sendian,fsign
|
460
|
+
CStruct::Utils::unpack(@data[foffset + iterator * fsize,fsize],sendian,fsize,fsign)
|
461
|
+
end
|
462
|
+
|
463
|
+
def buffer_to_values finfo,sendian # finfo =[fsize,foffset,fsign,dimension,array_bytesize]
|
464
|
+
value =[]
|
465
|
+
fsize,foffset,fsign,dimension,bytesize = * finfo
|
466
|
+
(0...bytesize/fsize).each do |i|
|
467
|
+
value << buffer_to_single_value(fsize,foffset,i,sendian,fsign)
|
468
|
+
end
|
469
|
+
value
|
470
|
+
end
|
471
|
+
|
472
|
+
def buffer_to_single_struct sclass,ssize,soffset,iterator,sendian,fsign
|
473
|
+
value = sclass.new
|
474
|
+
value << @data[soffset + iterator * ssize,ssize]
|
475
|
+
|
476
|
+
value.owner << [@data,soffset + iterator * ssize,ssize]
|
477
|
+
|
478
|
+
if self.owner.size > 0
|
479
|
+
value.owner += self.owner
|
480
|
+
end
|
481
|
+
value
|
482
|
+
end
|
483
|
+
|
484
|
+
def buffer_to_structs finfo,sendian,sclass # finfo =[ssize,soffset,ssign,dimension,array_bytesize]
|
485
|
+
value =[]
|
486
|
+
ssize,soffset,ssign,dimension,bytesize = finfo
|
487
|
+
(0...bytesize/ssize).each do |i|
|
488
|
+
value << buffer_to_single_struct(sclass,ssize,soffset,i,sendian,ssign)
|
489
|
+
end
|
490
|
+
value
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
494
|
+
def CStruct.union symbol,&block
|
495
|
+
union_super = self.ancestors[1]
|
496
|
+
union_class = Class.new(union_super) do
|
497
|
+
def self.change_to_union
|
498
|
+
@fields.each do|k,v|
|
499
|
+
v[1] = 0
|
500
|
+
@fields[k] = v
|
501
|
+
end
|
502
|
+
max_field_size = @fields.values.inject(0)do |max,v|
|
503
|
+
dimension = v[3]
|
504
|
+
dimension_product = 1
|
505
|
+
dimension_product = dimension.inject(1){|m,d| m *= d } if dimension.is_a? Array
|
506
|
+
field_size = v[0]* dimension_product
|
507
|
+
max = (field_size> max ? field_size : max)
|
508
|
+
end
|
509
|
+
@size = max_field_size
|
510
|
+
end
|
511
|
+
end
|
512
|
+
union_class.instance_eval(&block)
|
513
|
+
union_class.instance_eval{change_to_union}
|
514
|
+
do_structfield symbol,union_class,union_class.size
|
515
|
+
end
|
516
|
+
|
517
|
+
def CStruct.struct symbol,&block
|
518
|
+
struct_super = self.ancestors[1]
|
519
|
+
struct_class = Class.new(struct_super)
|
520
|
+
struct_class.instance_eval(&block)
|
521
|
+
do_structfield symbol,struct_class,struct_class.size
|
522
|
+
end
|
523
|
+
|
data/lib/win32struct.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
###############################################
|
2
|
+
# Win32Struct
|
3
|
+
# - TWS(Type-Wrapper-Struct) for win32
|
4
|
+
#
|
5
|
+
# Author: Wang Yong (skandhas)
|
6
|
+
# CStruct Homepage: cstruct.rubyforge.org
|
7
|
+
# E-Mail: skandhas@163.com
|
8
|
+
###############################################
|
9
|
+
|
10
|
+
require "cstruct"
|
11
|
+
class Win32Struct< CStruct
|
12
|
+
|
13
|
+
class << self
|
14
|
+
|
15
|
+
# Handle
|
16
|
+
alias HANDLE uint32
|
17
|
+
alias HMODULE uint32
|
18
|
+
alias HINSTANCE uint32
|
19
|
+
alias HRGN uint32
|
20
|
+
alias HTASK uint32
|
21
|
+
alias HKEY uint32
|
22
|
+
alias HDESK uint32
|
23
|
+
alias HMF uint32
|
24
|
+
alias HEMF uint32
|
25
|
+
alias HRSRC uint32
|
26
|
+
alias HSTR uint32
|
27
|
+
alias HWINSTA uint32
|
28
|
+
alias HKL uint32
|
29
|
+
alias HGDIOBJ uint32
|
30
|
+
|
31
|
+
alias HICON uint32
|
32
|
+
alias HPEN uint32
|
33
|
+
alias HACCEL uint32
|
34
|
+
alias HBITMAP uint32
|
35
|
+
alias HBRUSH uint32
|
36
|
+
alias HCOLORSPACE uint32
|
37
|
+
alias HDC uint32
|
38
|
+
alias HGLRC uint32
|
39
|
+
alias HENHMETAFILE uint32
|
40
|
+
alias HFONT uint32
|
41
|
+
alias HMENU uint32
|
42
|
+
alias HMETAFILE uint32
|
43
|
+
alias HPALETTE uint32
|
44
|
+
alias HCURSOR uint32
|
45
|
+
|
46
|
+
# Data Type
|
47
|
+
alias WPARAM uint32
|
48
|
+
alias LPARAM uint32
|
49
|
+
alias LRESULT uint32
|
50
|
+
alias ATOM uint32
|
51
|
+
|
52
|
+
alias BOOL uint32
|
53
|
+
alias DWORD uint32
|
54
|
+
alias WORD uint16
|
55
|
+
alias BYTE uint8
|
56
|
+
|
57
|
+
alias ULONG uint32
|
58
|
+
alias UINT uint32
|
59
|
+
alias USHORT uint16
|
60
|
+
alias UCHAR uchar
|
61
|
+
|
62
|
+
alias LONG int32
|
63
|
+
alias INT int32
|
64
|
+
alias SHORT int16
|
65
|
+
alias CHAR char
|
66
|
+
alias WCHAR uint16
|
67
|
+
|
68
|
+
# Pointer
|
69
|
+
alias DWORD_PTR uint32
|
70
|
+
alias ULONG_PTR uint32
|
71
|
+
alias UINT_PTR uint32
|
72
|
+
alias PHANDLE uint32
|
73
|
+
|
74
|
+
alias PBOOL uint32
|
75
|
+
alias LPBOOL uint32
|
76
|
+
alias PBYTE uint32
|
77
|
+
alias LPBYTE uint32
|
78
|
+
alias PINT uint32
|
79
|
+
alias LPINT uint32
|
80
|
+
alias PWORD uint32
|
81
|
+
alias LPWORD uint32
|
82
|
+
alias LPLONG uint32
|
83
|
+
alias PDWORD uint32
|
84
|
+
alias LPDWORD uint32
|
85
|
+
alias LPVOID uint32
|
86
|
+
alias LPCVOID uint32
|
87
|
+
alias LPCSTR uint32
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
data/lib/win64struct.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
###############################################
|
2
|
+
# Win64Struct
|
3
|
+
# - TWS(Type-Wrapper-Struct) for win64
|
4
|
+
#
|
5
|
+
# Author: Wang Yong (skandhas)
|
6
|
+
# CStruct Homepage: cstruct.rubyforge.org
|
7
|
+
# E-Mail: skandhas@163.com
|
8
|
+
###############################################
|
9
|
+
|
10
|
+
require "cstruct"
|
11
|
+
class Win64Struct< CStruct
|
12
|
+
"No Implement!"
|
13
|
+
end
|