gogyou 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,106 +1,149 @@
1
1
 
2
2
  require "rake/clean"
3
3
 
4
- DOC = FileList["{README,LICENSE,CHANGELOG,Changelog}{,.ja}{,.txt,.rd,.rdoc,.md,.markdown}"] +
5
- FileList["ext/**/{README,LICENSE,CHANGELOG,Changelog}{,.ja}{,.txt,.rd,.rdoc,.md,.markdown}"]
4
+ DOC = FileList["{README,LICENSE,CHANGELOG,Changelog,HISTORY}{,.ja}{,.txt,.rd,.rdoc,.md,.markdown}"] +
5
+ FileList["{contrib,ext}/**/{README,LICENSE,CHANGELOG,Changelog,HISTORY}{,.ja}{,.txt,.rd,.rdoc,.md,.markdown}"] +
6
+ FileList["ext/**/*.{c,C,cc,cxx,cpp,h,H,hh}"]
6
7
  #EXT = FileList["ext/**/*.{h,hh,c,cc,cpp,cxx}"] +
7
8
  # FileList["ext/externals/**/*"]
8
9
  EXT = FileList["ext/**/*"]
9
10
  BIN = FileList["bin/*"]
10
11
  LIB = FileList["lib/**/*.rb"]
11
12
  SPEC = FileList["spec/**/*"]
13
+ TEST = FileList["test/**/*"]
12
14
  EXAMPLE = FileList["examples/**/*"]
13
- RAKEFILE = [File.basename(__FILE__), "gemstub.rb"]
15
+ GEMSTUB_SRC = "gemstub.rb"
16
+ RAKEFILE = [File.basename(__FILE__), GEMSTUB_SRC]
14
17
  EXTRA = []
15
18
 
16
- load "gemstub.rb"
19
+ load GEMSTUB_SRC
17
20
 
18
21
  EXTCONF = FileList["ext/extconf.rb"]
19
22
  EXTCONF.reject! { |n| !File.file?(n) }
20
23
  GEMSTUB.extensions += EXTCONF
21
24
  GEMSTUB.executables += FileList["bin/*"].map { |n| File.basename n }
25
+ GEMSTUB.executables.sort!
22
26
 
23
27
  GEMFILE = "#{GEMSTUB.name}-#{GEMSTUB.version}.gem"
24
28
  GEMSPEC = "#{GEMSTUB.name}.gemspec"
25
29
 
26
- GEMSTUB.files += DOC + EXT + EXTCONF + BIN + LIB + SPEC + EXAMPLE + RAKEFILE + EXTRA
30
+ GEMSTUB.files += DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + EXTRA
31
+ GEMSTUB.files.sort!
27
32
  GEMSTUB.rdoc_options ||= %w(--charset UTF-8)
28
33
  GEMSTUB.extra_rdoc_files += DOC + LIB + EXT.reject { |n| n.include?("/externals/") || !%w(.h .hh .c .cc .cpp .cxx).include?(File.extname(n)) }
34
+ GEMSTUB.extra_rdoc_files.sort!
29
35
 
30
36
  CLEAN << GEMSPEC
31
37
  CLOBBER << GEMFILE
32
38
 
33
39
  task :default => :all
34
40
 
35
- task :all => GEMFILE
36
-
37
- task :rdoc => DOC + EXT + LIB do
38
- sh *(%w(rdoc) + GEMSTUB.rdoc_options + DOC + EXT + LIB)
39
- end
40
41
 
41
- file GEMFILE => DOC + EXT + EXTCONF + BIN + LIB + SPEC + EXAMPLE + RAKEFILE + [GEMSPEC] do
42
- sh "gem build #{GEMSPEC}"
43
- end
44
-
45
- file GEMSPEC => RAKEFILE do
46
- File.write(GEMSPEC, GEMSTUB.to_ruby, mode: "wb")
47
- end
42
+ unless EXTCONF.empty?
43
+ RUBYSET ||= (ENV["RUBYSET"] || "").split(",")
44
+
45
+ if RUBYSET.nil? || RUBYSET.empty?
46
+ $stderr.puts <<-EOS
47
+ #{__FILE__}:
48
+ |
49
+ | If you want binary gem package, launch rake with ``RUBYSET`` enviroment
50
+ | variable for set ruby interpreters by comma separated.
51
+ |
52
+ | e.g.) $ rake RUBYSET=ruby
53
+ | or) $ rake RUBYSET=ruby20,ruby21,ruby22
54
+ |
55
+ EOS
56
+ else
57
+ platforms = RUBYSET.map { |ruby| `#{ruby} --disable gems -rrbconfig -e "puts RbConfig::CONFIG['arch']"`.chomp }
58
+ platforms1 = platforms.uniq
59
+ unless platforms1.size == 1 && !platforms1[0].empty?
60
+ raise "different platforms (#{Hash[*RUBYSET.zip(platforms).flatten].inspect})"
61
+ end
62
+ PLATFORM = platforms1[0]
48
63
 
