wiithon.formats.bcsv module

class wiithon.formats.bcsv.BCSVKey[source]

Bases: ABC

Abstract Base Class for all BCSV Keys.

abstractmethod resolve_name()[source]

Subclass must implement this to provide a str key used in the BCSVEntry dict.

Returns:

key to be used in a BCSVEntry.

Return type:

str

static create(key)[source]

Creates a BCSVKey from one of the support input types.

Returns:

Key of sub-type X, which implements its own str key used in BCSVEntry

Return type:

BCSVKey

Parameters:

key (Union[str, int, BCSVField])

class wiithon.formats.bcsv.BCSVNameKey(name)[source]

Bases: BCSVKey

BCSVKey that uses the field name directly as an input string.

Parameters:

name (str)

resolve_name()[source]

Returns the internal name of the key/field

Returns:

Direct key/field name.

Return type:

str

class wiithon.formats.bcsv.BCSVHashKey(hash_val)[source]

Bases: BCSVKey

BCSVKey that uses the field hash as the key string.

Parameters:

hash_val (int)

resolve_name()[source]

Returns the stringified version of the hash_val

Returns:

stringified hashed value.

Return type:

str

class wiithon.formats.bcsv.BCSVFieldKey(field)[source]

Bases: BCSVKey

BCSVKey that uses the entire directly to get the key string.

Parameters:

field (BCSVField)

resolve_name()[source]

Returns the field’s field_name value

Returns:

Provided field’s field_name.

Return type:

str

wiithon.formats.bcsv.calculate_field_hash(field_name)[source]

Field names are stored internally in RAM for GC/Wii games as hashes, as they are faster lookup tables. So, we will calculate the hast and the resulting hash is a 32-bit value. Breaks on first null byte (if any)

Parameters:

field_name (str) – name of the field to calculate a hash for.

Return type:

int

class wiithon.formats.bcsv.BCSVType(*values)[source]

Bases: IntEnum

Indicates the type of data stored in each field.

Strings are deprecated, use STRING_OFFSET instead. LONG, SHORT and BYTE values must be ANDed with the field’s bitmask, then shifted by the field’s shift amount.

  • LONG / UNSIGNED_LONG — 32-bit integers (signedness unspecified, can be both)

  • FLOAT — 32-bit, read and written as is

  • SHORT — 16-bit integer (signedness unspecified)

  • BYTE — single char / 8-bit integer (signedness unspecified)

  • STRING_OFFSET — offset from the start of the string pool table

LONG = 0
STRING = 1
FLOAT = 2
UNSIGNED_LONG = 3
SHORT = 4
BYTE = 5
STRING_OFFSET = 6
class wiithon.formats.bcsv.BCSVTypeSize(*values)[source]

Bases: IntEnum

Returns the size of the field based on its BCSVType.

WORD = 4
HALF_WORD = 2
BYTE = 1
STRING = 32
class wiithon.formats.bcsv.StringPoolElement(value, offset)[source]

Bases: NamedTuple

Contains a single element when writing to the output string pool table.

Parameters:
value: str

Alias for field number 0

offset: int

Alias for field number 1

class wiithon.formats.bcsv.BCSVField(field_hash, field_bitmask, field_offset, data_shift, data_type)[source]

Bases: object

Represents a single field of data in a BCSV file, similar to a column in a data table.

Fields are indexed by hash and their name defaults to the stringified hash. A field_hash -> name converter function is provided.

A BCSV file header is 12 bytes:

Offset

Meaning

0x00

Field hash (how a name becomes a hash is unknown)

0x04

Field bitmask

0x08

Starting byte of the field within a data line

0x0A

Shift amount applied to the field’s value

0x0B

Data type, see BCSVType

Parameters:
  • field_hash (int)

  • field_bitmask (int)

  • field_offset (int)

  • data_shift (int)

  • data_type (int)

field_hash: int = 0
field_name: str = None
field_bitmask: int = 0
field_offset: int = 0
field_shift: int = 0
field_type: BCSVType = None
classmethod import_field(raw_bytes)[source]

