class Gogyou::Accessor

構造体データを構造体として参照させるためのクラスです。

このクラスのサブクラスをさらに派生させたクラスが、実際の役目を負います。

クラス関係図

リストの入れ子関係は、クラスの親子関係を表します。

Attributes

buffer[R]
buffer__GOGYOU__[R]
offset[R]
offset__GOGYOU__[R]

Public Class Methods

aref(buffer, offset) click to toggle source

型情報オブジェクトとしてのメソッドです。

# File lib/gogyou/accessor.rb, line 229
def self.aref(buffer, offset)
  new(buffer, offset)
end
aset(buffer, offset, data) click to toggle source

型情報オブジェクトとしてのメソッドです。

# File lib/gogyou/accessor.rb, line 236
def self.aset(buffer, offset, data)
  raise NotImplementedError, "IMPLEMENT ME in sub class!"
end
bind(buffer, offset = 0) click to toggle source
# File lib/gogyou/accessor.rb, line 142
def self.bind(buffer, offset = 0)
  new(buffer, offset)
end
bytealign() click to toggle source

型情報オブジェクトとしてのメソッドです。

# File lib/gogyou/accessor.rb, line 250
def self.bytealign
  self::BYTEALIGN
end
bytesize() click to toggle source

型情報オブジェクトとしてのメソッドです。

# File lib/gogyou/accessor.rb, line 243
def self.bytesize
  self::BYTESIZE
end
define(model) click to toggle source
# File lib/gogyou/accessor.rb, line 150
def self.define(model)
  klass = ::Class.new(self)
  klass.class_eval do
    const_set(:MODEL, model)
    const_set(:BYTESIZE, model.bytesize)
    const_set(:BYTEALIGN, model.bytealign)
    const_set(:EXTENSIBLE, model.extensible?)
  end

  define_accessors(klass, model)

  klass