64
+ RUBY_VERSIONS = RUBYSET.map do |ruby|
65
+ ver = `#{ruby} --disable gem -rrbconfig -e "puts RbConfig::CONFIG['ruby_version']"`.slice(/\d+\.\d+/)
66
+ raise "failed ruby checking - ``#{ruby}''" unless $?.success?
67
+ [ver, ruby]
68
+ end
69
+ SOFILES_SET = RUBY_VERSIONS.map { |(ver, ruby)| ["lib/#{ver}/#{GEMSTUB.name}.so", ruby] }
70
+ SOFILES = SOFILES_SET.map { |(lib, ruby)| lib }
49
71
 
50
- RUBYSET ||= nil
72
+ GEMSTUB_NATIVE = GEMSTUB.dup
73
+ GEMSTUB_NATIVE.files += SOFILES
74
+ GEMSTUB_NATIVE.platform = Gem::Platform.new(PLATFORM).to_s
75
+ GEMSTUB_NATIVE.extensions.clear
76
+ GEMFILE_NATIVE = "#{GEMSTUB_NATIVE.name}-#{GEMSTUB_NATIVE.version}-#{GEMSTUB_NATIVE.platform}.gem"
77
+ GEMSPEC_NATIVE = "#{GEMSTUB_NATIVE.name}-#{GEMSTUB_NATIVE.platform}.gemspec"
51
78
 
52
- if RUBYSET && !RUBYSET.empty? && !EXTCONF.empty?
53
- RUBY_VERSIONS = RUBYSET.map do |ruby|
54
- ver = `#{ruby} --disable gem -rrbconfig -e "puts RbConfig::CONFIG['ruby_version']"`.chomp
55
- raise "failed ruby checking - ``#{ruby}''" unless $?.success?
56
- [ver, ruby]
57
- end
58
- SOFILES_SET = RUBY_VERSIONS.map { |(ver, ruby)| ["lib/#{ver}/#{GEMSTUB.name}.so", ruby] }
59
- SOFILES = SOFILES_SET.map { |(lib, ruby)| lib }
60
- platforms = RUBYSET.map { |ruby| `#{ruby} -rubygems -e "puts Gem::Platform.local.to_s"`.chomp }
61
- platforms.uniq!
62
- platforms.compact!
63
- unless platforms.size == 1
64
- raise "wrong platforms (#{RUBYSET.inspect} => #{platforms.inspect})"
65
- end
79
+ task :all => ["native-gem", GEMFILE]
66
80
 
67
- GEMSTUB_NATIVE = GEMSTUB.dup
68
- GEMSTUB_NATIVE.files += SOFILES
69
- GEMSTUB_NATIVE.platform = platforms[0]
70
- GEMFILE_NATIVE = "#{GEMSTUB_NATIVE.name}-#{GEMSTUB_NATIVE.version}-#{GEMSTUB_NATIVE.platform}.gem"
71
- GEMSPEC_NATIVE = "#{GEMSTUB_NATIVE.name}-#{GEMSTUB_NATIVE.platform}.gemspec"
81
+ desc "build binary gem package"
82
+ task "native-gem" => GEMFILE_NATIVE
72
83
 
73
- task :all => [GEMFILE, :native]
84
+ desc "generate binary gemspec"
85
+ task "native-gemspec" => GEMSPEC_NATIVE
74
86
 
75
- task :native => GEMFILE_NATIVE
87
+ file GEMFILE_NATIVE => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + SOFILES + RAKEFILE + [GEMSPEC_NATIVE] do
88
+ sh "gem build #{GEMSPEC_NATIVE}"
89
+ end
76
90
 
77
- file GEMFILE_NATIVE => DOC + EXT + [EXTCONF] + BIN + LIB + SPEC + EXAMPLE + SOFILES + RAKEFILE + [GEMSPEC_NATIVE] do
78
- sh "gem build #{GEMSPEC_NATIVE}"
79
- end
91
+ file GEMSPEC_NATIVE => RAKEFILE do
92
+ File.write(GEMSPEC_NATIVE, GEMSTUB_NATIVE.to_ruby, mode: "wb")
93
+ end
80
94
 
