struct_packing 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
@@ -0,0 +1,117 @@
1
+ = C-language like structure declaration
2
+
3
+ == Overview:
4
+
5
+ StructPacking uses "C like structure declaration" to define
6
+ object packing byte array format.
7
+ It is mostly compatible with struct definition in C language, and
8
+ some extended notation to support byte packing function in Ruby language.
9
+
10
+ This is mainly use to genarate Ruby pack template string from C language's struct
11
+ declaration.
12
+
13
+ == Syntax:
14
+ Syntax is same as C-language variable declaration.
15
+ [sign-modifier] <type> <variable-name> [ [array-length] ];
16
+
17
+
18
+ == Type:
19
+ * Traditional C language's types.
20
+ * char
21
+ * short
22
+ * int
23
+ * long
24
+ * long long
25
+ * float
26
+ * double
27
+
28
+
29
+ * C99 types.
30
+ * int8_t
31
+ * int16_t
32
+ * int32_t
33
+ * int64_t
34
+ * uint8_t
35
+ * uint16_t
36
+ * uint32_t
37
+ * uint64_t
38
+
39
+ * Extend keyword for Ruby pack string support.
40
+ * ascii
41
+ * utf8
42
+ * big
43
+ * big16
44
+ * big32
45
+ * little
46
+ * little16
47
+ * little32
48
+ * big float
49
+ * little float
50
+ * big double
51
+ * little double
52
+
53
+ == Variable-name:
54
+ Variable-name is identifier of this variable.
55
+ This is must unique in this struct.
56
+
57
+ In StructPacking package, variable-name is used to make relation object
58
+ with struct definition.
59
+ Packing function is get value from object's attr-getter which is same name as
60
+ variable-name, and pack the value toC-like_structure_declaration.rdoc
61
+
62
+ == Array-length
63
+ If "[]" is placed after variable-name, this variable define as array.
64
+
65
+ == Sign-modifier:
66
+ * signed
67
+ * unsigned
68
+ are sign-modifier.
69
+
70
+ == Bit-field
71
+ * TODO
72
+
73
+
74
+ == Ruby pack template mapping:
75
+
76
+ * Signed (or not assinged)
77
+
78
+ *char*:: "c"
79
+ *int8_t*:: "c"
80
+ *short*:: "s"
81
+ *int16_t*:: "s"
82
+ *int*:: "i"
83
+ *int32_t*:: "l"
84
+ *long*:: "l"
85
+ *long* *long*:: "q"
86
+ *int64_t*:: "q"
87
+ *float*:: "f"
88
+ *double*:: "d"
89
+
90
+ * Unsigned
91
+
92
+ *unsigned* *char*:: "C"
93
+ *uint8_t*:: "C"
94
+ *unsigned* *short*:: "S"
95
+ *uint16_t*:: "S"
96
+ *unsigned* *int*:: "I"
97
+ *unsigned* *long*:: "L"
98
+ *uint32_t*:: "L"
99
+ *unsigned* *long* *long*:: "Q"
100
+ *uint64_t*:: "Q"
101
+
102
+ * Extend types
103
+
104
+ *ascii*:: "a"
105
+ *utf8*:: "U"
106
+ *big*:: "N"
107
+ *big16*:: "n"
108
+ *big32*:: "N"
109
+ *little*:: "V"
110
+ *little16*:: "v"
111
+ *little32*:: "V"
112
+ *big* *float*:: "g"
113
+ *little* *float*:: "e"
114
+ *big* *double*:: "G"
115
+ *little* *double*:: "E"
116
+
117
+
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ group :development do
9
+ gem "shoulda", ">= 0"
10
+ gem "rdoc", "~> 3.12"
11
+ gem "bundler", "~> 1.2.0"
12
+ gem "jeweler", "~> 1.8.4"
13
+ end
data/History.txt CHANGED
@@ -1,4 +1,4 @@
1
- === 0.0.1 2013-02-11
2
-
3
- * 1 major enhancement:
4
- * Initial release
1
+ === 0.0.1 2013-02-11
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 TOKITA Hiroshi
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest.txt CHANGED
@@ -1,14 +1,13 @@
1
- History.txt
2
- Manifest.txt
3
- PostInstall.txt
4
- README.rdoc
5
- Rakefile
6
- lib/struct_packing.rb
7
- script/console
8
- script/console.cmd
9
- script/destroy
10
- script/destroy.cmd
11
- script/generate
12
- script/generate.cmd
13
- test/test_helper.rb
14
- test/test_struct_packing.rb
1
+ History.txt
2
+ C-like_structure_declaration.rdoc
3
+ README.rdoc
4
+ Rakefile
5
+ lib/struct_packing.rb
6
+ script/console
7
+ script/console.cmd
8
+ script/destroy
9
+ script/destroy.cmd
10
+ script/generate
11
+ script/generate.cmd
12
+ test/test_helper.rb
13
+ test/test_struct_packing.rb
data/PostInstall.txt CHANGED
@@ -1,7 +1,7 @@
1
-
2
- For more information on struct_packing, see http://struct_packing.rubyforge.org
3
-
4
- NOTE: Change this information in PostInstall.txt
5
- You can also delete it if you don't want it.
6
-
7
-
1
+
2
+ For more information on struct_packing, see http://struct_packing.rubyforge.org
3
+
4
+ NOTE: Change this information in PostInstall.txt
5
+ You can also delete it if you don't want it.
6
+
7
+
data/README.rdoc CHANGED
@@ -1,59 +1,63 @@
1
- = struct_packing
2
-
3
- * http://github.com/TOKITAHiroshi/struct_packing
4
-
5
- == DESCRIPTION:
6
-
7
- * Read/Write ruby object to byte array with C-like struct declarations.
8
-
9
- == FEATURES/PROBLEMS:
10
-
11
- * Simple read/write ruby-object to formatted byte array.
12
-
13
- == SYNOPSIS:
14
-
15
- # Packing object to byte array.
16
-
17
- class MyStruct < OpenStruct
18
- include StructPacking::Packable
19
- self.byte_format = "uint32 hoge; int fuga; byte[1] piyo;"
20
- end
21
-
22
- obj = MyStruct.new
23
- sd.hoge = 1
24
- sd.fuga = 2
25
- sd.piyo = [8]
26
- packed_struct = obj.pack # => "\x01\x00\x00\x00\x02\x00\x00\x00\b"
27
-
28
- == REQUIREMENTS:
29
-
30
- * none
31
-
32
- == INSTALL:
33
-
34
- * sudo gem install struct_packing
35
-
36
- == LICENSE:
37
-
38
- (The MIT License)
39
-
40
- Copyright (c) 2013 TOKITA Hiroshi
41
-
42
- Permission is hereby granted, free of charge, to any person obtaining
43
- a copy of this software and associated documentation files (the
44
- 'Software'), to deal in the Software without restriction, including
45
- without limitation the rights to use, copy, modify, merge, publish,
46
- distribute, sublicense, and/or sell copies of the Software, and to
47
- permit persons to whom the Software is furnished to do so, subject to
48
- the following conditions:
49
-
50
- The above copyright notice and this permission notice shall be
51
- included in all copies or substantial portions of the Software.
52
-
53
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
54
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
55
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
56
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
57
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
58
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
59
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ = struct_packing
2
+
3
+ * http://github.com/TOKITAHiroshi/struct_packing
4
+
5
+ == DESCRIPTION:
6
+
7
+ * Read/Write ruby object to byte array with C-like struct declarations.
8
+
9
+ == INSTALL:
10
+
11
+ * sudo gem install struct_packing
12
+
13
+
14
+ == SYNOPSIS:
15
+ === Packing object to byte array.
16
+ class PackableOStruct < OpenStruct
17
+ include StructPacking::Packable
18
+ self.byte_format = "int foo; char bar; byte[1] baz;"
19
+ end
20
+
21
+ obj = PackableOStruct.new
22
+ obj.foo = 1
23
+ obj.bar = 2
24
+ obj.baz = [8]
25
+ packed_bytes = obj.pack # => "\x01\x00\x00\x00\x02\b"
26
+
27
+
28
+ === Read object attributes from byte array.
29
+ class UnpackableOStruct < OpenStruct
30
+ include StructPacking::Unpackable
31
+ self.byte_format = "char foo; byte[1] bar; int baz;"
32
+ end
33
+
34
+ obj = UnpackableOStruct.from_data [1, 2, 3, 0, 0, 0].pack("C*")
35
+ obj.foo # => 1
36
+ obj.bar # => [2]
37
+ obj.baz # => 3
38
+
39
+
40
+ == LICENSE:
41
+
42
+ (The MIT License)
43
+
44
+ Copyright (c) 2013 TOKITA Hiroshi
45
+
46
+ Permission is hereby granted, free of charge, to any person obtaining
47
+ a copy of this software and associated documentation files (the
48
+ 'Software'), to deal in the Software without restriction, including
49
+ without limitation the rights to use, copy, modify, merge, publish,
50
+ distribute, sublicense, and/or sell copies of the Software, and to
51
+ permit persons to whom the Software is furnished to do so, subject to
52
+ the following conditions:
53
+
54
+ The above copyright notice and this permission notice shall be
55
+ included in all copies or substantial portions of the Software.
56
+
57
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
58
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
59
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
60
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
61
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
62
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
63
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,26 +1,53 @@
1
- require 'rubygems'
2
- gem 'hoe', '>= 2.1.0'
3
- require 'hoe'
4
- require 'fileutils'
5
- require './lib/struct_packing'
1
+ # encoding: utf-8
6
2
 