Creates a given field/header from the raw BytesIO (should be 12 bytes)

Parameters:

raw_bytes (BytesIO) – Field bytes

export_field()[source]

Exports a given field back to bytes (size: 0xC)

Returns:

The field object back in its bytes format.

Return type:

bytes

get_value_from_bytes(reader)[source]

Gets the field’s value from a given BCSV entry’s bytes.

Parameters:

reader (BinaryReader) – The reader

Returns:

Converted object from bytes into its field_type format.

Return type:

int | str | float

set_value_in_buffer(reader, writer, entry_value, string_pool)[source]

Sets the field’s value into a given BCSV entry’s bytes.

Parameters:
get_field_size()[source]

Gets the expected field size of a BCSVValue type.

Returns:

Size of the field.

Return type:

int

class wiithon.formats.bcsv.BCSVEntry[source]

Bases: dict[str, int | str | float]

BCSV entry class which allows for lookup as a string, int (field hash), or as a field directly.

hash_names: dict[int, str] = {}
class wiithon.formats.bcsv.BCSV(fields=None, entries=None)[source]

Bases: object

BCSV files are table-structured: a header block followed by a data entry block. The structure resembles a modern data table, with one key difference:

  • The header block defines all field headers (columns) and field data. The order of these definitions does not matter.

  • The data block contains the rows, one at a time. Each row is a single list index where a dictionary maps the key (column) to the value.

  • All strings live in a string table appended at the end of the data.

BCSV files start with 16 bytes describing the rest of the file structure.

Parameters:
fields: list[BCSVField]
entries: list[BCSVEntry]
str_fmt: str
classmethod import_bcsv(raw_data, field_names=None, str_fmt='utf-8')[source]

Takes an input stream of BCSV data and converts it into a BCSV object.

Parameters:
  • raw_data (BytesIO) – raw stream of a file

  • field_names (dict[int, str], default: None) – Contains the field_hash -> name quick lookup reference. By default, a field’s name is the same as the hash, this allows for human-readable names to be used instead.

  • str_fmt (str, default: 'utf-8') – Output decoding format.

export_bcsv(str_fmt='utf-8')[source]

Converts this object back into a file stream.

Parameters:

str_fmt (str, default: 'utf-8') – Output decoding format.

Returns:

output BCSV object.

Return type:

BytesIO

calculate_data_entry_size()[source]

Calculates the size of the entry based on the field’s data type.

Order of the entry size calculation is:

STRING < FLOAT < LONG < LONG_2 < SHORT < BYTE < STRING_OFFSET
Returns:

Max field size required when writing.

Return type:

int

add_bcsv_field(bcsv_field, default_value)[source]

Adds a new BCSVField and a default value to all existing data entries.

Parameters:
  • bcsv_field (BCSVField) – field to add into a given file.

  • default_value (int | str | float) – Default value to use for all entries.

remove_bcsv_field(key)[source]

Removes a new BCSVField and a default value to all existing data entries.

Parameters:

key (int | str | BCSVField) – field to add into a given file.

add_bcsv_entry(bcsv_entry)[source]

Adds a new data entry using field names or hashes as keys with complete field validation.

Parameters:

bcsv_entry (BCSVEntry) – entry to add into the BCSV

remove_bcsv_entry(bcsv_entry)[source]

Deletes a BCSVEntry by either the Entry itself or the index number.

Parameters:

bcsv_entry (int | BCSVEntry) – entry (or index) to remove from the BCSV

verify_fields_and_entries(fields=None, entries=None)[source]

Verifies if all the BCSV Fields are in fact properly defined keys/fields. Similarly validates entries.

Parameters:
  • fields (list[BCSVField], default: None) – A list of headers/fields for a BCSV file

  • entries (list[BCSVEntry], default: None) – A list of rows/entries for a BCSV file

classmethod read(stream, **kwargs)[source]
Parameters:

stream (BytesIO)

Return type:

BCSV

write(stream)[source]
Parameters:

stream (BytesIO)

Return type:

None