81
- file GEMSPEC_NATIVE => __FILE__ do
82
- File.write(GEMSPEC_NATIVE, GEMSTUB_NATIVE.to_ruby, mode: "wb")
83
- end
95
+ desc "build c-extension libraries"
96
+ task "sofiles" => SOFILES
84
97
 
85
- SOFILES_SET.each do |(soname, ruby)|
86
- sodir = File.dirname(soname)
87
- makefile = File.join(sodir, "Makefile")
98
+ SOFILES_SET.each do |(soname, ruby)|
99
+ sodir = File.dirname(soname)
100
+ makefile = File.join(sodir, "Makefile")
88
101
 
89
- CLEAN << GEMSPEC_NATIVE << sodir
90
- CLOBBER << GEMFILE_NATIVE
102
+ CLEAN << GEMSPEC_NATIVE << sodir
103
+ CLOBBER << GEMFILE_NATIVE
91
104
 
92
- directory sodir
105
+ directory sodir
93
106
 
94
- file soname => [makefile] + EXT do
95
- cd sodir do
96
- sh "make"
107
+ desc "generate Makefile for binary extension library"
108
+ file makefile => [sodir] + EXTCONF do
109
+ cd sodir do
110
+ sh "#{ruby} ../../#{EXTCONF[0]} \"--ruby=#{ruby}\""
111
+ end
97
112
  end
98
- end
99
113
 
100
- file makefile => [sodir] + [EXTCONF] do
101
- cd sodir do
102
- sh "#{ruby} ../../#{EXTCONF} \"--ruby=#{ruby}\""
114
+ desc "build binary extension library"
115
+ file soname => [makefile] + EXT do
116
+ cd sodir do
117
+ sh "make"
118
+ end
103
119
  end
104
120
  end
105
121
  end
106
122
  end
123
+
124
+
125
+ task :all => GEMFILE
126
+
127
+ desc "generate local rdoc"
128
+ task :rdoc => DOC + LIB do
129
+ sh *(%w(rdoc) + GEMSTUB.rdoc_options + DOC + LIB)
130
+ end
131
+
132
+ desc "launch rspec"
133
+ task rspec: :all do
134
+ sh "rspec"
135
+ end
136
+
137
+ desc "build gem package"
138
+ task gem: GEMFILE
139
+
140
+ desc "generate gemspec"
141
+ task gemspec: GEMSPEC
142
+
143
+ file GEMFILE => DOC + EXT + EXTCONF + BIN + LIB + SPEC + TEST + EXAMPLE + RAKEFILE + [GEMSPEC] do
144
+ sh "gem build #{GEMSPEC}"
145
+ end
146
+
147
+ file GEMSPEC => RAKEFILE do
148
+ File.write(GEMSPEC, GEMSTUB.to_ruby, mode: "wb")
149
+ end
data/gemstub.rb CHANGED
@@ -1,27 +1,24 @@
1
1
 
2
- # "lib/gogyou/primitives.rb" がない場合は、読み込みを遅らせる。Gogyou::VERSION の参照も後回し。
3
- hasprims = File.file?(File.join(File.dirname(__FILE__), "lib", "gogyou", "primitives.rb"))
4
- require_relative "lib/gogyou" if hasprims
2
+ require_relative "lib/gogyou/version"
5
3
 
6
4
  GEMSTUB = Gem::Specification.new do |s|
7
5
  s.name = "gogyou"
8
- s.version = Gogyou::VERSION if hasprims
6
+ s.version = Gogyou::VERSION
9
7
  s.summary = "binary data operation library with the C liked struct and union"
10
8
  s.description = <<EOS
11
- The gogyou is a library that provides auxiliary features of binary data operation for ruby.
9
+ The gogyou is a library written at pure ruby that provides auxiliary features of binary data operation for ruby.
12
10
 
13
11
  The C-liked struct, union and multidimensional array definition are posible in ruby syntax.
14
12
 
15
- * Usable nested struct.
16
- * Usable nested union.
17
- * Usable multidimensional array.
18
- * Usable user definition types.
13
+ * Available nested struct and union with anonymous field.
14
+ * Available multidimensional array.
15
+ * Available const field.
16
+ * Available packed field.
17
+ * Available user definition types.
19
18
  EOS
20
19
  s.license = "2-clause BSD License"
