Gran Turismo File System (GTFS): C# parsing library

File extension

vol

KS implementation details

License: CC0-1.0

References

This page hosts a formal specification of Gran Turismo File System (GTFS) using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

Runtime library

All parsing code for C# generated by Kaitai Struct depends on the C# runtime library. You have to install it before you can parse data.

The C# runtime library is available in the NuGet Gallery. Installation instructions can also be found there.

Code

Parse a local file and get structure in memory:

var data = GranTurismoVol.FromFile("path/to/local/file.vol");

Or parse structure from a byte array:

byte[] someArray = new byte[] { ... };
var data = new GranTurismoVol(new KaitaiStream(someArray));

After that, one can get various attributes from the structure by accessing properties like:

data.Magic // => get magic

C# source code to parse Gran Turismo File System (GTFS)

GranTurismoVol.cs

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

using System.Collections.Generic;

namespace Kaitai
{
    public partial class GranTurismoVol : KaitaiStruct
    {
        public static GranTurismoVol FromFile(string fileName)
        {
            return new GranTurismoVol(new KaitaiStream(fileName));
        }

        public GranTurismoVol(KaitaiStream p__io, KaitaiStruct p__parent = null, GranTurismoVol p__root = null) : base(p__io)
        {
            m_parent = p__parent;
            m_root = p__root ?? this;
            f_ofsDir = false;
            f_files = false;
            _read();
        }
        private void _read()
        {
            _magic = m_io.ReadBytes(8);
            if (!((KaitaiStream.ByteArrayCompare(Magic, new byte[] { 71, 84, 70, 83, 0, 0, 0, 0 }) == 0)))
            {
                throw new ValidationNotEqualError(new byte[] { 71, 84, 70, 83, 0, 0, 0, 0 }, Magic, M_Io, "/seq/0");
            }
            _numFiles = m_io.ReadU2le();
            _numEntries = m_io.ReadU2le();
            _reserved = m_io.ReadBytes(4);
            if (!((KaitaiStream.ByteArrayCompare(Reserved, new byte[] { 0, 0, 0, 0 }) == 0)))
            {
                throw new ValidationNotEqualError(new byte[] { 0, 0, 0, 0 }, Reserved, M_Io, "/seq/3");
            }
            _offsets = new List<uint>();
            for (var i = 0; i < NumFiles; i++)
            {
                _offsets.Add(m_io.ReadU4le());
            }
        }
        public partial class FileInfo : KaitaiStruct
        {
            public static FileInfo FromFile(string fileName)
            {
                return new FileInfo(new KaitaiStream(fileName));
            }

            public FileInfo(KaitaiStream p__io, GranTurismoVol p__parent = null, GranTurismoVol p__root = null) : base(p__io)
            {
                m_parent = p__parent;
                m_root = p__root;
                f_size = false;
                f_body = false;
                f_isDir = false;
                f_isLastEntry = false;
                _read();
            }
            private void _read()
            {
                _timestamp = m_io.ReadU4le();
                _offsetIdx = m_io.ReadU2le();
                _flags = m_io.ReadU1();
                _name = System.Text.Encoding.GetEncoding("ASCII").GetString(KaitaiStream.BytesTerminate(KaitaiStream.BytesStripRight(m_io.ReadBytes(25), 0), 0, false));
            }
            private bool f_size;
            private int _size;
            public int Size
            {
                get
                {
                    if (f_size)
                        return _size;
                    _size = (int) (((M_Root.Offsets[(OffsetIdx + 1)] & 4294965248) - M_Root.Offsets[OffsetIdx]));
                    f_size = true;
                    return _size;
                }
            }
            private bool f_body;
            private byte[] _body;
            public byte[] Body
            {
                get
                {
                    if (f_body)
                        return _body;
                    if (!(IsDir)) {
                        long _pos = m_io.Pos;
                        m_io.Seek((M_Root.Offsets[OffsetIdx] & 4294965248));
                        _body = m_io.ReadBytes(Size);
                        m_io.Seek(_pos);
                        f_body = true;
                    }
                    return _body;
                }
            }
            private bool f_isDir;
            private bool _isDir;
            public bool IsDir
            {
                get
                {
                    if (f_isDir)
                        return _isDir;
                    _isDir = (bool) ((Flags & 1) != 0);
                    f_isDir = true;
                    return _isDir;
                }
            }
            private bool f_isLastEntry;
            private bool _isLastEntry;
            public bool IsLastEntry
            {
                get
                {
                    if (f_isLastEntry)
                        return _isLastEntry;
                    _isLastEntry = (bool) ((Flags & 128) != 0);
                    f_isLastEntry = true;
                    return _isLastEntry;
                }
            }
            private uint _timestamp;
            private ushort _offsetIdx;
            private byte _flags;
            private string _name;
            private GranTurismoVol m_root;
            private GranTurismoVol m_parent;
            public uint Timestamp { get { return _timestamp; } }
            public ushort OffsetIdx { get { return _offsetIdx; } }
            public byte Flags { get { return _flags; } }
            public string Name { get { return _name; } }
            public GranTurismoVol M_Root { get { return m_root; } }
            public GranTurismoVol M_Parent { get { return m_parent; } }
        }
        private bool f_ofsDir;
        private uint _ofsDir;
        public uint OfsDir
        {
            get
            {
                if (f_ofsDir)
                    return _ofsDir;
                _ofsDir = (uint) (Offsets[1]);
                f_ofsDir = true;
                return _ofsDir;
            }
        }
        private bool f_files;
        private List<FileInfo> _files;
        public List<FileInfo> Files
        {
            get
            {
                if (f_files)
                    return _files;
                long _pos = m_io.Pos;
                m_io.Seek((OfsDir & 4294965248));
                _files = new List<FileInfo>();
                for (var i = 0; i < M_Root.NumEntries; i++)
                {
                    _files.Add(new FileInfo(m_io, this, m_root));
                }
                m_io.Seek(_pos);
                f_files = true;
                return _files;
            }
        }
        private byte[] _magic;
        private ushort _numFiles;
        private ushort _numEntries;
        private byte[] _reserved;
        private List<uint> _offsets;
        private GranTurismoVol m_root;
        private KaitaiStruct m_parent;
        public byte[] Magic { get { return _magic; } }
        public ushort NumFiles { get { return _numFiles; } }
        public ushort NumEntries { get { return _numEntries; } }
        public byte[] Reserved { get { return _reserved; } }
        public List<uint> Offsets { get { return _offsets; } }
        public GranTurismoVol M_Root { get { return m_root; } }
        public KaitaiStruct M_Parent { get { return m_parent; } }
    }
}