struct_packing 0.0.1 → 0.0.2

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/.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