21
20
  s.author = "dearblue"
22
21
  s.email = "dearblue@users.sourceforge.jp"
23
- #s.author = "**PRIVATE**"
24
- #s.email = "**PRIVATE**"
25
22
  s.homepage = "http://sourceforge.jp/projects/rutsubo/"
26
23
 
27
24
  s.required_ruby_version = ">= 2.0"
@@ -29,12 +26,12 @@ EOS
29
26
  s.add_development_dependency "rake", "~> 10.0"
30
27
  end
31
28
 
32
- LIB << "lib/gogyou/primitives.rb"
33
- EXTRA << "mkprims.rb"
34
- CLEAN << "lib/gogyou/primitives.rb"
29
+ primitives = "lib/gogyou/primitives.rb"
30
+ mkprims = "mkprims.rb"
31
+ LIB << primitives
32
+ CLEAN << primitives
33
+ EXTRA << mkprims
35
34
 
36
- file "lib/gogyou/primitives.rb" => "mkprims.rb" do
37
- sh "ruby mkprims.rb"
38
- require_relative "lib/gogyou"
39
- GEMSTUB.version = Gogyou::VERSION
35
+ file primitives => mkprims do
36
+ sh "ruby #{mkprims}"
40
37
  end
@@ -24,47 +24,42 @@
24
24
  #
25
25
  # 原始的な型情報は Gogyou::Primitives で定義してあり、struct や union メソッド内で利用できる型を次の表に示します:
26
26
  #
27
- # 符号あり 符号なし
28
- # ---- ----
29
- # 8ビット整数型 char uchar
30
- # unsigned_char
31
- # 16ビット整数型 short ushort
32
- # unsigned_short
33
- # 32ビット整数型 int uint
34
- # unsigned_int
35
- # 環境依存32/64ビット整数型 long ulong
36
- # unsigned_long
37
- # 64ビット整数型 longlong ulonglong
38
- # long_long unsigned_long_long
39
- # 32ビット浮動少数型 float
40
- # 64ビット浮動少数型 double
41
- # sizeof 表現型 ssize_t size_t
42
- # ポインタ整数型 intptr_t uintptr_t
27
+ # ==== C 標準型
28
+ # 符号あり 符号なし
29
+ # ---- ----
30
+ # char 型 char uchar
31
+ # unsigned_char
32
+ # short 型 short ushort
33
+ # unsigned_short
34
+ # int 型 int uint
35
+ # unsigned_int
36
+ # long 型 long ulong
37
+ # unsigned_long
38
+ # long long 型 longlong ulonglong
39
+ # long_long unsigned_long_long
40
+ # sizeof 型 ssize_t size_t
41
+ # ポインタ整数型 intptr_t uintptr_t
43
42
  #
44
- # *** ビット数環境非依存 ***
43
+ # バイトオーダー環境依存 バイトオーダー反転
44
+ # 符号あり 符号なし 符号あり 符号なし
45
+ # ---- ---- ---- ----
46
+ # 8ビット整数型 int8_t uint8_t N/A N/A
47
+ # 16ビット整数型 int16_t uint16_t int16_swap uint16_swap
48
+ # 32ビット整数型 int32_t uint32_t int32_swap uint32_swap
49
+ # 64ビット整数型 int64_t uint64_t int64_swap uint64_swap
50
+ # 32ビット浮動小数点数型 float N/A float_swap N/A
51
+ # 64ビット浮動小数点数型 double N/A double_swap N/A
45
52
  #
