class Ronin::Support::Binary::Struct

Generic Binary Struct class.

@note This class provides lazy memory mapped access to an underlying buffer. This means values are decoded/encoded each time they are read or written to.

## Examples

### Defining Members

class Point < Ronin::Support::Binary::Struct

  member :x, :int32
  member :y, :int32

end

### Initializing Structs

From a Hash:

point = Point.new(x: 1, y: 2)

From a buffer:

point = Point.new("\x01\x00\x00\x00\xFF\xFF\xFF\xFF")

### Reading Fields

point = Point.new("\x01\x00\x00\x00\xFF\xFF\xFF\xFF")
point[:x]
# => 1
point[:y]
# => -1

point.x
# => 1
point.y
# => -1

### Packing Structs

class Point < Ronin::Support::Binary::Struct

  member :x, :int32
  member :y, :int32

end

point = Point.new(x: 10, y: -1)
point.pack
# => "\n\x00\x00\x00\xFF\xFF\xFF\xFF"

### Unpacking Structs

class Point < Ronin::Support::Binary::Struct

  member :x, :int32
  member :y, :int32

end

point = Point.unpack("\x00\x00\x00\x01\xFF\xFF\xFF\xFF")
point.x
# => 1
point.y
# => -1

### Inheriting Structs

class Point < Ronin::Support::Binary::Struct

  member :x, :int32
  member :y, :int32

end

class Point3D < Point

  member :z, :int32

end

point   = Point.new(x: 100, y: 42)
point3d = Point3D.new(x: 100, y: 42, z: -1)

### Array Fields

class MyStruct < Ronin::Support::Binary::Struct

  member :x,    :uint32
  member :nums, [:uint8, 10]

end

struct = MyStruct.new
struct.nums = [0x01, 0x02, 0x03, 0x04]
struct.pack
# => "\x00\x00\x00\x00\x01\x02\x03\x04\x00\x00\x00\x00\x00\x00"

### Unbounded Array Fields

class MyStruct < Ronin::Support::Binary::Struct

  member :length,  :uint32
  member :payload, (:uint8..)

end

struct = MyStruct.new
struct.payload = [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]
struct.pack
# => "\x00\x00\x00\x00\x01\x02\x03\x04\x05\x06\a\b"

### Struct Endianness

class MyStruct < Ronin::Support::Binary::Struct

  platform endian: :big

  member :x, :uint32
  member :y, :uint32

end

struct = MyStruct.new
struct.x = 0xAABB
struct.y = 0xCCDD
struct.pack
# => "\x00\x00\xAA\xBB\x00\x00\xCC\xDD"

### Struct Architecture

class MyStruct < Ronin::Support::Binary::Struct

  platform arch: :arm64_be

  member :x, :int
  member :y, :int
  member :f, :double

end

struct = MyStruct.new
struct.x = 100
struct.y = -100
struct.f = (90 / Math::PI)
struct.pack
# => "\x00\x00\x00d\xFF\xFF\xFF\x9C@<\xA5\xDC\x1Ac\xC1\xF8"

### Struct Operating System (OS)

class MyStruct < Ronin::Support::Binary::Struct

  platform arch: :x86_64, os: :windows

  member :x, :long
  member :y, :long

end

struct = MyStruct.new
struct.x = 255
struct.y = -1
struct.pack
# => "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF"

### Struct Alignment

class Pixel < Ronin::Support::Binary::Struct

  align 4

  member :r, :uint8
  member :g, :uint8
  member :b, :uint8

end

class PixelBuf < Ronin::Support::Binary::Struct

  member :count, :uint8
  member :pixels, [Pixel, 255]

end

pixelbuf = PixelBuf.new
pixelbuf.count = 2
pixelbuf.pixels[0].r = 0xAA
pixelbuf.pixels[0].g = 0xBB
pixelbuf.pixels[0].b = 0xCC
pixelbuf.pixels[1].r = 0xAA
pixelbuf.pixels[1].g = 0xBB
pixelbuf.pixels[1].b = 0xCC
pixelbuf.pack
# => "\x02\x00\x00\x00\xAA\xBB\xCC\xAA\xBB\xCC..."

### Disable Struct Padding

class MyStruct < Ronin::Support::Binary::Struct

  padding false

  member :c, :char
  member :i, :int32

end

struct = MyStruct.new
struct.c = 'A'
struct.i = -1
struct.pack
# => "A\xFF\xFF\xFF\xFF"

@api public