cstruct 1.0.0 → 1.0.1
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/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
|
+
|