class BinData::Struct

def _assign(val)

def _assign(val)
  clear
  assign_fields(as_snapshot(val))
end

def _do_num_bytes(name) #:nodoc:

:nodoc:
def _do_num_bytes(name) #:nodoc:
  if name.nil?
    orig__do_num_bytes(nil)
  else
    warn "'obj.num_bytes(name)' is deprecated.  Replacing with 'obj.name.num_bytes'"
    obj = find_obj_for_name(name)
    obj.nil? ? 0 : obj.do_num_bytes
  end
end

def _do_num_bytes(deprecated)

def _do_num_bytes(deprecated)
  instantiate_all_objs
  sum_num_bytes_for_all_fields.ceil
end

def _do_read(io)

def _do_read(io)
  instantiate_all_objs
  @field_objs.each { |f| f.do_read(io) if include_obj(f) }
end

def _do_write(io)

def _do_write(io)
  instantiate_all_objs
  @field_objs.each { |f| f.do_write(io) if include_obj(f) }
end

def _done_read

def _done_read
  @field_objs.each { |f| f.done_read if include_obj(f) }
end

def _snapshot

def _snapshot
  snapshot = Snapshot.new
  field_names.each do |name|
    obj = find_obj_for_name(name)
    snapshot[name] = obj.snapshot if include_obj(obj)
  end
  snapshot
end

def as_snapshot(val)

def as_snapshot(val)
  if val.class == Hash
    snapshot = Snapshot.new
    val.each_pair { |k,v| snapshot[k.to_s] = v unless v.nil? }
    snapshot
  elsif val.nil?
    Snapshot.new
  else
    val
  end
end

def assign_fields(snapshot)

def assign_fields(snapshot)
  field_names(true).each do |name|
    obj = find_obj_for_name(name)
    if obj and snapshot.respond_to?(name)
      obj.assign(snapshot.__send__(name))
    end
  end
end

def clear(name = nil) #:nodoc:

:nodoc:
def clear(name = nil) #:nodoc:
  if name.nil?
    orig_clear
  else
    warn "'obj.clear(name)' is deprecated.  Replacing with 'obj.name.clear'"
    obj = find_obj_for_name(name)
    obj.clear unless obj.nil?
  end
end

def clear

def clear
  @field_objs.each { |f| f.clear unless f.nil? }
end

def clear?(name = nil) #:nodoc:

:nodoc:
def clear?(name = nil) #:nodoc:
  if name.nil?
    orig_clear?
  else
    warn "'obj.clear?(name)' is deprecated.  Replacing with 'obj.name.clear?'"
    obj = find_obj_for_name(name)
    obj.nil? ? true : obj.clear?
  end
end

def clear?

def clear?
  @field_objs.inject(true) { |all_clear, f| all_clear and (f.nil? or f.clear?) }
end

def debug_name_of(child)

def debug_name_of(child)
  field_name = @field_names[find_index_of(child)]
  "#{debug_name}.#{field_name}"
end

def ensure_field_names_are_valid(field_names)

def ensure_field_names_are_valid(field_names)
  instance_methods = self.instance_methods
  reserved_names = RESERVED
  field_names.each do |name|
    if instance_methods.include?(name)
      raise NameError.new("Rename field '#{name}' in #{self}, " +
                          "as it shadows an existing method.", name)
    end
    if reserved_names.include?(name)
      raise NameError.new("Rename field '#{name}' in #{self}, " +
                          "as it is a reserved name.", name)
    end
    if field_names.count(name) != 1
      raise NameError.new("field '#{name}' in #{self}, " +
                          "is defined multiple times.", name)
    end
  end
end

def field_names(include_hidden = false)

in the listing.
object. +include_hidden+ specifies whether to include hidden names
Returns a list of the names of all fields accessible through this
def field_names(include_hidden = false)
  if include_hidden
    @field_names.dup
  else
    hidden = get_parameter(:hide) || []
    @field_names - hidden
  end
end

def find_index_of(obj)

def find_index_of(obj)
  @field_objs.find_index { |el| el.equal?(obj) }
end

def find_obj_for_name(name)

def find_obj_for_name(name)
  field_name = name.to_s.chomp("=")
  index = @field_names.find_index(field_name)
  if index
    instantiate_obj_at(index)
    @field_objs[index]
  else
    nil
  end
