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.
@@ -0,0 +1,119 @@
1
+
2
+ module StructPacking
3
+
4
+ public
5
+
6
+ # internal C-like_structure_declaration
7
+ class Util
8
+
9
+ private
10
+
11
+ def self.parse_ctype_decl(decl)
12
+ decl =~ /^\s*(unsigned|signed)?\s*(ascii|utf8|byte|char|short|(?:u?int)(?:(?:8|16|32|64)_t)?|(?:big|little)?(?:16|32)|(?:big|little)?\s*(?:float|double)?|long(?:\s*long))\s*(?:\[\s*(\d+)\s*\])?\s*$/
13
+
14
+ sign = !("unsigned" == $1)
15
+ template = template_of(sign, $2)
16
+ if $3 != nil and $3 == "1"
17
+ template += $3
18
+ end
19
+ template
20
+ end
21
+
22
+ def self.template_of(sign, type)
23
+ case type
24
+ when "ascii"
25
+ 'a'
26
+ when "utf8"
27
+ 'U'
28
+ when "byte"
29
+ 'C'
30
+ when "char"
31
+ 'c'
32
+ when "int8_t"
33
+ sign ? 'c' : 'C'
34
+ when "short"
35
+ 's'
36
+ when "int16_t"
37
+ sign ? 's' : 'S'
38
+ when "int"
39
+ sign ? 'i' : 'I'
40
+ when "int32_t"
41
+ sign ? 'l' : 'L'
42
+ when "long"
43
+ sign ? 'l' : 'L'
44
+ when /long(\s*long)/
45
+ sign ? 'q' : 'Q'
46
+ when "int64_t"
47
+ sign ? 'q' : 'Q'
48
+ when "uint8_t"
49
+ 'C'
50
+ when "uint16_t"
51
+ 'S'
52
+ when "uint"
53
+ 'I'
54
+ when "uint32_t"
55
+ 'L'
56
+ when "uint64_t"
57
+ 'Q'
58
+ when "big16"
59
+ 'n'
60
+ when "big"
61
+ 'N'
62
+ when "big32"
63
+ 'N'
64
+ when "little16"
65
+ 'v'
66
+ when "little"
67
+ 'V'
68
+ when "little32"
69
+ 'V'
70
+ when "float"
71
+ 'f'
72
+ when /big\s*float/
73
+ 'g'
74
+ when /little\s*float/
75
+ 'e'
76
+ when "double"
77
+ 'd'
78
+ when /big\s*double/
79
+ 'G'
80
+ when /little\s*double/
81
+ 'E'
82
+ end
83
+ end
84
+
85
+ def self.types_to_template(types)
86
+ types.collect {|t| parse_ctype_decl(t)}.join
87
+ end
88
+
89
+ public
90
+ # Parse declaration string into pack template.
91
+ def self.pack_template_from(text)
92
+ internal = internal_format_from(text)
93
+ types_to_template(internal.values)
94
+ end
95
+
96
+ # Parse declaration string into internal format.
97
+ # Internal format is {:name=>"type", ...}
98
+ def self.internal_format_from(text)
99
+ params = {}
100
+ text.split(/[\n;]/).each do |line|
101
+ line.gsub!(/^\s*/,'')
102
+ line.gsub!(/\s*$/,'')
103
+
104
+ idx = line.rindex(' ')
105
+ type = line[0..idx-1]
106
+ name = line[idx+1..line.length]
107
+
108
+ if name =~ /(.*)\[\w*(\d+)\w*\]\w*/
109
+ type += "[#{$2}]"
110
+ name = $1
111
+ end
112
+
113
+ params[name.to_sym] = type
114
+ end
115
+
116
+ params
117
+ end
118
+ end
119
+ end
@@ -1,12 +1,20 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
-
4
- module StructPacking
5
- VERSION = '0.0.1'
6
- end
7
-
8
- require 'struct_packing/base'
9
- require 'struct_packing/util'
10
- require 'struct_packing/packable'
11
- require 'struct_packing/unpackable'
12
-
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+
5
+ # StructPacking package make up with Packable and Unpackable module.
6
+ #
7
+ # Include these module to a class, struct defining method and
8
+ # packing/unpacing methods append to the class and instances.
9
+ #
10
+ # First, call struct defining method with "C-like sturucture declaration",
11
+ # and the class and instances can packing or unpacking by these methods.
12
+ module StructPacking
13
+ # Gem version.
14
+ VERSION = '0.0.1'
15
+ end
16
+
17
+ require 'struct_packing/base'
18
+ require 'struct_packing/util'
19
+ require 'struct_packing/packable'
20
+ require 'struct_packing/unpackable'
data/script/console CHANGED
@@ -1,10 +1,10 @@
1
- #!/usr/bin/env ruby
2
- # File: script/console
3
- irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
-
5
- libs = " -r irb/completion"
6
- # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
- # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
- libs << " -r #{File.dirname(__FILE__) + '/../lib/struct_packing.rb'}"
9
- puts "Loading struct_packing gem"
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/struct_packing.rb'}"
9
+ puts "Loading struct_packing gem"
10
10
  exec "#{irb} #{libs} --simple-prompt"
