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