.dat file format of Fallout 2: Java (read-write) parsing library

Application

Fallout 2

File extension

dat

KS implementation details

License: CC0-1.0

References

This page hosts a formal specification of .dat file format of Fallout 2 using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Java (read-write) source code to parse .dat file format of Fallout 2

Fallout2Dat.java

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

import io.kaitai.struct.ByteBufferKaitaiStream;
import io.kaitai.struct.KaitaiStruct;
import io.kaitai.struct.KaitaiStream;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Objects;
import io.kaitai.struct.ConsistencyError;
import java.util.ArrayList;
import java.util.List;
import java.nio.charset.StandardCharsets;
import java.nio.charset.Charset;

public class Fallout2Dat extends KaitaiStruct.ReadWrite {
    public static Fallout2Dat fromFile(String fileName) throws IOException {
        return new Fallout2Dat(new ByteBufferKaitaiStream(fileName));
    }

    public enum Compression {
        NONE(0),
        ZLIB(1);

        private final long id;
        Compression(long id) { this.id = id; }
        public long id() { return id; }
        private static final Map<Long, Compression> byId = new HashMap<Long, Compression>(2);
        static {
            for (Compression e : Compression.values())
                byId.put(e.id(), e);
        }
        public static Compression byId(long id) { return byId.get(id); }
    }
    public Fallout2Dat() {
        this(null, null, null);
    }

    public Fallout2Dat(KaitaiStream _io) {
        this(_io, null, null);
    }

    public Fallout2Dat(KaitaiStream _io, KaitaiStruct.ReadWrite _parent) {
        this(_io, _parent, null);
    }

    public Fallout2Dat(KaitaiStream _io, KaitaiStruct.ReadWrite _parent, Fallout2Dat _root) {
        super(_io);
        this._parent = _parent;
        this._root = _root == null ? this : _root;
    }
    public void _read() {
        _dirty = false;
    }

    public void _fetchInstances() {
        footer();
        if (this.footer != null) {
            this.footer._fetchInstances();
        }
        index();
        if (this.index != null) {
            this.index._fetchInstances();
        }
    }

    public void _write_Seq() {
        _assertNotDirty();
        _shouldWriteFooter = _enabledFooter;
        _shouldWriteIndex = _enabledIndex;
    }

    public void _check() {
        if (_enabledFooter) {
            if (!Objects.equals(this.footer._root(), _root()))
                throw new ConsistencyError("footer", _root(), this.footer._root());
            if (!Objects.equals(this.footer._parent(), this))
                throw new ConsistencyError("footer", this, this.footer._parent());
        }
        if (_enabledIndex) {
            if (!Objects.equals(this.index._root(), _root()))
                throw new ConsistencyError("index", _root(), this.index._root());
            if (!Objects.equals(this.index._parent(), this))
                throw new ConsistencyError("index", this, this.index._parent());
        }
        _dirty = false;
    }
    public static class File extends KaitaiStruct.ReadWrite {
        public static File fromFile(String fileName) throws IOException {
            return new File(new ByteBufferKaitaiStream(fileName));
        }
        public File() {
            this(null, null, null);
        }

        public File(KaitaiStream _io) {
            this(_io, null, null);
        }

        public File(KaitaiStream _io, Fallout2Dat.Index _parent) {
            this(_io, _parent, null);
        }

        public File(KaitaiStream _io, Fallout2Dat.Index _parent, Fallout2Dat _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
        }
        public void _read() {
            this.name = new Pstr(this._io, this, _root);
            this.name._read();
            this.flags = Fallout2Dat.Compression.byId(this._io.readU1());
            this.sizeUnpacked = this._io.readU4le();
            this.sizePacked = this._io.readU4le();
            this.offset = this._io.readU4le();
            _dirty = false;
        }

        public void _fetchInstances() {
            this.name._fetchInstances();
            contentsRaw();
            if (this.contentsRaw != null) {
            }
            contentsZlib();
            if (this.contentsZlib != null) {
            }
        }

        public void _write_Seq() {
            _assertNotDirty();
            _shouldWriteContentsRaw = _enabledContentsRaw;
            _shouldWriteContentsZlib = _enabledContentsZlib;
            this.name._write_Seq(this._io);
            this._io.writeU1(((Number) (this.flags.id())).intValue());
            this._io.writeU4le(this.sizeUnpacked);
            this._io.writeU4le(this.sizePacked);
            this._io.writeU4le(this.offset);
        }