data/script/destroy CHANGED
@@ -1,14 +1,14 @@
1
- #!/usr/bin/env ruby
2
- APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
-
4
- begin
5
- require 'rubigen'
6
- rescue LoadError
7
- require 'rubygems'
8
- require 'rubigen'
9
- end
10
- require 'rubigen/scripts/destroy'
11
-
12
- ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
- RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
- RubiGen::Scripts::Destroy.new.run(ARGV)
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate CHANGED
@@ -1,14 +1,14 @@
1
- #!/usr/bin/env ruby
2
- APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
-
4
- begin
5
- require 'rubigen'
6
- rescue LoadError
7
- require 'rubygems'
8
- require 'rubigen'
9
- end
10
- require 'rubigen/scripts/generate'
11
-
12
- ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
- RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
- RubiGen::Scripts::Generate.new.run(ARGV)
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,76 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "struct_packing"
8
+ s.version = "0.0.2"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["TOKITA Hiroshi"]
12
+ s.date = "2013-02-16"
13
+ s.description = "* Read/Write ruby object to byte array with C-like struct declarations."
14
+ s.email = ["tokita.hiroshi@gmail.com"]
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "C-like_structure_declaration.rdoc",
22
+ "Gemfile",
23
+ "History.txt",
24
+ "LICENSE.txt",
25
+ "Manifest.txt",
26
+ "PostInstall.txt",
27
+ "README.rdoc",
28
+ "Rakefile",
29
+ "VERSION",
30
+ "lib/struct_packing.rb",
31
+ "lib/struct_packing/base.rb",
32
+ "lib/struct_packing/packable.rb",
33
+ "lib/struct_packing/unpackable.rb",
34
+ "lib/struct_packing/util.rb",
35
+ "script/console",
36
+ "script/console.cmd",
37
+ "script/destroy",
38
+ "script/destroy.cmd",
39
+ "script/generate",
40
+ "script/generate.cmd",
41
+ "struct_packing.gemspec",
42
+ "test/struct_packing/test_base.rb",
43
+ "test/struct_packing/test_packable.rb",
44
+ "test/struct_packing/test_unpackable.rb",
45
+ "test/struct_packing/test_util.rb",
46
+ "test/test_helper.rb",
47
+ "test/test_struct_packing.rb"
48
+ ]
49
+ s.homepage = "http://github.com/TOKITAHiroshi/struct_packing"
50
+ s.licenses = ["MIT"]
51
+ s.require_paths = ["lib"]
52
+ s.rubygems_version = "1.8.25"
53
+ s.summary = "* Read/Write ruby object to byte array with C-like struct declarations."
54
+
55
+ if s.respond_to? :specification_version then
56
+ s.specification_version = 3
57
+
58
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
59
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
60
+ s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
61
+ s.add_development_dependency(%q<bundler>, ["~> 1.2.0"])
62
+ s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
63
+ else
64
+ s.add_dependency(%q<shoulda>, [">= 0"])
65
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
66
+ s.add_dependency(%q<bundler>, ["~> 1.2.0"])
67
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
68
+ end
69
+ else
70
+ s.add_dependency(%q<shoulda>, [">= 0"])
71
+ s.add_dependency(%q<rdoc>, ["~> 3.12"])
72
+ s.add_dependency(%q<bundler>, ["~> 1.2.0"])
73
+ s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
74
+ end
75
+ end
76
+
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ require 'ostruct'
4
+
5
+ class TestBase < Test::Unit::TestCase
6
+
7
+ def setup
8
+ end
9
+
10
+ class ClassIncludeOnly
11
+ include StructPacking::Base
12
+ end
13
+
14
+ def test_null_internal_format
15
+ obj = ClassIncludeOnly.new
16
+ assert_equal({}, obj.internal_format())
17
+ end
18
+
19
+
20
+ class SingleIntStruct
21
+ include StructPacking::Base
22
+ self.byte_format = "int hoge;"
23
+ end
24
+
25
+ def test_single_int_internal_format
26
+ assert_equal("int" , SingleIntStruct.internal_format[:hoge])
27
+ end
28
+
29
+ class MultiFieldStruct
30
+ include StructPacking::Base
31
+ self.byte_format = "int fuga; char piyo"
32
+ end
33
+
34
+ def test_multi_field_internal_format
35
+ assert_equal("int" , MultiFieldStruct.internal_format[:fuga])
36
+ assert_equal("char" , MultiFieldStruct.internal_format[:piyo])
37
+ end
38
+
39
+ =begin
40
+ def test_internal_format_not_modifiable
41
+ assert_equal(4, (SingleIntStruct.internal_format[:hoge])[:size])
42
+ (SingleIntStruct.internal_format[:hoge])[:size] = 8
43
+ assert_equal(8, (SingleIntStruct.internal_format[:hoge])[:size])
44
+ assert_equal({:type=>"int", :start=>0, :size=>4} , SingleIntStruct.internal_format[:hoge])
45
+ end
46
+ =end
47
+
48
+ end
@@ -0,0 +1,89 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ require 'ostruct'
4
+
5
+ class TestPackable < Test::Unit::TestCase
6
+
7
+ TEST_MOD = StructPacking::Packable
8
+
9
+ def setup
10
+ end
11
+
12
+
13
+
14
+ class ClsIntNoAttr
15
+ include TEST_MOD
16
+ self.byte_format = "uint32_t packtestint;"
17
+ end
18
+
19
+ def test_pack_undefined_field_int
20
+ obj = ClsIntNoAttr.new
21
+ assert_equal( [0,0,0,0].pack("C4"), obj.pack() )
22
+ end
23
+
24
+ class ClsInt < ClsIntNoAttr
25
+ attr_accessor :packtestint
26
+ end
27
+
28
+ def test_pack_field_int
29
+ obj = ClsInt.new
30
+ obj.packtestint = 1
31
+ assert_equal( [1,0,0,0].pack("C4"), obj.pack() )
32
+ end
33
+
34
+ class ClsCharNoAttr
35
+ include TEST_MOD
36
+ self.byte_format = "char packtestchar;"
37
+ end
38
+
39
+ def test_pack_undefined_field_char
40
+ obj = ClsCharNoAttr.new
41
+ assert_equal( [0].pack("C"), obj.pack() )
42
+ end
43
+
44
+ class ClsChar < ClsCharNoAttr
45
+ attr_accessor :packtestchar
46
+ end
47
+
48
+ def test_pack_field_char
49
+ obj = ClsChar.new
50
+ obj.packtestchar = 1
51
+ assert_equal( [1].pack("C"), obj.pack() )
52
+ end
53
+
54
+ class ClsMultiField
55
+ include TEST_MOD
56
+ attr_accessor :packtestchar, :packtestint
57
+
58
+ self.byte_format = "char packtestchar; int packtestint"
59
+
60
+ def initialize
61
+ @packtestint = 9999
62
+ @packtestchar = 9999
63
+ end
64
+ end
65
+
66
+ def test_pack_multi_field
67
+ obj = ClsMultiField.new
68
+ obj.packtestint = 1
69
+ obj.packtestchar = 1
70
+ assert_equal( [1, 1, 0, 0, 0].pack("C*"), obj.pack() )
71
+ end
72
+
73
+ class OStructTestClass < OpenStruct
74
+ include TEST_MOD
75
+ self.byte_format = "uint32_t hoge; int fuga; byte piyo[1]"
76
+ end
77
+
78
+ def test_pack_with_ostruct
79
+ sd = OStructTestClass.new
80
+ sd.hoge = 1
81
+ sd.fuga = 2
82
+ sd.piyo = [8]
83
+
84
+ ba = sd.pack()
85
+
86
+ assert_equal([1, 0, 0, 0, 2, 0, 0, 0, 8].pack("C*"), ba)
87
+ end
88
+
89
+ end
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ require 'ostruct'
4
+
5
+ class TestUnpackable < Test::Unit::TestCase
6
+
7
+ TEST_MOD = StructPacking::Unpackable
8
+
9
+ def setup
10
+ end
11
+
12
+
13
+
14
+ class ClsIntNoAttr
15
+ include TEST_MOD
16
+ self.byte_format = "uint32_t packtestint;"
17
+ end
18
+
19
+ def test_unpack_undefined_field_int
20
+ obj = ClsIntNoAttr.from_data( [0,0,0,0].pack("C4") )
21
+ assert_raise(NoMethodError) do
22
+ obj.packtestint
23
+ end
24
+ end
25
+
26
+ class ClsInt < ClsIntNoAttr
27
+ attr_accessor :packtestint
28
+ end
29
+
30
+ def test_unpack_field_int
31
+ obj = ClsInt.from_data( [1,0,0,0].pack("C4") )
32
+ assert_equal(1 , obj.packtestint)
33
+ end
34
+
35
+ class ClsCharNoAttr
36
+ include TEST_MOD
37
+ self.byte_format = "char packtestchar;"
38
+ end
39
+
40
+ def test_unpack_undefined_field_char
41
+ obj = ClsCharNoAttr.from_data( [1].pack("C") )
42
+ assert_raise(NoMethodError) do
43
+ obj.packtestchar
44
+ end
45
+ end
46
+
47
+ class ClsChar < ClsCharNoAttr
48
+ attr_accessor :packtestchar
49
+ end
50
+
51
+ def test_unpack_field_char
52
+ obj = ClsChar.from_data( [1].pack("C") )
53
+ assert_equal(1 , obj.packtestchar)
54
+ end
55
+
56
+ class ClsMultiField
57
+ include TEST_MOD
58
+ attr_accessor :packtestchar, :packtestint
59
+
60
+ self.byte_format = "char packtestchar; int packtestint"
61
+
62
+ def initialize
63
+ @packtestint = 9999
64
+ @packtestchar = 9999
65
+ end
66
+ end
67
+
68
+ def test_unpack_multi_field
69
+ obj = ClsMultiField.from_data( [1, 1, 0, 0, 0].pack("C*") )
70
+ assert_equal(1, obj.packtestint)
71
+ assert_equal(1, obj.packtestchar)
72
+ end
73
+
74
+ class OStructTestClass < OpenStruct
75
+ include TEST_MOD
76
+ self.byte_format = "uint32_t hoge; int fuga; byte piyo[1]"
77
+ end
78
+
79
+ def test_from_data_with_ostruct
80
+ ud = OStructTestClass.from_data [1, 0, 0, 0, 2, 0, 0, 0, 8, 9].pack("C*")
81
+
82
+ assert_equal(1, ud.hoge)
83
+ assert_equal(2, ud.fuga)
84
+ assert_equal([8], ud.piyo)
85
+ end
86
+
87
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/../test_helper.rb'
2
+
3
+ require 'ostruct'
4
+
5
+ class TestUtil < Test::Unit::TestCase
6
+
7
+ def setup
8
+ end
9
+
10
+ def test_types_to_template
11
+ tpl = StructPacking::Util.types_to_template(["int", "char"])
12
+
13
+ assert_equal("ic", tpl)
14
+
15
+ end
16
+
17
+ end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,3 @@
1
- require 'stringio'
2
- require 'test/unit'
3
- require File.dirname(__FILE__) + '/../lib/struct_packing'
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/struct_packing'
@@ -6,41 +6,5 @@ class TestStructPacking < Test::Unit::TestCase
6
6
 
