cstruct 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +81 -0
- data/cstruct.gemspec +10 -0
- data/doc/examples/anonymous_struct.rb.html +94 -94
- data/doc/examples/anonymous_union.rb.html +93 -93
- data/doc/examples/array_member.rb.html +79 -79
- data/doc/examples/file_io.rb.html +87 -87
- data/doc/examples/first_example.rb.html +104 -104
- data/doc/examples/get_system_info.rb.html +114 -114
- data/doc/examples/get_versionex.rb.html +97 -97
- data/doc/examples/global_memory.rb.html +102 -102
- data/doc/examples/inner_struct.rb.html +79 -79
- data/doc/examples/inner_union.rb.html +77 -77
- data/doc/examples/namespace.rb.html +80 -80
- data/doc/examples/show_processes.rb.html +95 -95
- data/doc/examples/struct_member.rb.html +128 -128
- data/doc/stylesheets/ie.css +8 -8
- data/examples/anonymous_struct.rb +6 -6
- data/examples/anonymous_union.rb +5 -5
- data/examples/array_member.rb +1 -1
- data/examples/file_io.rb +22 -23
- data/examples/first_example.rb +4 -4
- data/examples/inner_struct.rb +5 -5
- data/examples/inner_union.rb +4 -4
- data/examples/namespace.rb +15 -15
- data/examples/win32/get_system_info.rb +31 -31
- data/examples/win32/get_versionex.rb +12 -12
- data/examples/win32/global_memory.rb +9 -9
- data/examples/win32/show_processes.rb +28 -28
- data/lib/cstruct.rb +1 -523
- data/lib/cstruct/cstruct.rb +457 -0
- data/lib/cstruct/field.rb +45 -0
- data/lib/cstruct/utils.rb +53 -0
- data/lib/cstruct/win32struct.rb +84 -0
- data/lib/cstruct/win64struct.rb +5 -0
- data/lib/win32struct.rb +3 -90
- data/lib/win64struct.rb +3 -13
- data/spec/cstruct_spec.rb +240 -0
- metadata +62 -73
@@ -0,0 +1,45 @@
|
|
1
|
+
class CStruct
|
2
|
+
class Field #:nodoc: all
|
3
|
+
attr_accessor:tag
|
4
|
+
attr_accessor:size
|
5
|
+
attr_accessor:offset
|
6
|
+
attr_accessor:sign
|
7
|
+
attr_accessor:dimension
|
8
|
+
|
9
|
+
def initialize(tag,size,offset,sign,dimension = nil,*args)
|
10
|
+
@tag = tag
|
11
|
+
@size = size
|
12
|
+
@offset = offset
|
13
|
+
@sign = sign
|
14
|
+
@dimension = dimension
|
15
|
+
@byte_size = size
|
16
|
+
|
17
|
+
if @dimension
|
18
|
+
@byte_size = @size * dimension.inject(1){|m,i| m*=i}
|
19
|
+
@sign = :struct_array if @sign == :struct
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def byte_size
|
25
|
+
@byte_size
|
26
|
+
end
|
27
|
+
|
28
|
+
def is_float?
|
29
|
+
@sign == :float
|
30
|
+
end
|
31
|
+
|
32
|
+
def is_double?
|
33
|
+
@sign == :double
|
34
|
+
end
|
35
|
+
|
36
|
+
def is_struct?
|
37
|
+
@sign == :struct
|
38
|
+
end
|
39
|
+
|
40
|
+
def is_union?
|
41
|
+
@sign == :union
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'enumerator'
|
2
|
+
|
3
|
+
class CStruct
|
4
|
+
module Utils #:nodoc: all
|
5
|
+
UnpackFormat =
|
6
|
+
{
|
7
|
+
:little => { 1=>'C',2=>'v',4=>'V',8=>'Q',:float=>'e',:double=>'E'},
|
8
|
+
:big => { 1=>'C',2=>'n',4=>'N',8=>'Q',:float=>'g',:double=>'G'}, #8=>'Q'? 'Q' is native endian
|
9
|
+
}
|
10
|
+
SigedMaxValue = { 1 => 0x7F, 2 => 0x7FFF, 4 => 0x7FFFFFFF, 8 => 0x7FFFFFFFFFFFFFFF }
|
11
|
+
UnsigedMaxValue = { 1 => 0xFF, 2 => 0xFFFF, 4 => 0xFFFFFFFF, 8 => 0xFFFFFFFFFFFFFFFF }
|
12
|
+
|
13
|
+
class << self
|
14
|
+
# buffer is a String's object
|
15
|
+
def unpack(buffer,struct_endian,fsize,fsign)
|
16
|
+
format_index = (fsign==:float or fsign ==:double) ? (fsign):(fsize)
|
17
|
+
format = UnpackFormat[struct_endian][format_index]
|
18
|
+
value = buffer.unpack(format).first
|
19
|
+
|
20
|
+
if fsign == :signed
|
21
|
+
value = unsigned_to_signed value,fsize
|
22
|
+
end
|
23
|
+
value
|
24
|
+
end
|
25
|
+
|
26
|
+
# buffer is a Array's object
|
27
|
+
def pack(buffer,struct_endian,fsize,fsign)
|
28
|
+
format_index = (fsign==:float or fsign ==:double) ? (fsign):(fsize)
|
29
|
+
format = UnpackFormat[struct_endian][format_index]
|
30
|
+
buffer.pack format
|
31
|
+
end
|
32
|
+
|
33
|
+
def string_setbyte(string,index,value)
|
34
|
+
RUBY_VERSION < "1.9" ? (string[index] = value):(string.setbyte index,value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def string_getbyte(string,index)
|
38
|
+
RUBY_VERSION < "1.9" ? (string[index]):(string.getbyte index)
|
39
|
+
end
|
40
|
+
|
41
|
+
def unsigned_to_signed(value,value_size)
|
42
|
+
value > SigedMaxValue[value_size] ? (value - UnsigedMaxValue[value_size]-1):(value)
|
43
|
+
end
|
44
|
+
|
45
|
+
def buffer_setbytes(target,source,target_index)
|
46
|
+
source.enum_for(:each_byte).each_with_index do |byte,index|
|
47
|
+
string_setbyte(target,target_index + index,byte)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "cstruct/cstruct"
|
2
|
+
#
|
3
|
+
# ===Description
|
4
|
+
# Win32Struct defined some Win32 type,like as: HANDLE,HMODULE,...
|
5
|
+
# ===How to use
|
6
|
+
# require 'cstruct/win32struct
|
7
|
+
#
|
8
|
+
class Win32Struct< CStruct
|
9
|
+
class << self
|
10
|
+
# Handle
|
11
|
+
alias HANDLE uint32
|
12
|
+
alias HMODULE uint32
|
13
|
+
alias HINSTANCE uint32
|
14
|
+
alias HRGN uint32
|
15
|
+
alias HTASK uint32
|
16
|
+
alias HKEY uint32
|
17
|
+
alias HDESK uint32
|
18
|
+
alias HMF uint32
|
19
|
+
alias HEMF uint32
|
20
|
+
alias HRSRC uint32
|
21
|
+
alias HSTR uint32
|
22
|
+
alias HWINSTA uint32
|
23
|
+
alias HKL uint32
|
24
|
+
alias HGDIOBJ uint32
|
25
|
+
alias HICON uint32
|
26
|
+
alias HPEN uint32
|
27
|
+
alias HACCEL uint32
|
28
|
+
alias HBITMAP uint32
|
29
|
+
alias HBRUSH uint32
|
30
|
+
alias HCOLORSPACE uint32
|
31
|
+
alias HDC uint32
|
32
|
+
alias HGLRC uint32
|
33
|
+
alias HENHMETAFILE uint32
|
34
|
+
alias HFONT uint32
|
35
|
+
alias HMENU uint32
|
36
|
+
alias HMETAFILE uint32
|
37
|
+
alias HPALETTE uint32
|
38
|
+
alias HCURSOR uint32
|
39
|
+
|
40
|
+
# Data Type
|
41
|
+
alias WPARAM uint32
|
42
|
+
alias LPARAM uint32
|
43
|
+
alias LRESULT uint32
|
44
|
+
alias ATOM uint32
|
45
|
+
|
46
|
+
alias BOOL uint32
|
47
|
+
alias DWORD uint32
|
48
|
+
alias WORD uint16
|
49
|
+
alias BYTE uint8
|
50
|
+
|
51
|
+
alias ULONG uint32
|
52
|
+
alias UINT uint32
|
53
|
+
alias USHORT uint16
|
54
|
+
alias UCHAR uchar
|
55
|
+
|
56
|
+
alias LONG int32
|
57
|
+
alias INT int32
|
58
|
+
alias SHORT int16
|
59
|
+
alias CHAR char
|
60
|
+
alias WCHAR uint16
|
61
|
+
|
62
|
+
# Pointer
|
63
|
+
alias DWORD_PTR uint32
|
64
|
+
alias ULONG_PTR uint32
|
65
|
+
alias UINT_PTR uint32
|
66
|
+
alias PHANDLE uint32
|
67
|
+
|
68
|
+
alias PBOOL uint32
|
69
|
+
alias LPBOOL uint32
|
70
|
+
alias PBYTE uint32
|
71
|
+
alias LPBYTE uint32
|
72
|
+
alias PINT uint32
|
73
|
+
alias LPINT uint32
|
74
|
+
alias PWORD uint32
|
75
|
+
alias LPWORD uint32
|
76
|
+
alias LPLONG uint32
|
77
|
+
alias PDWORD uint32
|
78
|
+
alias LPDWORD uint32
|
79
|
+
alias LPVOID uint32
|
80
|
+
alias LPCVOID uint32
|
81
|
+
alias LPCSTR uint32
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
data/lib/win32struct.rb
CHANGED
@@ -1,90 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
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
|
1
|
+
require 'cstruct/win32struct'
|
2
|
+
puts "In CStruct-#{CStruct::VERSION} require 'win32struct' is not recommended."
|
3
|
+
puts "Replacing 'win32struct' by 'cstruct/win32struct'."
|
data/lib/win64struct.rb
CHANGED
@@ -1,13 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
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
|
1
|
+
require 'cstruct/win64struct'
|
2
|
+
puts "In CStruct-#{CStruct::VERSION} require 'win64struct' is not recommended."
|
3
|
+
puts "Replacing 'win32struct' by 'cstruct/win64struct'."
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'cstruct'
|
3
|
+
|
4
|
+
puts "Test CStruct-#{CStruct::VERSION}"
|
5
|
+
|
6
|
+
describe 'Normal Member -> Point' do
|
7
|
+
subject do
|
8
|
+
|
9
|
+
class Point < CStruct
|
10
|
+
int32:x
|
11
|
+
int32:y
|
12
|
+
end
|
13
|
+
|
14
|
+
point = Point.new
|
15
|
+
point.x,point.y = -10,20
|
16
|
+
point
|
17
|
+
end
|
18
|
+
its(:x) { should == -10 }
|
19
|
+
its(:y) { should == 20 }
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'Struct Member -> Line' do
|
23
|
+
subject do
|
24
|
+
class Point < CStruct
|
25
|
+
int32:x
|
26
|
+
int32:y
|
27
|
+
end
|
28
|
+
|
29
|
+
class Line < CStruct
|
30
|
+
Point:begin_point
|
31
|
+
Point:end_point
|
32
|
+
end
|
33
|
+
|
34
|
+
line = Line.new
|
35
|
+
line.begin_point.x = 10
|
36
|
+
line.begin_point.y = 20
|
37
|
+
line
|
38
|
+
end
|
39
|
+
its(:'begin_point.x') { should == 10 }
|
40
|
+
its(:'begin_point.y') { should == 20 }
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'Array Member -> Collection' do
|
44
|
+
subject do
|
45
|
+
|
46
|
+
class Collection < CStruct
|
47
|
+
int32:elements,[8]
|
48
|
+
end
|
49
|
+
|
50
|
+
collection = Collection.new
|
51
|
+
|
52
|
+
(0..7).each do |i|
|
53
|
+
collection.elements[i] = i # assign like as C language
|
54
|
+
end
|
55
|
+
|
56
|
+
collection
|
57
|
+
end
|
58
|
+
its(:elements) { should == (0..7).to_a }
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'Array Struct Member -> PointArray' do
|
62
|
+
it 'PointArray' do
|
63
|
+
class Point < CStruct
|
64
|
+
double:x
|
65
|
+
double:y
|
66
|
+
end
|
67
|
+
|
68
|
+
class PointArray < CStruct
|
69
|
+
Point:elements,[4]
|
70
|
+
end
|
71
|
+
|
72
|
+
array = PointArray.new
|
73
|
+
(0..3).each do |i|
|
74
|
+
array.elements[i].x = i+0.234
|
75
|
+
array.elements[i].y = i+1.667
|
76
|
+
end
|
77
|
+
|
78
|
+
(0..3).each do |i|
|
79
|
+
array.elements[i].x.should == i+0.234
|
80
|
+
array.elements[i].y.should == i+1.667
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
describe 'Inner Struct Member-> T' do
|
88
|
+
subject do
|
89
|
+
class T < CStruct
|
90
|
+
class Inner < CStruct
|
91
|
+
int32 :v1
|
92
|
+
int32 :v2
|
93
|
+
end
|
94
|
+
Inner :inner
|
95
|
+
end
|
96
|
+
|
97
|
+
t = T.new
|
98
|
+
t.inner.v1 = 10
|
99
|
+
t.inner.v2 = 20
|
100
|
+
t
|
101
|
+
end
|
102
|
+
its(:'inner.v1') { should == 10 }
|
103
|
+
its(:'inner.v2') { should == 20 }
|
104
|
+
end
|
105
|
+
|
106
|
+
describe 'Anonymous Struct Member -> Window' do
|
107
|
+
subject do
|
108
|
+
class Window < CStruct
|
109
|
+
int32:style
|
110
|
+
struct :position do
|
111
|
+
int32:x
|
112
|
+
int32:y
|
113
|
+
end
|
114
|
+
end
|
115
|
+
window = Window.new
|
116
|
+
window.style = 1
|
117
|
+
window.position.x = 10
|
118
|
+
window.position.y = 20
|
119
|
+
window
|
120
|
+
end
|
121
|
+
|
122
|
+
its(:style) { should == 1}
|
123
|
+
its(:'position.x'){ should == 10}
|
124
|
+
its(:'position.y'){ should == 20}
|
125
|
+
end
|
126
|
+
|
127
|
+
describe 'Anonymous Union Member -> U' do
|
128
|
+
subject do
|
129
|
+
class U < CStruct
|
130
|
+
union:value do
|
131
|
+
int32:x
|
132
|
+
int32:y
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
u = U.new
|
137
|
+
u.value.x = 10
|
138
|
+
u
|
139
|
+
end
|
140
|
+
its(:'value.x'){ should == 10}
|
141
|
+
end
|
142
|
+
|
143
|
+
describe 'Char Buffer Member -> Addition' do
|
144
|
+
subject do
|
145
|
+
class Addition < CStruct
|
146
|
+
char :description,[32]
|
147
|
+
end
|
148
|
+
|
149
|
+
addition = Addition.new
|
150
|
+
addition.description = 'Hello Ruby!'
|
151
|
+
addition
|
152
|
+
end
|
153
|
+
|
154
|
+
its(:'description.to_cstr') {should == 'Hello Ruby!'}
|
155
|
+
end
|
156
|
+
|
157
|
+
=begin
|
158
|
+
describe 'Binary File IO ' do
|
159
|
+
subject do
|
160
|
+
|
161
|
+
class Point < CStruct
|
162
|
+
int32:x
|
163
|
+
int32:y
|
164
|
+
end
|
165
|
+
|
166
|
+
class PointF < CStruct
|
167
|
+
double:x
|
168
|
+
double:y
|
169
|
+
end
|
170
|
+
|
171
|
+
class Addition < CStruct
|
172
|
+
char :description,[32]
|
173
|
+
end
|
174
|
+
|
175
|
+
class IOData < CStruct
|
176
|
+
Point:point
|
177
|
+
PointF:pointf
|
178
|
+
Addition:addition
|
179
|
+
end
|
180
|
+
|
181
|
+
write_data = IOData.new
|
182
|
+
# write file
|
183
|
+
File.open("point.bin","wb")do |f|
|
184
|
+
write_data.point = Point.new {|st| st.x = 100; st.y =200 }
|
185
|
+
write_data.point_f = PointF.new{|st| st.x = 20.65; st.y =70.86 }
|
186
|
+
|
187
|
+
write_data.addition = Addition.new
|
188
|
+
write_data.addition.description= "Hello Ruby!"
|
189
|
+
|
190
|
+
f.write write_data.data
|
191
|
+
end
|
192
|
+
|
193
|
+
read_data = IOData.new
|
194
|
+
|
195
|
+
#read file
|
196
|
+
File.open("point.bin","rb")do |f|
|
197
|
+
read_data << f.read(IODtata.size)
|
198
|
+
|
199
|
+
puts point.x
|
200
|
+
puts point.y
|
201
|
+
puts point_f.x
|
202
|
+
puts point_f.y
|
203
|
+
puts addition.description.to_cstr
|
204
|
+
end
|
205
|
+
read_data
|
206
|
+
end
|
207
|
+
|
208
|
+
its(:'point.x') {should == 200}
|
209
|
+
end
|
210
|
+
=end
|
211
|
+
describe 'Namespace ' do
|
212
|
+
it 'NS1 NS2' do
|
213
|
+
module NS1 #namespace
|
214
|
+
class A < CStruct
|
215
|
+
uint32:handle
|
216
|
+
end
|
217
|
+
|
218
|
+
module NS2
|
219
|
+
class B < CStruct
|
220
|
+
A:a # directly use A
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
class C < CStruct
|
225
|
+
A :a
|
226
|
+
NS2_B :b # Meaning of the 'NS2_B' is NS2::B
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
class D < CStruct
|
231
|
+
NS1_NS2_B:b # Meaning of the 'NS1_NS2_B' is NS1::NS2::B
|
232
|
+
end
|
233
|
+
|
234
|
+
v = D.new
|
235
|
+
v.b.a.handle = 120
|
236
|
+
v.b.a.handle.should == 120
|
237
|
+
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|