end

def hidden_field_names(hidden)

def hidden_field_names(hidden)
  (hidden || []).collect { |h| h.to_s }
end

def include_obj(obj)

def include_obj(obj)
  not obj.has_parameter?(:onlyif) or obj.eval_parameter(:onlyif)
end

def inherited(subclass) #:nodoc:

:nodoc:
def inherited(subclass) #:nodoc:
  if subclass != Record
    fail "error: inheriting from BinData::Struct has been deprecated. Inherit from BinData::Record instead."
  end
end

def initialize(params = {}, parent = nil)

def initialize(params = {}, parent = nil)
  super(params, parent)
  @field_names = get_parameter(:fields).field_names
  @field_objs  = []
end

def instantiate_all_objs

def instantiate_all_objs
  @field_names.each_index { |i| instantiate_obj_at(i) }
end

def instantiate_obj_at(index)

def instantiate_obj_at(index)
  if @field_objs[index].nil?
    field = get_parameter(:fields)[index]
    @field_objs[index] = field.instantiate(self)
  end
end

def invoke_field(obj, symbol, args)

def invoke_field(obj, symbol, args)
  name = symbol.to_s
  is_writer = (name[-1, 1] == "=")
  if is_writer
    obj.assign(*args)
  else
    obj
  end
end

def method_missing(symbol, *args, &block)

def method_missing(symbol, *args, &block)
  obj = find_obj_for_name(symbol)
  if obj
    invoke_field(obj, symbol, args)
  else
    super
  end
end

def offset_of(child)

def offset_of(child)
  if child.class == ::String
    fail "error: 'offset_of(\"fieldname\")' is deprecated.  Use 'fieldname.offset' instead"
  end
  orig_offset_of(child)
end

def offset_of(child)

def offset_of(child)
  instantiate_all_objs
  sum = sum_num_bytes_below_index(find_index_of(child))
  child_offset = (::Integer === child.do_num_bytes) ? sum.ceil : sum.floor
  offset + child_offset
end

def respond_to?(symbol, include_private = false)

def respond_to?(symbol, include_private = false)
  super(symbol, include_private) ||
    field_names(true).include?(symbol.to_s.chomp("="))
end

def sanitize_endian(params, sanitizer)

def sanitize_endian(params, sanitizer)
  if params.needs_sanitizing?(:endian)
    params[:endian] = sanitizer.create_sanitized_endian(params[:endian])
  end
end

def sanitize_fields(params, sanitizer)

def sanitize_fields(params, sanitizer)
  if params.needs_sanitizing?(:fields)
    fields = params[:fields]
    params[:fields] = sanitizer.create_sanitized_fields(params[:endian])
    fields.each do |ftype, fname, fparams|
      params[:fields].add_field(ftype, fname, fparams)
    end
    field_names = sanitized_field_names(params[:fields])
    ensure_field_names_are_valid(field_names)
  end
end

def sanitize_hide(params, sanitizer)

def sanitize_hide(params, sanitizer)
  if params.needs_sanitizing?(:hide) and params.has_parameter?(:fields)
    field_names = sanitized_field_names(params[:fields])
    hfield_names = hidden_field_names(params[:hide])
    params[:hide]   = (hfield_names & field_names)
  end
end

def sanitize_parameters!(params, sanitizer)

def sanitize_parameters!(params, sanitizer)
  sanitize_endian(params, sanitizer)
  sanitize_fields(params, sanitizer)
  sanitize_hide(params, sanitizer)
end

def sanitized_field_names(sanitized_fields)

def sanitized_field_names(sanitized_fields)
  sanitized_fields.field_names
end

def sum_num_bytes_below_index(index)

def sum_num_bytes_below_index(index)
  sum = 0
  (0...index).each do |i|
    obj = @field_objs[i]
    if include_obj(obj)
      nbytes = obj.do_num_bytes
      sum = ((::Integer === nbytes) ? sum.ceil : sum) + nbytes
    end
  end
  sum
end

def sum_num_bytes_for_all_fields

def sum_num_bytes_for_all_fields
  sum_num_bytes_below_index(@field_objs.length)
end