46
- # バイトオーダー環境依存 バイトオーダー反転
47
- # 符号あり 符号なし 符号あり 符号なし
48
- # ---- ---- ---- ----
49
- # 8ビット整数型 int8_t uint8_t // //
50
- # 16ビット整数型 int16_t uint16_t int16_swap uint16_swap
51
- # 24ビット整数型 int24_t uint24_t int24_swap uint24_swap
52
- # 32ビット整数型 int32_t uint32_t int32_swap uint32_swap
53
- # 48ビット整数型 int48_t uint48_t int48_swap uint48_swap
54
- # 64ビット整数型 int64_t uint64_t int64_swap uint64_swap
55
- #
56
- # ビッグエンディアン リトルエンディアン
57
- # 符号あり 符号なし 符号あり 符号なし
58
- # ---- ---- ---- ----
59
- # 16ビット整数型 int16_be uint16_be int16_le uint16_le
60
- # 24ビット整数型 int24_be uint24_be int24_le uint24_le
61
- # 32ビット整数型 int32_be uint32_be int32_le uint32_le
62
- # 48ビット整数型 int48_be uint48_be int48_le uint48_le
63
- # 64ビット整数型 int64_be uint64_be int64_le uint64_le
64
- #
65
- # ビッグエンディアン リトルエンディアン バイトオーダー反転
66
- # 32ビット浮動少数型 float_be float_le float_swap
67
- # 64ビット浮動少数型 double_be double_le double_swap
53
+ # ビッグエンディアン リトルエンディアン
54
+ # 符号あり 符号なし 符号あり 符号なし
55
+ # ---- ---- ---- ----
56
+ # 16ビット整数型 int16_be uint16_be int16_le uint16_le
57
+ # 24ビット整数型 int24_be uint24_be int24_le uint24_le
58
+ # 32ビット整数型 int32_be uint32_be int32_le uint32_le
59
+ # 48ビット整数型 int48_be uint48_be int48_le uint48_le
60
+ # 64ビット整数型 int64_be uint64_be int64_le uint64_le
61
+ # 32ビット浮動小数点数型 float_be N/A float_le N/A
62
+ # 64ビット浮動小数点数型 double_be N/A double_le N/A
68
63
  #
69
64
  #
70
65
  # ==== 利用者定義の型情報
@@ -141,14 +136,67 @@
141
136
  #
142
137
  module Gogyou
143
138
  Gogyou = self
144
- VERSION = Gem::Version.new("0.2.2")
145
139
 
140
+ require_relative "gogyou/version"
146
141
  require_relative "gogyou/typespec"
147
142
  require_relative "gogyou/mixin"
148
143
  require_relative "gogyou/model"
149
144
  require_relative "gogyou/primitives"
150
145
  require_relative "gogyou/accessor"
151
146
 
147
+ class Model
148
+ TYPEMAP = {}
149
+
150
+ Gogyou::Primitives.constants.each do |n|
151
+ prim = Gogyou::Primitives.const_get(n)
152
+ next unless prim.kind_of?(Gogyou::Primitives::Primitive)
153
+ TYPEMAP[prim.name.to_sym] = prim
154
+ end
155
+
156
+ TYPEMAP[:unsigned_char] = TYPEMAP[:uchar]
157
+ TYPEMAP[:unsigned_short] = TYPEMAP[:ushort]
158
+ TYPEMAP[:unsigned_int] = TYPEMAP[:uint]
159
+ TYPEMAP[:unsigned_long] = TYPEMAP[:ulong]
160
+ TYPEMAP[:unsigned_long_long] = TYPEMAP[:ulonglong]
161
+ TYPEMAP[:long_long] = TYPEMAP[:longlong]
162
+ end
163
+
164
+ class Struct < Accessor::Struct
165
+ def self.struct(&block)
166
+ raise TypeError, "already defined struct" if const_defined?(:MODEL)
167
+
168
+ # TODO: Accessor.define からコピペ。統一するべき。
169
+ model = Model.struct(Model::TYPEMAP.dup, &block)
170
+ const_set(:MODEL, model)
171
+ const_set(:BYTESIZE, model.bytesize)
172
+ const_set(:BYTEALIGN, model.bytealign)
173
+ const_set(:EXTENSIBLE, model.extensible?)
174
+ define_accessors(self, model)
175
+
176
+ nil
177
+ end
178
+
179
+ private_class_method :struct
180
+ end
181
+
182
+ class Union < Accessor::Union
183
+ def self.union(&block)
184
+ raise TypeError, "already defined union" if const_defined?(:MODEL)
185
+
186
+ # TODO: Accessor.define からコピペ。統一するべき。
187
+ model = Model.union(Model::TYPEMAP.dup, &block)
188
+ const_set(:MODEL, model)
189
+ const_set(:BYTESIZE, model.bytesize)
190
+ const_set(:BYTEALIGN, model.bytealign)
191
+ const_set(:EXTENSIBLE, model.extensible?)
192
+ define_accessors(self, model)
193
+
194
+ nil
195
+ end
196
+
197
+ private_class_method :union
198
+ end
199
+
152
200
  #
153
201
  # call-seq:
154
202
  # struct { ... } -> accessor class
@@ -43,15 +43,15 @@ module Gogyou
43
43
  # バイナリデータとして取り出します。
44
44
  #
45
45
  def to_s
46
- buffer__GOGYOU__.byteslice(offset__GOGYOU__, self.class::BYTESIZE)
46
+ @buffer__GOGYOU__.byteslice(@offset__GOGYOU__, self.class::BYTESIZE)
47
47
  end
