gogyou 0.2.2 → 0.2.3

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