end
define_accessors(accessorclass, model) click to toggle source
# File lib/gogyou/accessor.rb, line 186
    def self.define_accessors(accessorclass, model)
      accessorclass.class_eval do
        namecheck = {}
        fieldsize = model.fields.size
        define_method(:size__GOGYOU__, -> { fieldsize })
        alias_method(:elementsize, :size__GOGYOU__)
        alias_method(:size, :size__GOGYOU__)
        const_set(:GOGYOU_FIELD_TYPES, types = [])
        model.fields.each_with_index do |field, ifield|
          name = field.name
          name = name.intern
          raise NameError, "already exist field name - #{name}" if namecheck[name]
          namecheck[name] = true

          if field.vector
            subarray = define_subarray(field)
            types << subarray
          else
            subarray = nil
            types << field.type
          end

          class_eval <<-EOS, __FILE__, __LINE__ + 1
            def #{field.name}
              v = GOGYOU_FIELD_TYPES[#{ifield}].aref(@buffer__GOGYOU__, @offset__GOGYOU__ + #{field.offset})
              v.taint if !v.frozen? && (tainted? || @buffer__GOGYOU__.tainted?)
              v.freeze if #{field.const?} || frozen? || @buffer__GOGYOU__.frozen?
              v
            end

            def #{field.name}=(value)
              raise TypeError, "immutable object (#<%s:0x%08X>)" % [self.class, __id__], caller(1) if frozen?
              raise TypeError, "immutable field (#<%s:0x%08X>.%s)" % [self.class, __id__, #{field.name.inspect}], caller(1) if #{field.const?}
              GOGYOU_FIELD_TYPES[#{ifield}].aset(@buffer__GOGYOU__, @offset__GOGYOU__ + #{field.offset}, value)
            end
          EOS
        end
      end
    end
define_subarray(field) click to toggle source
# File lib/gogyou/accessor.rb, line 164
def self.define_subarray(field)
  #sub-array のためのクラスを生成する (多次元配列であれば、それぞれの次元に対して作成)
  #sub-array クラスの MODEL 定数は、Gogyou::Model::Array のインスタンス
  fsize = field.vector.inject(&:*) * field.type.bytesize
  falign = field.type.bytealign
  felements = field.vector[-1]
  raise "BUG: negative element bytesize - #{field.inspect}" unless felements >= 0
  felements = nil if felements == 0
  fvect = field.vector.slice(0 ... -1)
  fvect = nil if fvect.empty?
  subarray = Accessor::Array.define(Model::Array[fsize, falign, [Model::Field[nil, felements, fvect, field.type]]])
  subarray.name # すでに名前が定義されてる場合はこれで固定される
  Accessor.const_set("UserArray_%08X" % subarray.__id__, subarray)
  subarray
end
define_subpointer(typeobj, constant = false) click to toggle source
# File lib/gogyou/accessor.rb, line 180
def self.define_subpointer(typeobj, constant = false)
  newtype = Accessor::Pointer.define(typeobj)
  Accessor.const_set("AnonymousPointer_%08X" % newtype.__id__, newtype)
  newtype
end
extensible?() click to toggle source

型情報オブジェクトとしてのメソッドです。

# File lib/gogyou/accessor.rb, line 257
def self.extensible?
  self::EXTENSIBLE
end
model() click to toggle source
# File lib/gogyou/accessor.rb, line 146
def self.model
  self::MODEL
end
new(buffer = String.alloc(self.class::BYTESIZE), offset = 0) click to toggle source
# File lib/gogyou/accessor.rb, line 29
def initialize(buffer = String.alloc(self.class::BYTESIZE), offset = 0)
  buffer = String.alloc(buffer.to_i) if buffer.kind_of?(Integer)
  @buffer__GOGYOU__ = buffer
  @offset__GOGYOU__ = offset.to_i
end

Public Instance Methods

bytesize() click to toggle source
# File lib/gogyou/accessor.rb, line 84
def bytesize
  self.class::BYTESIZE
end
elementsize() click to toggle source
# File lib/gogyou/accessor.rb, line 88
def elementsize
  nil
end
initialize_copy(obj) click to toggle source
Calls superclass method
# File lib/gogyou/accessor.rb, line 35
def initialize_copy(obj)
  super(obj)
  unless obj.frozen?
    @buffer__GOGYOU__ = obj.buffer__GOGYOU__.dup
  end
end
inspect() click to toggle source
# File lib/gogyou/accessor.rb, line 110
def inspect
  text = "#<#{self.class}"
  bufsize = @buffer__GOGYOU__.bytesize
  self.class::MODEL.fields.each_with_index do |f, i|
    if @offset__GOGYOU__ + f.offset + f.bytesize > bufsize
      text << "#{i > 0 ? "," : ""} #{f.name}=N/A"
    else
      text << "#{i > 0 ? "," : ""} #{f.name}=#{__send__(f.name).inspect}"
    end
  end
  text << ">"
end
pretty_print(q) click to toggle source
# File lib/gogyou/accessor.rb, line 123
def pretty_print(q)
  bufsize = @buffer__GOGYOU__.bytesize
  q.group(2, "#<#{self.class}") do
    self.class::MODEL.fields.each_with_index do |f, i|
      q.text "," if i > 0
      q.breakable " "
      if @offset__GOGYOU__ + f.offset + f.bytesize > bufsize
        q.text "#{f.name}=N/A"
      else
        q.group(1, "#{f.name}=") do
          q.breakable ""
          q.pp __send__(f.name)
        end
      end
    end
    q.text ">"
  end
end
size() click to toggle source
# File lib/gogyou/accessor.rb, line 92
def size
  elementsize
end
slide() → new_accessor or nil click to toggle source
slide(bytesize) → new_accessor or nil

自身のデータ領域を指定バイト数ずらした参照体を返します。

# File lib/gogyou/accessor.rb, line 66
def slide(bytesize = 0)
  offset = @offset__GOGYOU__ + self.class::BYTESIZE + bytesize
  self.class.new(@buffer__GOGYOU__, offset)
end
slide!() → self or nil click to toggle source
slide!(bytesize) → self or nil

詳細は slide を参照して下さい。

# File lib/gogyou/accessor.rb, line 78
def slide!(bytesize = 0)
  offset = @offset__GOGYOU__ + self.class::BYTESIZE + bytesize
  @offset__GOGYOU__ = offset
  self
end
to_address() click to toggle source
# File lib/gogyou/accessor.rb, line 53
def to_address
  @buffer__GOGYOU__.to_address + @offset__GOGYOU__
end
Also aliased as: to_ptr
to_buffer() click to toggle source
# File lib/gogyou/accessor.rb, line 49
def to_buffer
  @buffer__GOGYOU__
end
to_ptr()
Alias for: to_address
to_s() click to toggle source

バイナリデータとして取り出します。

# File lib/gogyou/accessor.rb, line 45
def to_s
  @buffer__GOGYOU__.byteslice(@offset__GOGYOU__, self.class::BYTESIZE)
end
validate? → true or false click to toggle source

validation for buffer window.

# File lib/gogyou/accessor.rb, line 102
def validate?
  if @offset__GOGYOU__ + bytesize > @buffer__GOGYOU__.bytesize
    false
  else
    true
  end
end