Class: Ips::BinaryWriter

Inherits:
Object
  • Object
show all
Defined in:
lib/ips/binary_writer.rb

Overview

Binary data writer for modifying ROM files with patch data.

This class provides methods to write bytes at specific offsets and save the modified data to a file. It includes comprehensive error handling and validation.

Examples:

Writing bytes and saving

rom_data = File.binread("game.rom")
writer = Ips::BinaryWriter.new(rom_data)
writer.set_bytes(0x1000, "\x42\x43\x44")
writer.save_to_file("game_patched.rom")

Defined Under Namespace

Classes: Error

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(data) ⇒ BinaryWriter

Creates a new BinaryWriter instance.

Parameters:

  • data (String) —

    the binary data to write to

Raises:

  • (Error) —

    if data is nil or not a String



25
26
27
28
29
30
31
32
# File 'lib/ips/binary_writer.rb', line 25

def initialize(data)
  raise Error, "Data cannot be nil" if data.nil?
  raise Error, "Data must be a String" unless data.is_a?(String)
  
  @data = StringIO.new(data.b)
rescue => e
  raise Error, "Failed to initialize BinaryWriter: #{e.message}"
end

Instance Attribute Details

#data ⇒ StringIO (readonly)

Returns the internal StringIO object containing the binary data.

Returns:

  • (StringIO) —

    the internal StringIO object containing the binary data



18
19
20
# File 'lib/ips/binary_writer.rb', line 18

def data
  @data
end

Instance Method Details

#save_to_file(path) ⇒ void

This method returns an undefined value.

Saves the current data to a file.

Parameters:

  • path (String) —

    the file path to save to

Raises:

  • (Error) —

    if path is nil or empty

  • (Error) —

    if the directory does not exist

  • (Error) —

    if permission is denied

  • (Error) —

    if no space is left on the device

  • (Error) —

    if an IO or system error occurs during saving



64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/ips/binary_writer.rb', line 64

def save_to_file(path)
  raise Error, "Path cannot be nil or empty" if path.nil? || path.to_s.empty?

  File.binwrite(path, @data.string)
rescue Errno::ENOENT => e
  raise Error, "Directory does not exist: #{e.message}"
rescue Errno::EACCES => e
  raise Error, "Permission denied: #{e.message}"
rescue Errno::ENOSPC => e
  raise Error, "No space left on device: #{e.message}"
rescue IOError, SystemCallError => e
  raise Error, "Failed to save file to #{path}: #{e.message}"
end

#set_bytes(offset, bytes) ⇒ void

This method returns an undefined value.

Writes bytes at a specific offset in the data.

Parameters:

  • offset (Integer) —

    the position to write the bytes at

  • bytes (String) —

    the bytes to write

Raises:

  • (Error) —

    if offset is nil, not numeric, or negative

  • (Error) —

    if bytes is nil or not a String

  • (Error) —

    if an IO or system error occurs during writing



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/ips/binary_writer.rb', line 42

def set_bytes(offset, bytes)
  raise Error, "Offset cannot be nil" if offset.nil?
  raise Error, "Offset must be a numeric value" unless offset.is_a?(Numeric)
  raise Error, "Offset cannot be negative" if offset < 0
  raise Error, "Bytes cannot be nil" if bytes.nil?
  raise Error, "Bytes must be a String" unless bytes.is_a?(String)

  @data.seek(offset)
  @data.write(bytes)
rescue IOError, SystemCallError => e
  raise Error, "Failed to write bytes at offset #{offset}: #{e.message}"
end