### Navigation

- index
- modules |
- next |
- previous |
- PyFFI 2.2.2 documentation »
- `pyffi` — Interfacing block structured files »
- `pyffi.formats` — File format interfaces »

# `pyffi.formats.bsa` — Bethesda Archive (.bsa)

Warning

This module is still a work in progress, and is not yet ready for production use.

A .bsa file is an archive format used by Bethesda (Morrowind, Oblivion, Fallout 3).

## Implementation

class `pyffi.formats.bsa.``BsaFormat`

  Bases: `pyffi.object_models.xml.FileFormat`

  This class implements the BSA format.

  `Data`

    alias of `Header`

  class `FileVersion`(**kwargs)

    Bases: `pyffi.object_models.common.UInt`

    Basic type which implements the header of a BSA file.

    `get_size`(data=None)

      Return number of bytes the header string occupies in a file.

      Returns: | Number of bytes.

    `read`(stream, data)

      Read header string from stream and check it.

      Parameters: | stream (file) – The stream to read from.

    `write`(stream, data)

      Write the header string to stream.

      Parameters: | stream (file) – The stream to write to.

  class `BsaFormat.``Header`(template=None, argument=None, parent=None)

    Bases: `pyffi.formats.bsa._Header`, `pyffi.object_models.Data`

    A class to contain the actual bsa data.

    `inspect`(stream)

      Quickly checks if stream contains BSA data, and reads the header.

      Parameters: | stream (file) – The stream to inspect.

    `inspect_quick`(stream)

      Quickly checks if stream contains BSA data, and gets the version, by looking at the first 8 bytes.

      Parameters: | stream (file) – The stream to inspect.

    `read`(stream)

      Read a bsa file.

      Parameters: | stream (`file`) – The stream from which to read.

    `write`(stream)

      Write a bsa file.

      Parameters: | stream (`file`) – The stream to which to write.

  `BsaFormat.``UInt32`

    alias of `UInt`

  class `BsaFormat.``ZString`(**kwargs)

    Bases: `pyffi.object_models.xml.basic.BasicBase`, `pyffi.object_models.editable.EditableLineEdit`

    String of variable length (null terminated).

        >>> from tempfile import TemporaryFile
        >>> f = TemporaryFile()
        >>> s = ZString()
        >>> if f.write('abcdefghijklmnopqrst\x00'.encode("ascii")): pass # b'abc...'
        >>> if f.seek(0): pass # ignore result for py3k
        >>> s.read(f)
        >>> str(s)
        'abcdefghijklmnopqrst'
        >>> if f.seek(0): pass # ignore result for py3k
        >>> s.set_value('Hi There!')
        >>> s.write(f)
        >>> if f.seek(0): pass # ignore result for py3k
        >>> m = ZString()
        >>> m.read(f)
        >>> str(m)
        'Hi There!'

    `get_hash`(data=None)

      Return a hash value for this string.

      Returns: | An immutable object that can be used as a hash.

    `get_size`(data=None)

      Return number of bytes this type occupies in a file.

      Returns: | Number of bytes.

    `get_value`()

      Return the string.

      Returns: | The stored string.
      Return type: | C{bytes}

    `read`(stream, data=None)

      Read string from stream.

      Parameters: | stream (file) – The stream to read from.

    `set_value`(value)

      Set string to C{value}.

      Parameters: | value (`str` (will be encoded as default) or C{bytes}) – The value to assign.

    `write`(stream, data=None)

      Write string to stream.

      Parameters: | stream (file) – The stream to write to.

  static `BsaFormat.``version_number`(version_str)

    Converts version string into an integer.

    Parameters: | version_str (str) – The version string.
    Returns: | A version integer.

        >>> BsaFormat.version_number('103')
        103
        >>> BsaFormat.version_number('XXX')
        -1

## Regression tests

### Read a BSA file

    >>> # check and read bsa file
    >>> stream = open('tests/bsa/test.bsa', 'rb')
    >>> data = BsaFormat.Data()
    >>> data.inspect_quick(stream)
    >>> data.version
    103
    >>> data.inspect(stream)
    >>> data.folders_offset
    36
    >>> hex(data.archive_flags.to_int(data))
    '0x703'
    >>> data.num_folders
    1
    >>> data.num_files
    7
    >>> #data.read(stream)
    >>> # TODO check something else...

### Parse all BSA files in a directory tree

    >>> for stream, data in BsaFormat.walkData('tests/bsa'):
    ...     print(stream.name)
    tests/bsa/test.bsa

### Create an BSA file from scratch and write to file

    >>> data = BsaFormat.Data()
    >>> # TODO store something...
    >>> from tempfile import TemporaryFile
    >>> stream = TemporaryFile()
    >>> #data.write(stream)

### Navigation

- index
- modules |
- next |
- previous |
- PyFFI 2.2.2 documentation »
- `pyffi` — Interfacing block structured files »
- `pyffi.formats` — File format interfaces »