48
48
 
49
49
  def to_buffer
50
- buffer__GOGYOU__
50
+ @buffer__GOGYOU__
51
51
  end
52
52
 
53
53
  def to_ptr
54
- buffer__GOGYOU__.to_ptr
54
+ @buffer__GOGYOU__.to_ptr
55
55
  end
56
56
 
57
57
  #
@@ -61,8 +61,9 @@ module Gogyou
61
61
  #
62
62
  # 自身のデータ領域を指定バイト数ずらした参照体を返します。
63
63
  #
64
- def slide(bytesize = self.class::BYTESIZE)
65
- self.class.new(buffer__GOGYOU__, offset__GOGYOU__ + bytesize)
64
+ def slide(bytesize = 0)
65
+ offset = @offset__GOGYOU__ + self.class::BYTESIZE + bytesize
66
+ self.class.new(@buffer__GOGYOU__, offset)
66
67
  end
67
68
 
68
69
  #
@@ -72,10 +73,8 @@ module Gogyou
72
73
  #
73
74
  # 詳細は slide を参照して下さい。
74
75
  #
75
- def slide!(bytesize = self.class::BYTESIZE)
76
- offset = offset__GOGYOU__ + bytesize
77
- #return nil if offset < 0
78
- #return nil if offset + buffer__GOGYOU__.bytesize > layout__GOGYOU__.bytesize
76
+ def slide!(bytesize = 0)
77
+ offset = @offset__GOGYOU__ + self.class::BYTESIZE + bytesize
79
78
  @offset__GOGYOU__ = offset
80
79
  self
81
80
  end
@@ -84,25 +83,56 @@ module Gogyou
84
83
  self.class::BYTESIZE
85
84
  end
86
85
 
87
- def size
86
+ def elementsize
88
87
  nil
89
88
  end
90
89
 
90
+ def size
91
+ elementsize
92
+ end
93
+
94
+ #
95
+ # call-seq:
96
+ # validate? -> true or false
97
+ #
98
+ # validation for buffer window.
99
+ #
100
+ def validate?
101
+ if @offset__GOGYOU__ + bytesize > @buffer__GOGYOU__.bytesize
102
+ false
103
+ else
104
+ true
105
+ end
106
+ end
107
+
91
108
  def inspect
92
- "#<%s buffer=%p, offset=%p>" % [self.class,
93
- buffer__GOGYOU__.inspect,
94
- offset__GOGYOU__]
109
+ text = "#<#{self.class}"
110
+ bufsize = @buffer__GOGYOU__.bytesize
111
+ self.class::MODEL.fields.each_with_index do |f, i|
112
+ if @offset__GOGYOU__ + f.offset + f.bytesize > bufsize
113
+ text << "#{i > 0 ? "," : ""} #{f.name}=N/A"
114
+ else
115
+ text << "#{i > 0 ? "," : ""} #{f.name}=#{__send__(f.name).inspect}"
116
+ end
117
+ end
118
+ text << ">"
95
119
  end
96
120
 
97
121
  def pretty_print(q)
98
- q.group(1, "#<#{self.class}") do
99
- q.breakable " "
100
- q.text "buffer="
101
- q.pp buffer__GOGYOU__
102
- q.text ","
103
- q.breakable " "
104
- q.text "offset="
105
- q.pp offset__GOGYOU__
122
+ bufsize = @buffer__GOGYOU__.bytesize
123
+ q.group(2, "#<#{self.class}") do
124
+ self.class::MODEL.fields.each_with_index do |f, i|
125
+ q.text "," if i > 0
126
+ q.breakable " "
127
+ if @offset__GOGYOU__ + f.offset + f.bytesize > bufsize
128
+ q.text "#{f.name}=N/A"
129
+ else
130
+ q.group(1, "#{f.name}=") do
131
+ q.breakable ""
132
+ q.pp __send__(f.name)
133
+ end
134
+ end
135
+ end
106
136
  q.text ">"
107
137
  end
108
138
  end
@@ -150,10 +180,10 @@ module Gogyou
150
180
  namecheck = {}
151
181
  fieldsize = model.fields.size
152
182
  define_method(:size__GOGYOU__, -> { fieldsize })
183
+ alias_method(:elementsize, :size__GOGYOU__)
153
184
  alias_method(:size, :size__GOGYOU__)
154
185
  model.fields.each do |field|
155
186
  name = field.name
