.dat file format of Fallout: Go parsing library

Application

Fallout

File extension

dat

KS implementation details

License: CC0-1.0

References

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

Go source code to parse .dat file format of Fallout

fallout_dat.go

// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.

import (
	"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
	"io"
)


type FalloutDat_Compression int
const (
	FalloutDat_Compression__None FalloutDat_Compression = 32
	FalloutDat_Compression__Lzss FalloutDat_Compression = 64
)
type FalloutDat struct {
	FolderCount uint32
	Unknown1 uint32
	Unknown2 uint32
	Timestamp uint32
	FolderNames []*FalloutDat_Pstr
	Folders []*FalloutDat_Folder
	_io *kaitai.Stream
	_root *FalloutDat
	_parent interface{}
}
func NewFalloutDat() *FalloutDat {
	return &FalloutDat{
	}
}

func (this *FalloutDat) Read(io *kaitai.Stream, parent interface{}, root *FalloutDat) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp1, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.FolderCount = uint32(tmp1)
	tmp2, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Unknown1 = uint32(tmp2)
	tmp3, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Unknown2 = uint32(tmp3)
	tmp4, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Timestamp = uint32(tmp4)
	for i := 0; i < int(this.FolderCount); i++ {
		_ = i
		tmp5 := NewFalloutDat_Pstr()
		err = tmp5.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.FolderNames = append(this.FolderNames, tmp5)
	}
	for i := 0; i < int(this.FolderCount); i++ {
		_ = i
		tmp6 := NewFalloutDat_Folder()
		err = tmp6.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Folders = append(this.Folders, tmp6)
	}
	return err
}
type FalloutDat_Pstr struct {
	Size uint8
	Str string
	_io *kaitai.Stream
	_root *FalloutDat
	_parent interface{}
}
func NewFalloutDat_Pstr() *FalloutDat_Pstr {
	return &FalloutDat_Pstr{
	}
}

func (this *FalloutDat_Pstr) Read(io *kaitai.Stream, parent interface{}, root *FalloutDat) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp7, err := this._io.ReadU1()
	if err != nil {
		return err
	}
	this.Size = tmp7
	tmp8, err := this._io.ReadBytes(int(this.Size))
	if err != nil {
		return err
	}
	tmp8 = tmp8
	this.Str = string(tmp8)
	return err
}
type FalloutDat_Folder struct {
	FileCount uint32
	Unknown uint32
	Flags uint32
	Timestamp uint32
	Files []*FalloutDat_File
	_io *kaitai.Stream
	_root *FalloutDat
	_parent *FalloutDat
}
func NewFalloutDat_Folder() *FalloutDat_Folder {
	return &FalloutDat_Folder{
	}
}

func (this *FalloutDat_Folder) Read(io *kaitai.Stream, parent *FalloutDat, root *FalloutDat) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp9, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.FileCount = uint32(tmp9)
	tmp10, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Unknown = uint32(tmp10)
	tmp11, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Flags = uint32(tmp11)
	tmp12, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Timestamp = uint32(tmp12)
	for i := 0; i < int(this.FileCount); i++ {
		_ = i
		tmp13 := NewFalloutDat_File()
		err = tmp13.Read(this._io, this, this._root)
		if err != nil {
			return err
		}
		this.Files = append(this.Files, tmp13)
	}
	return err
}
type FalloutDat_File struct {
	Name *FalloutDat_Pstr
	Flags FalloutDat_Compression
	Offset uint32
	SizeUnpacked uint32
	SizePacked uint32
	_io *kaitai.Stream
	_root *FalloutDat
	_parent *FalloutDat_Folder
	_f_contents bool
	contents []byte
}
func NewFalloutDat_File() *FalloutDat_File {
	return &FalloutDat_File{
	}
}

func (this *FalloutDat_File) Read(io *kaitai.Stream, parent *FalloutDat_Folder, root *FalloutDat) (err error) {
	this._io = io
	this._parent = parent
	this._root = root

	tmp14 := NewFalloutDat_Pstr()
	err = tmp14.Read(this._io, this, this._root)
	if err != nil {
		return err
	}
	this.Name = tmp14
	tmp15, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Flags = FalloutDat_Compression(tmp15)
	tmp16, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.Offset = uint32(tmp16)
	tmp17, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.SizeUnpacked = uint32(tmp17)
	tmp18, err := this._io.ReadU4be()
	if err != nil {
		return err
	}
	this.SizePacked = uint32(tmp18)
	return err
}
func (this *FalloutDat_File) Contents() (v []byte, err error) {
	if (this._f_contents) {
		return this.contents, nil
	}
	thisIo := this._root._io
	_pos, err := thisIo.Pos()
	if err != nil {
		return nil, err
	}
	_, err = thisIo.Seek(int64(this.Offset), io.SeekStart)
	if err != nil {
		return nil, err
	}
	var tmp19 uint32;
	if (this.Flags == FalloutDat_Compression__None) {
		tmp19 = this.SizeUnpacked
	} else {
		tmp19 = this.SizePacked
	}
	tmp20, err := thisIo.ReadBytes(int(tmp19))
	if err != nil {
		return nil, err
	}
	tmp20 = tmp20
	this.contents = tmp20
	_, err = thisIo.Seek(_pos, io.SeekStart)
	if err != nil {
		return nil, err
	}
	this._f_contents = true
	this._f_contents = true
	return this.contents, nil
}