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
[source]¶ Bases:
pyffi.object_models.xml.FileFormat
This class implements the BSA format.
-
class
BZString
(**kwargs)[source]¶ Bases:
pyffi.object_models.common.SizedString
-
get_size
(data=None)[source]¶ Return number of bytes this type occupies in a file.
- Returns
Number of bytes.
-
-
class
FileVersion
(**kwargs)[source]¶ Bases:
pyffi.object_models.common.UInt
Basic type which implements the header of a BSA file.
-
get_size
(data=None)[source]¶ Return number of bytes the header string occupies in a file.
- Returns
Number of bytes.
-
-
class
Header
(template=None, argument=None, parent=None)[source]¶ Bases:
pyffi.formats.bsa._Header
,pyffi.object_models.Data
A class to contain the actual bsa data.
-
inspect
(stream)[source]¶ Quickly checks if stream contains BSA data, and reads the header.
- Parameters
stream (file) – The stream to inspect.
-
-
UInt32
¶ alias of
pyffi.object_models.common.UInt
-
class
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.
-
-
class
Regression tests¶
Read a BSA file¶
>>> # check and read bsa file
>>> from os.path import dirname
>>> dirpath = __file__
>>> for i in range(4): #recurse up to root repo dir
... dirpath = dirname(dirpath)
>>> repo_root = dirpath
>>> format_root = os.path.join(repo_root, 'tests', 'formats', 'bsa')
>>> stream = open(os.path.join(format_root, 'test.bsa'), 'rb')
>>> data = BsaFormat.Data()
>>> data.inspect_quick(stream)
>>> data.version
103
>>> data.inspect(stream)
>>> data.folders_offset
36
>>> hex(data.archive_flags.get_attributes_values(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(format_root):
... try:
... # the replace call makes the doctest also pass on windows
... os_path = stream.name
... split = (os_path.split(os.sep))[-4:]
... rejoin = os.path.join(*split).replace(os.sep, "/")
... print("reading %s" % rejoin)
... data.read(stream)
... except Exception:
... print(
... "Warning: read failed due corrupt file,"
... " corrupt format description, or bug.")
reading tests/formats/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)