        public void _check() {
            if (!Objects.equals(this.name._root(), _root()))
                throw new ConsistencyError("name", _root(), this.name._root());
            if (!Objects.equals(this.name._parent(), this))
                throw new ConsistencyError("name", this, this.name._parent());
            if (_enabledContentsRaw) {
                if (flags() == Fallout2Dat.Compression.NONE) {
                    if (this.contentsRaw.length != sizeUnpacked())
                        throw new ConsistencyError("contents_raw", sizeUnpacked(), this.contentsRaw.length);
                }
            }
            if (_enabledContentsZlib) {
                if (flags() == Fallout2Dat.Compression.ZLIB) {
                }
            }
            _dirty = false;
        }
        private byte[] contents;
        public byte[] contents() {
            if (this.contents != null)
                return this.contents;
            if ( ((flags() == Fallout2Dat.Compression.ZLIB) || (flags() == Fallout2Dat.Compression.NONE)) ) {
                this.contents = (flags() == Fallout2Dat.Compression.ZLIB ? contentsZlib() : contentsRaw());
            }
            return this.contents;
        }
        public void _invalidateContents() { this.contents = null; }
        private byte[] contentsRaw;
        private boolean _shouldWriteContentsRaw = false;
        private boolean _enabledContentsRaw = true;
        public byte[] contentsRaw() {
            if (_shouldWriteContentsRaw)
                _writeContentsRaw();
            if (this.contentsRaw != null)
                return this.contentsRaw;
            if (!_enabledContentsRaw)
                return null;
            if (flags() == Fallout2Dat.Compression.NONE) {
                KaitaiStream io = _root()._io();
                long _pos = io.pos();
                io.seek(offset());
                this.contentsRaw = io.readBytes(sizeUnpacked());
                io.seek(_pos);
            }
            return this.contentsRaw;
        }
        public void setContentsRaw(byte[] _v) { _dirty = true; contentsRaw = _v; }
        public void setContentsRaw_Enabled(boolean _v) { _dirty = true; _enabledContentsRaw = _v; }

        private void _writeContentsRaw() {
            _shouldWriteContentsRaw = false;
            if (flags() == Fallout2Dat.Compression.NONE) {
                KaitaiStream io = _root()._io();
                long _pos = io.pos();
                io.seek(offset());
                io.writeBytes(this.contentsRaw);
                io.seek(_pos);
            }
        }
        private byte[] contentsZlib;
        private boolean _shouldWriteContentsZlib = false;
        private boolean _enabledContentsZlib = true;
        public byte[] contentsZlib() {
            if (_shouldWriteContentsZlib)
                _writeContentsZlib();
            if (this.contentsZlib != null)
                return this.contentsZlib;
            if (!_enabledContentsZlib)
                return null;
            if (flags() == Fallout2Dat.Compression.ZLIB) {
                KaitaiStream io = _root()._io();
                long _pos = io.pos();
                io.seek(offset());
                this._raw_contentsZlib = io.readBytes(sizePacked());
                this.contentsZlib = KaitaiStream.processZlib(this._raw_contentsZlib);
                io.seek(_pos);
            }
            return this.contentsZlib;
        }
        public void setContentsZlib(byte[] _v) { _dirty = true; contentsZlib = _v; }
        public void setContentsZlib_Enabled(boolean _v) { _dirty = true; _enabledContentsZlib = _v; }

        private void _writeContentsZlib() {
            _shouldWriteContentsZlib = false;
            if (flags() == Fallout2Dat.Compression.ZLIB) {
                KaitaiStream io = _root()._io();
                long _pos = io.pos();
                io.seek(offset());
                this._raw_contentsZlib = KaitaiStream.unprocessZlib(this.contentsZlib);
                if (this._raw_contentsZlib.length != sizePacked())
                    throw new ConsistencyError("contents_zlib", sizePacked(), this._raw_contentsZlib.length);
                io.writeBytes(this._raw_contentsZlib);
                io.seek(_pos);
            }
        }
        private Pstr name;
        private Compression flags;
        private long sizeUnpacked;
        private long sizePacked;
        private long offset;
        private Fallout2Dat _root;
        private Fallout2Dat.Index _parent;
        private byte[] _raw_contentsZlib;
        public Pstr name() { return name; }
        public void setName(Pstr _v) { _dirty = true; name = _v; }
        public Compression flags() { return flags; }
        public void setFlags(Compression _v) { _dirty = true; flags = _v; }
        public long sizeUnpacked() { return sizeUnpacked; }
        public void setSizeUnpacked(long _v) { _dirty = true; sizeUnpacked = _v; }
        public long sizePacked() { return sizePacked; }
        public void setSizePacked(long _v) { _dirty = true; sizePacked = _v; }
        public long offset() { return offset; }
        public void setOffset(long _v) { _dirty = true; offset = _v; }
        public Fallout2Dat _root() { return _root; }
        public void set_root(Fallout2Dat _v) { _dirty = true; _root = _v; }
        public Fallout2Dat.Index _parent() { return _parent; }
        public void set_parent(Fallout2Dat.Index _v) { _dirty = true; _parent = _v; }
        public byte[] _raw_contentsZlib() { return _raw_contentsZlib; }
        public void set_raw_ContentsZlib(byte[] _v) { _dirty = true; _raw_contentsZlib = _v; }
    }
    public static class Footer extends KaitaiStruct.ReadWrite {
        public static Footer fromFile(String fileName) throws IOException {
            return new Footer(new ByteBufferKaitaiStream(fileName));
        }
        public Footer() {
            this(null, null, null);
        }