7
7
  def setup
8
8
  end
9
-
10
- def test_truth
11
- assert true
12
- end
13
-
14
- class UserData < OpenStruct
15
- include StructPacking::Unpackable
16
- self.byte_format = {:hoge=>"uint32", :fuga=>"int", :piyo=> "byte[1]"}
17
- end
18
-
19
- class SysData < OpenStruct
20
- include StructPacking::Packable
21
- self.byte_format = "uint32 hoge; int fuga; byte[1] piyo;"#{:hoge=>"uint32", :fuga=>"int", :piyo=> "byte[1]"}
22
- end
23
-
24
- def test_from_data_with_ostruct
25
- ud = UserData.from_data [1, 0, 0, 0, 2, 0, 0, 0, 8, 9].pack("C*")
26
-
27
- assert_equal(1, ud.hoge)
28
- assert_equal(2, ud.fuga)
29
- assert_equal([8], ud.piyo)
30
- end
31
-
32
-
33
-
34
- def test_pack_with
35
- sd = SysData.new
36
- sd.hoge = 1
37
- sd.fuga = 2
38
- sd.piyo = [8]
39
-
40
-
41
- ba = sd.pack()
42
-
43
- assert_equal([1, 0, 0, 0, 2, 0, 0, 0, 8].pack("C*"), ba)
44
- end
45
-
9
+
46
10
  end