class BinData::Stringz

byte.
:max_length

The maximum length of the string including the zero
does, as well as the following:
Stringz objects accept all the params that BinData::BasePrimitive
== Parameters
obj.to_binary_s #=> “abcd000”
obj.num_bytes #=> 5
obj.snapshot #=> “abcd”
obj.read(data)
obj = BinData::Stringz.new
data = “abcdx00efgh”
require ‘bindata’
value. Likewise, the returned value will not be zero terminated.
For convenience, the zero terminator is not necessary when setting the
string.
A BinData::Stringz object is a container for a zero (“0”) terminated

def append_zero_byte_if_needed!(str)

def append_zero_byte_if_needed!(str)
  if str.length == 0 || str[-1, 1] != "\0"
    str << "\0"
  end
end

def assign(val)

def assign(val)
  super(binary_string(val))
end

def read_and_return_value(io)

def read_and_return_value(io)
  max_length = eval_parameter(:max_length)
  str = ""
  i = 0
  ch = nil
  # read until zero byte or we have read in the max number of bytes
  while ch != "\0" && i != max_length
    ch = io.readbytes(1)
    str += ch
    i += 1
  end
  trim_and_zero_terminate(str)
end

def sensible_default

def sensible_default
  ""
end

def snapshot

def snapshot
  # override to always remove trailing zero bytes
  result = super
  trim_and_zero_terminate(result).chomp("\0")
end

def trim_and_zero_terminate(str)

def trim_and_zero_terminate(str)
  result = binary_string(str)
  truncate_after_first_zero_byte!(result)
  trim_to!(result, eval_parameter(:max_length))
  append_zero_byte_if_needed!(result)
  result
end

def trim_to!(str, max_length = nil)

def trim_to!(str, max_length = nil)
  if max_length
    max_length = 1 if max_length < 1
    str.slice!(max_length..-1)
    if str.length == max_length && str[-1, 1] != "\0"
      str[-1, 1] = "\0"
    end
  end
end

def truncate_after_first_zero_byte!(str)

def truncate_after_first_zero_byte!(str)
  str.sub!(/([^\0]*\0).*/, '\1')
end

def value_to_binary_string(val)

def value_to_binary_string(val)
  trim_and_zero_terminate(val)
end