        public Footer(KaitaiStream _io) {
            this(_io, null, null);
        }

        public Footer(KaitaiStream _io, Fallout2Dat _parent) {
            this(_io, _parent, null);
        }

        public Footer(KaitaiStream _io, Fallout2Dat _parent, Fallout2Dat _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
        }
        public void _read() {
            this.indexSize = this._io.readU4le();
            this.fileSize = this._io.readU4le();
            _dirty = false;
        }

        public void _fetchInstances() {
        }

        public void _write_Seq() {
            _assertNotDirty();
            this._io.writeU4le(this.indexSize);
            this._io.writeU4le(this.fileSize);
        }

        public void _check() {
            _dirty = false;
        }
        private long indexSize;
        private long fileSize;
        private Fallout2Dat _root;
        private Fallout2Dat _parent;
        public long indexSize() { return indexSize; }
        public void setIndexSize(long _v) { _dirty = true; indexSize = _v; }
        public long fileSize() { return fileSize; }
        public void setFileSize(long _v) { _dirty = true; fileSize = _v; }
        public Fallout2Dat _root() { return _root; }
        public void set_root(Fallout2Dat _v) { _dirty = true; _root = _v; }
        public Fallout2Dat _parent() { return _parent; }
        public void set_parent(Fallout2Dat _v) { _dirty = true; _parent = _v; }
    }
    public static class Index extends KaitaiStruct.ReadWrite {
        public static Index fromFile(String fileName) throws IOException {
            return new Index(new ByteBufferKaitaiStream(fileName));
        }
        public Index() {
            this(null, null, null);
        }

        public Index(KaitaiStream _io) {
            this(_io, null, null);
        }

        public Index(KaitaiStream _io, Fallout2Dat _parent) {
            this(_io, _parent, null);
        }

        public Index(KaitaiStream _io, Fallout2Dat _parent, Fallout2Dat _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
        }
        public void _read() {
            this.fileCount = this._io.readU4le();
            this.files = new ArrayList<File>();
            for (int i = 0; i < fileCount(); i++) {
                File _t_files = new File(this._io, this, _root);
                try {
                    _t_files._read();
                } finally {
                    this.files.add(_t_files);
                }
            }
            _dirty = false;
        }

        public void _fetchInstances() {
            for (int i = 0; i < this.files.size(); i++) {
                this.files.get(((Number) (i)).intValue())._fetchInstances();
            }
        }

        public void _write_Seq() {
            _assertNotDirty();
            this._io.writeU4le(this.fileCount);
            for (int i = 0; i < this.files.size(); i++) {
                this.files.get(((Number) (i)).intValue())._write_Seq(this._io);
            }
        }

        public void _check() {
            if (this.files.size() != fileCount())
                throw new ConsistencyError("files", fileCount(), this.files.size());
            for (int i = 0; i < this.files.size(); i++) {
                if (!Objects.equals(this.files.get(((Number) (i)).intValue())._root(), _root()))
                    throw new ConsistencyError("files", _root(), this.files.get(((Number) (i)).intValue())._root());
                if (!Objects.equals(this.files.get(((Number) (i)).intValue())._parent(), this))
                    throw new ConsistencyError("files", this, this.files.get(((Number) (i)).intValue())._parent());
            }
            _dirty = false;
        }
        private long fileCount;
        private List<File> files;
        private Fallout2Dat _root;
        private Fallout2Dat _parent;
        public long fileCount() { return fileCount; }
        public void setFileCount(long _v) { _dirty = true; fileCount = _v; }
        public List<File> files() { return files; }
        public void setFiles(List<File> _v) { _dirty = true; files = _v; }
        public Fallout2Dat _root() { return _root; }
        public void set_root(Fallout2Dat _v) { _dirty = true; _root = _v; }
        public Fallout2Dat _parent() { return _parent; }
        public void set_parent(Fallout2Dat _v) { _dirty = true; _parent = _v; }
    }
    public static class Pstr extends KaitaiStruct.ReadWrite {
        public static Pstr fromFile(String fileName) throws IOException {
            return new Pstr(new ByteBufferKaitaiStream(fileName));
        }
        public Pstr() {
            this(null, null, null);
        }

