module FFI
  class AbstractMemory
    interface _Size
      def size: () -> Integer
    end
    include _Size
    type type_size = Integer | _Size | Symbol

    type order_out = :big | :little
    type order_in = order_out | :network

    def []: (Integer idx) -> instance
    def clear: () -> self
    def freeze: ...
    def get: (ffi_type type, Integer offset) -> top
    def put: (ffi_type type, Integer offset, top value) -> nil
    def size_limit?: () -> bool
    def type_size: () -> Integer
    alias total size

    def get_int8: (Integer offset) -> Integer
    def get_int16: (Integer offset) -> Integer
    def get_int32: (Integer offset) -> Integer
    def get_int64: (Integer offset) -> Integer
    def get_uint8: (Integer offset) -> Integer
    def get_uint16: (Integer offset) -> Integer
    def get_uint32: (Integer offset) -> Integer
    def get_uint64: (Integer offset) -> Integer
    def get_char: (Integer offset) -> Integer
    def get_short: (Integer offset) -> Integer
    def get_int: (Integer offset) -> Integer
    def get_long_long: (Integer offset) -> Integer
    def get_float32: (Integer offset) -> Float
    def get_float64: (Integer offset) -> Float
    def get_pointer: (Integer offset) -> Pointer
    def get_bytes: (Integer offset, Integer length) -> String
    def get_string: (Integer offset, ?Integer? length) -> String
    alias get_float get_float32
    alias get_double get_float64

    def put_int8: (Integer offset, int value) -> self
    def put_int16: (Integer offset, int value) -> self
    def put_int32: (Integer offset, int value) -> self
    def put_int64: (Integer offset, int value) -> self
    def put_uint8: (Integer offset, int value) -> self
    def put_uint16: (Integer offset, int value) -> self
    def put_uint32: (Integer offset, int value) -> self
    def put_uint64: (Integer offset, int value) -> self
    def put_char: (Integer offset, int value) -> self
    def put_short: (Integer offset, int value) -> self
    def put_int: (Integer offset, int value) -> self
    def put_long_long: (Integer offset, int value) -> self
    def put_float32: (Integer offset, Numeric value) -> self
    def put_float64: (Integer offset, Numeric value) -> self
    def put_pointer: (Integer offset, pointer value) -> self
    def put_bytes: (Integer offset, String str, ?Integer index, ?Integer? length) -> self
    def put_string: (Integer offset, String value) -> self
    alias put_float put_float32
    alias put_double put_float64

    def read_int8: () -> Integer
    def read_int16: () -> Integer
    def read_int32: () -> Integer
    def read_int64: () -> Integer
    def read_uint8: () -> Integer
    def read_uint16: () -> Integer
    def read_uint32: () -> Integer
    def read_uint64: () -> Integer
    def read_char: () -> Integer
    def read_short: () -> Integer
    def read_int: () -> Integer
    def read_long_long: () -> Integer
    def read_float: () -> Float
    def read_double: () -> Float
    def read_pointer: () -> Pointer
    def read_bytes: (Integer length) -> String

    def write_int8: (int value) -> self
    def write_int16: (int value) -> self
    def write_int32: (int value) -> self
    def write_int64: (int value) -> self
    def write_uint8: (int value) -> self
    def write_uint16: (int value) -> self
    def write_uint32: (int value) -> self
    def write_uint64: (int value) -> self
    def write_char: (int value) -> self
    def write_short: (int value) -> self
    def write_int: (int value) -> self
    def write_long_long: (int value) -> self
    def write_float: (Numeric value) -> self
    def write_double: (Numeric value) -> self
    def write_pointer: (pointer value) -> self
    def write_bytes: (String str, ?Integer index, ?Integer? length) -> self

    def get_array_of_int8: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_int16: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_int32: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_int64: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_uint8: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_uint16: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_uint32: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_uint64: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_char: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_short: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_int: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_long_long: (Integer offset, Integer length) -> Array[Integer]
    def get_array_of_float32: (Integer offset, Integer length) -> Array[Float]
    def get_array_of_float64: (Integer offset, Integer length) -> Array[Float]
    def get_array_of_pointer: (Integer offset, Integer length) -> Array[Pointer]
    def get_array_of_string: (Integer offset, ?Integer? count) -> Array[String?]
    alias get_array_of_float get_array_of_float32
    alias get_array_of_double get_array_of_float64

    def put_array_of_int8: (Integer offset, Array[int] ary) -> self
    def put_array_of_int16: (Integer offset, Array[int] ary) -> self
    def put_array_of_int32: (Integer offset, Array[int] ary) -> self
    def put_array_of_int64: (Integer offset, Array[int] ary) -> self
    def put_array_of_uint8: (Integer offset, Array[int] ary) -> self
    def put_array_of_uint16: (Integer offset, Array[int] ary) -> self
    def put_array_of_uint32: (Integer offset, Array[int] ary) -> self
    def put_array_of_uint64: (Integer offset, Array[int] ary) -> self
    def put_array_of_char: (Integer offset, Array[int] ary) -> self
    def put_array_of_short: (Integer offset, Array[int] ary) -> self
    def put_array_of_int: (Integer offset, Array[int] ary) -> self
    def put_array_of_long_long: (Integer offset, Array[int] ary) -> self
    def put_array_of_float32: (Integer offset, Array[Numeric] ary) -> self
    def put_array_of_float64: (Integer offset, Array[Numeric] ary) -> self
    def put_array_of_pointer: (Integer offset, Array[pointer] ary) -> self
    alias put_array_of_float put_array_of_float32
    alias put_array_of_double put_array_of_float64

    def read_array_of_int8: (Integer length) -> Array[Integer]
    def read_array_of_int16: (Integer length) -> Array[Integer]
    def read_array_of_int32: (Integer length) -> Array[Integer]
    def read_array_of_int64: (Integer length) -> Array[Integer]
    def read_array_of_uint8: (Integer length) -> Array[Integer]
    def read_array_of_uint16: (Integer length) -> Array[Integer]
    def read_array_of_uint32: (Integer length) -> Array[Integer]
    def read_array_of_uint64: (Integer length) -> Array[Integer]
    def read_array_of_char: (Integer length) -> Array[Integer]
    def read_array_of_short: (Integer length) -> Array[Integer]
    def read_array_of_int: (Integer length) -> Array[Integer]
    def read_array_of_long_long: (Integer length) -> Array[Integer]
    def read_array_of_float: (Integer length) -> Array[Float]
    def read_array_of_double: (Integer length) -> Array[Float]
    def read_array_of_pointer: (Integer length) -> Array[Pointer]
    def read_array_of_string: (?Integer? count) -> Array[String?]

    def write_array_of_int8: (Array[int] ary) -> self
    def write_array_of_int16: (Array[int] ary) -> self
    def write_array_of_int32: (Array[int] ary) -> self
    def write_array_of_int64: (Array[int] ary) -> self
    def write_array_of_uint8: (Array[int] ary) -> self
    def write_array_of_uint16: (Array[int] ary) -> self
    def write_array_of_uint32: (Array[int] ary) -> self
    def write_array_of_uint64: (Array[int] ary) -> self
    def write_array_of_char: (Array[int] ary) -> self
    def write_array_of_short: (Array[int] ary) -> self
    def write_array_of_int: (Array[int] ary) -> self
    def write_array_of_long_long: (Array[int] ary) -> self
    def write_array_of_float: (Array[Numeric] ary) -> self
    def write_array_of_double: (Array[Numeric] ary) -> self
    def write_array_of_pointer: (Array[pointer] ary) -> self
  end
end