7
- Hoe.plugin :newgem
8
- # Hoe.plugin :website
9
- # Hoe.plugin :cucumberfeatures
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
10
13
 
11
- # Generate all the Rake tasks
12
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
13
- $hoe = Hoe.spec 'struct_packing' do
14
- self.developer 'TOKITA Hiroshi', 'tokita.hiroshi@gmail.com'
15
- self.post_install_message = 'PostInstall.txt' # TODO remove if post-install message not required
16
- self.rubyforge_name = self.name # TODO this is default value
17
- # self.extra_deps = [['activesupport','>= 2.0.2']]
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "struct_packing"
18
+ gem.homepage = "http://github.com/TOKITAHiroshi/struct_packing"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{* Read/Write ruby object to byte array with C-like struct declarations.}
21
+ gem.description = %Q{* Read/Write ruby object to byte array with C-like struct declarations.}
22
+ gem.email = ["tokita.hiroshi@gmail.com"]
23
+ gem.authors = ["TOKITA Hiroshi"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
18
27
 
28
+ require 'rake/testtask'
29
+ Rake::TestTask.new(:test) do |test|
30
+ test.libs << 'lib' << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+ =begin
35
+ require 'rcov/rcovtask'
36
+ Rcov::RcovTask.new do |test|
37
+ test.libs << 'test'
38
+ test.pattern = 'test/**/test_*.rb'
39
+ test.verbose = true
40
+ test.rcov_opts << '--exclude "gems/*"'
19
41
  end
42
+ =end
43
+ task :default => :test
20
44
 
21
- require 'newgem/tasks'
22
- Dir['tasks/**/*.rake'].each { |t| load t }
45
+ require 'rdoc/task'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
23
48
 
24
- # TODO - want other tests/tasks run by default? Add them to the list
25
- # remove_task :default
26
- # task :default => [:spec, :features]
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "struct_packing #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
@@ -0,0 +1,91 @@
1
+
2
+ module StructPacking
3
+
4
+ private
5
+
6
+ # Common defines for Packable and Unpackable
7
+ module Base
8
+
9
+ private
10
+
11
+ def self.included(base)
12
+ base.extend ClassMethods
13
+ end
14
+
15
+ public
16
+
17
+ # Get structure format string used in packing this object.
18
+ #
19
+ # This method work as just wrapper to same name class-method.
20
+ def internal_format
21
+ self.class.internal_format
22
+ end
23
+
24
+ # Get field name list of this class.
25
+ def field_names
26
+ self.class.field_names
27
+ end
28
+
29
+ # Get field type list of this class.
30
+ def field_types
31
+ self.class.field_types
32
+ end
33
+
34
+ # Get Ruby's pack tenplate string for this class.
35
+ def pack_template
36
+ self.class.pack_template
37
+ end
38
+
39
+ # Common extending methods for Packable and Unpackable.
40
+ #
41
+ # Automatically extend on including StructPacking::Base module.
42
+ module ClassMethods
43
+
44
+ private
45
+
46
+ # TODO temporary initializer for @@struct_internal_format
47
+ def check_vardef
48
+ if not self.class_variable_defined?(:@@struct_internal_format)
49
+ class_eval("@@struct_internal_format = ''")
50
+ end
51
+ end
52
+
53
+ public
54
+
55
+ # Get internal structure format used to pack a object of this class.
56
+ def internal_format
57
+ check_vardef # TODO Find more good way!
58
+
59
+ Util.internal_format_from( self.class_variable_get(:@@struct_internal_format) )
60
+ end
61
+
62
+ # Set structure format for this class by string.
63
+ def byte_format=(text)
64
+ check_vardef # TODO Find more good way!
65
+
66
+ self.class_variable_set(:@@struct_internal_format, text)
67
+
68
+ true
69
+ end
70
+
71
+ # Get field name list of this class.
72
+ def field_names
73
+ internal_format.keys
74
+ end
75
+
76
+ # Get field type list of this class.
77
+ def field_types
78
+ internal_format.values
79
+ end
80
+
81
+ # Get Ruby's pack tenplate string for this class.
82
+ def pack_template
83
+ check_vardef # TODO Find more good way!
84
+
85
+ Util.pack_template_from( self.class_variable_get(:@@struct_internal_format) )
86
+ end
87
+
88
+ end
89
+ end
90
+
91
+ end
@@ -0,0 +1,49 @@
1
+
2
+ module StructPacking
3
+
4
+ # Packable module provides object-packing function.
5
+ #
6
+ # A class include this module, and call struct defining method,
7
+ # pack method returns defined byte-array-form of that class's instance.
8
+ #
9
+ # == SYNOPSIS:
10
+ # class PackableOStruct < OpenStruct
11
+ # include StructPacking::Packable
12
+ # self.byte_format = "int foo; char bar; byte[1] baz;"
13
+ # end
14
+ #
15
+ # obj = PackableOStruct.new
16
+ # obj.foo = 1
17
+ # obj.bar = 2
18
+ # obj.baz = [8]
19
+ # packed_bytes = obj.pack # => "\x01\x00\x00\x00\x02\b"
20
+ module Packable
21
+ private
22
+
23
+ include Base
24
+
25
+ def self.included(base)
26
+ base.send("include", Base)
27
+ end
28
+
29
+ public
30
+
31
+ # Pack this object to byte array.
32
+ #
33
+ # If attribute defined in byte_format,
34
+ # but object has no attr_getter, treat as the attribute is zero.
35
+ def pack()
36
+ values = field_names.collect do |n|
37
+ begin
38
+ instance_eval { send(n) }
39
+ rescue NoMethodError
40
+ 0
41
+ end
42
+ end
43
+ values.flatten!
44
+
45
+ values.pack( pack_template )
46
+ end
47
+
48
+ end
49
+ end
@@ -0,0 +1,79 @@
1
+ module StructPacking
2
+
3
+ # Unpackable module provides value assign function from packed byte array.
4
+ #
5
+ # A class include this module, and call struct defininesg method,
6
+ # A instance's unpack method assign variables from packed object.
7
+ # This module also provide read_struct_data class method
8
+ # which construct object and assign values from packed object.
9
+ module Unpackable
10
+ include StructPacking::Base
11
+
12
+ private
13
+
14
+ def self.included(base)
15
+ base.send("include", Base)
16
+ base.extend ClassMethods
17
+ end
18
+
19
+ # Extending methods for Unpackable class.
20
+ #
21
+ # Automatically extend on including StructPacking::Unpackable module.
22
+ module ClassMethods
23
+
24
+ # Construct object byte array.
25
+ #
26
+ # This method is simply do object construct and values assignment.
27
+ # If attribute defined in byte_format,
28
+ # but object has no attr_setter, do nothing.
29
+ #
30
+ # TODO: Including class must have default constructor.
31
+ #
32
+ # * _bytes_ packed structure. (see Packable.pack)
33
+ def unpack(bytes)
34
+ obj = self.new
35
+ set_values_from_byte_to_object(bytes, obj)
36
+ end
37
+
38
+ alias :from_data :unpack
39
+
40
+ private
41
+
42
+ def set_values_from_byte_to_object(bytes, obj)
43
+
44
+ values = bytes.unpack( pack_template )
45
+
46
+ field_names.zip(gather_array_field(values) ).each do |name,value|
47
+ begin
48
+ obj.instance_eval {
49
+ send("#{name}=", value)
50
+ }
51
+ rescue NoMethodError
52
+ end
53
+ end
54
+ obj
55
+ end
56
+
57
+ def gather_array_field(values)
58
+ field_types.collect do |name|
59
+ if name =~ /.*\[\w*(\d+)\w*\]\w*/
60
+ [0..$1.to_i].to_a.collect { values.shift }
61
+ else
62
+ values.shift
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ public
69
+
70
+ # Set attributes from packed struct byte array.
71
+ #
72
+ # If attribute defined in byte_format,
73
+ # but object has no attr_setter, do nothing.
74
+ def read_struct_data(bytes)
75
+ self.class.set_values_from_byte_to_object(bytes, self)
76
+ end
77
+
78
+ end
79
+ end