156
- #raise NameError, "wrong field name - #{name}" unless name =~ /\A[A-Za-z_][A-Za-z_0-9]*\Z/
157
187
  name = name.intern
158
188
  raise NameError, "already exist field name - #{name}" if namecheck[name]
159
189
  namecheck[name] = true
@@ -167,7 +197,7 @@ module Gogyou
167
197
  end
168
198
 
169
199
  define_method(field.name, -> {
170
- v = type.aref(buffer__GOGYOU__, offset__GOGYOU__ + field.offset)
200
+ v = type.aref(@buffer__GOGYOU__, @offset__GOGYOU__ + field.offset)
171
201
  v.infect_from(self, buffer) unless v.frozen?
172
202
  v.freeze if frozen? || buffer.frozen? || field.const?
173
203
  v
@@ -176,7 +206,7 @@ module Gogyou
176
206
  define_method("#{field.name}=", ->(value) {
177
207
  raise TypeError, "immutable object (#<%s:0x%08X>.%s)" % [self.class, __id__, field.name], caller(2) if frozen?
178
208
  raise TypeError, "immutable field (#<%s:0x%08X>.%s)" % [self.class, __id__, field.name], caller(2) if field.const?
179
- type.aset(buffer__GOGYOU__, offset__GOGYOU__ + field.offset, value)
209
+ type.aset(@buffer__GOGYOU__, @offset__GOGYOU__ + field.offset, value)
180
210
  })
181
211
  end
182
212
  end
@@ -272,27 +302,29 @@ module Gogyou
272
302
  if model.bytesize == 0
273
303
  define_method(:check_index, ->(index) {
274
304
  index = index.to_i
275
- unless index >= 0 && index < self.size
276
- raise IndexError, "out of element size (index #{index} for 0 ... #{self.size})", caller(2)
305
+ unless index >= 0 && index < self.elementsize
306
+ raise IndexError, "out of element size (index #{index} for 0 ... #{self.elementsize})", caller(2)
277
307
  end
278
308
  index
279
309
  })
280
310
 
281
311
  define_method(:<<, ->(value) {
282
312
  raise TypeError, "immutable object (#<%s:0x%08X>)" % [self.class, __id__], caller(2) if frozen?
283
- voff = (buffer__GOGYOU__.bytesize - offset__GOGYOU__).align_floor(type.bytesize)
284
- expandsize = offset__GOGYOU__ + voff + type.bytesize
285
- buffer__GOGYOU__.resize(expandsize)
286
- type.aset(buffer__GOGYOU__, offset__GOGYOU__ + voff, value)
313
+ voff = (@buffer__GOGYOU__.bytesize - @offset__GOGYOU__).align_floor(type.bytesize)
314
+ expandsize = @offset__GOGYOU__ + voff + type.bytesize
315
+ @buffer__GOGYOU__.resize(expandsize)
316
+ type.aset(@buffer__GOGYOU__, @offset__GOGYOU__ + voff, value)
287
317
  self
288
318
  })
289
319
 
290
- define_method(:size, -> {
291
- (buffer__GOGYOU__.bytesize - offset__GOGYOU__).unit_floor(type.bytesize)
320
+ define_method(:elementsize, -> {
321
+ (@buffer__GOGYOU__.bytesize - @offset__GOGYOU__).unit_floor(type.bytesize)
292
322
  })
293
323
 
324
+ alias_method(:size, :elementsize)
325
+
294
326
  define_method(:bytesize, -> {
295
- (buffer__GOGYOU__.bytesize - offset__GOGYOU__).align_floor(type.bytesize)
327
+ (@buffer__GOGYOU__.bytesize - @offset__GOGYOU__).align_floor(type.bytesize)
296
328
  })
297
329
  else
298
330
  eval <<-EOS
@@ -304,10 +336,12 @@ module Gogyou
304
336
  index
305
337
  end
306
338
 
307
- def size
339
+ def elementsize
308
340
  #{elements}
309
341
  end
310
342
 
343
+ alias size elementsize
344
+
311
345
  def bytesize
312
346
  #{type.bytesize * elements}
313
347
  end
@@ -315,19 +349,19 @@ module Gogyou
315
349
  end
316
350
 
317
351
  define_method(:to_s, -> {
318
- buffer__GOGYOU__.byteslice(offset__GOGYOU__, self.bytesize)
352
+ @buffer__GOGYOU__.byteslice(@offset__GOGYOU__, self.bytesize)
319
353
  })
320
354
 
321
355
  define_method(:[], ->(index) {
322
- v = type.aref(buffer__GOGYOU__, offset__GOGYOU__ + check_index(index) * bytesize)
356
+ v = type.aref(@buffer__GOGYOU__, @offset__GOGYOU__ + check_index(index) * bytesize)
323
357
  v.infect_from(self, buffer) unless v.frozen?
324
358
  v.freeze if frozen? || buffer.frozen? || field.const?
325
359
  v
326
360
  })
327
361
 
328
362
  define_method(:[]=, ->(index, value) {
329
- raise TypeError, "immutable object (#<%s:0x%08X>)" % [self.class, __id__, index], caller(2) if frozen? or field.const?
330
- type.aset(buffer__GOGYOU__, offset__GOGYOU__ + check_index(index) * bytesize, value)
363
+ raise TypeError, "immutable object (#<%s:0x%08X>)" % [self.class, __id__, index], caller(2) if frozen? || field.const?
364
+ type.aset(@buffer__GOGYOU__, @offset__GOGYOU__ + check_index(index) * bytesize, value)
331
365
  })
332
366
  end
333
367
  klass
@@ -336,7 +370,7 @@ module Gogyou
336
370
  def self.aset(buffer, offset, value)
337
371
  case value
338
372
  when ::String
339
- raise ArgumentError, "buffer size too small" unless value.bytesize < self::BYTESIZE
373
+ raise ArgumentError, "buffer size too small" unless value.bytesize <= self::BYTESIZE
340
374
  buffer.setbinary(offset, value, 0, self::BYTESIZE)
341
375
  when ::Array
342
376
  raise NotImplementedError
@@ -351,7 +385,28 @@ module Gogyou
351
385
 
352
386
  def bytesize
353
387
  return super unless self.class.extensible?
354
- self.class::BYTESIZE * buffer__GOGYOU__.bytesize.unit_floor(self.class::SUBTYPE)
388
+ self.class::BYTESIZE * @buffer__GOGYOU__.bytesize.unit_floor(self.class::SUBTYPE)
389
+ end
390
+
391
+ def inspect
392
+ text = "["
393
+ elementsize.times.with_index do |n, i|
394
+ text << (i > 0 ? ", " : "") << __send__(:[], n).inspect
395
+ end
396
+ text << "]"
397
+ end
398
+
399
+ def pretty_print(q)
400
+ q.group(1, "[") do
401
+ elementsize.times.with_index do |n, i|
402
+ if i > 0
403
+ q.text ","
404
+ q.breakable " "
405
+ end
406
+ q.pp __send__(:[], n)
407
+ end
408
+ q.text "]"
409
+ end
355
410
  end
356
411
  end
357
412
 
@@ -360,31 +415,31 @@ module Gogyou
360
415
 
361
416
  def initialize(buffer, offset, model)
362
417
  super(buffer, offset)
363
- @model__GOGYOU__ = nil
418
+ @model__GOGYOU__ = model
364
419
  self.class.define_accessors(singleton_class, model)
365
420
  end
366
421
 
367
422
  def inspect
368
- "#<%s buffer=%p, offset=%p, model=%p>" % [self.class,
369
- buffer__GOGYOU__,
370
- offset__GOGYOU__,
371
- model__GOGYOU__]
423
+ text = "{"
424
+ model__GOGYOU__.fields.each_with_index do |f, i|
425
+ text << "#{i > 0 ? ", " : ""}#{f.name}=#{__send__(f.name).inspect}"
426
+ end
427
+ text << "}"
372
428
  end
373
429
 
374
430
  def pretty_print(q)
375
- q.group(1, "#<#{self.class}") do
376
- q.breakable " "
377
- q.text "buffer="
378
- q.pp buffer__GOGYOU__
379
- q.text ","
380
- q.breakable " "
381
- q.text "offset="
382
- q.pp offset__GOGYOU__
383
- q.text ","
384
- q.breakable " "
385
- q.text "model="
386
- q.pp model__GOGYOU__ #|| self.class.model
387
- q.text ">"
431
+ q.group(1, "{") do
432
+ model__GOGYOU__.fields.each_with_index do |f, i|
433
+ if i > 0
434
+ q.text ","
435
+ q.breakable " "
436
+ end
437
+ q.group(1, "#{f.name}=") do
438
+ q.breakable ""
439
+ q.pp __send__(f.name)
440
+ end
441
+ end
442
+ q.text "}"
388
443
  end
389
444
  end
390
445
  end