        public Pstr(KaitaiStream _io) {
            this(_io, null, null);
        }

        public Pstr(KaitaiStream _io, Fallout2Dat.File _parent) {
            this(_io, _parent, null);
        }

        public Pstr(KaitaiStream _io, Fallout2Dat.File _parent, Fallout2Dat _root) {
            super(_io);
            this._parent = _parent;
            this._root = _root;
        }
        public void _read() {
            this.size = this._io.readU4le();
            this.str = new String(this._io.readBytes(size()), StandardCharsets.US_ASCII);
            _dirty = false;
        }

        public void _fetchInstances() {
        }

        public void _write_Seq() {
            _assertNotDirty();
            this._io.writeU4le(this.size);
            this._io.writeBytes((this.str).getBytes(Charset.forName("ASCII")));
        }

        public void _check() {
            if ((this.str).getBytes(Charset.forName("ASCII")).length != size())
                throw new ConsistencyError("str", size(), (this.str).getBytes(Charset.forName("ASCII")).length);
            _dirty = false;
        }
        private long size;
        private String str;
        private Fallout2Dat _root;
        private Fallout2Dat.File _parent;
        public long size() { return size; }
        public void setSize(long _v) { _dirty = true; size = _v; }
        public String str() { return str; }
        public void setStr(String _v) { _dirty = true; str = _v; }
        public Fallout2Dat _root() { return _root; }
        public void set_root(Fallout2Dat _v) { _dirty = true; _root = _v; }
        public Fallout2Dat.File _parent() { return _parent; }
        public void set_parent(Fallout2Dat.File _v) { _dirty = true; _parent = _v; }
    }
    private Footer footer;
    private boolean _shouldWriteFooter = false;
    private boolean _enabledFooter = true;
    public Footer footer() {
        if (_shouldWriteFooter)
            _writeFooter();
        if (this.footer != null)
            return this.footer;
        if (!_enabledFooter)
            return null;
        long _pos = this._io.pos();
        this._io.seek(_io().size() - 8);
        this.footer = new Footer(this._io, this, _root);
        this.footer._read();
        this._io.seek(_pos);
        return this.footer;
    }
    public void setFooter(Footer _v) { _dirty = true; footer = _v; }
    public void setFooter_Enabled(boolean _v) { _dirty = true; _enabledFooter = _v; }

    private void _writeFooter() {
        _shouldWriteFooter = false;
        long _pos = this._io.pos();
        this._io.seek(_io().size() - 8);
        this.footer._write_Seq(this._io);
        this._io.seek(_pos);
    }
    private Index index;
    private boolean _shouldWriteIndex = false;
    private boolean _enabledIndex = true;
    public Index index() {
        if (_shouldWriteIndex)
            _writeIndex();
        if (this.index != null)
            return this.index;
        if (!_enabledIndex)
            return null;
        long _pos = this._io.pos();
        this._io.seek((_io().size() - 8) - footer().indexSize());
        this.index = new Index(this._io, this, _root);
        this.index._read();
        this._io.seek(_pos);
        return this.index;
    }
    public void setIndex(Index _v) { _dirty = true; index = _v; }
    public void setIndex_Enabled(boolean _v) { _dirty = true; _enabledIndex = _v; }

    private void _writeIndex() {
        _shouldWriteIndex = false;
        long _pos = this._io.pos();
        this._io.seek((_io().size() - 8) - footer().indexSize());
        this.index._write_Seq(this._io);
        this._io.seek(_pos);
    }
    private Fallout2Dat _root;
    private KaitaiStruct.ReadWrite _parent;
    public Fallout2Dat _root() { return _root; }
    public void set_root(Fallout2Dat _v) { _dirty = true; _root = _v; }
    public KaitaiStruct.ReadWrite _parent() { return _parent; }
    public void set_parent(KaitaiStruct.ReadWrite _v) { _dirty = true; _parent = _v; }
}