/**
     * Return a list of files in the packed data.
     */
    public IList <String> GetFileList()
    {
        var filenames = new List <String>();

        DirStream.Seek(0, SeekOrigin.Begin);

        for (int index = 0; index < GetNumFiles(); index++)
        {
            string filename = GetIndexFilename(index);

            for (int i = 0;; i++)
            {
                //Console.WriteLine(filename + (i==0 ? "*" : ""));
                filenames.Add(filename);

                if (i == GetNumFileParts(index) - 1)
                {
                    break;
                }

                filename = AddToFileIndex(filename, 1);
                if (filename == "")
                {
                    Console.WriteLine("ASSUMPTION BROKEN");
                    break;
                }
            }
        }

        return(filenames);
    }
    int GetNumFileParts(int index)
    {
        if (index == -1)
        {
            return(-1);
        }
        DirStream.Seek(index * 14 + 13, SeekOrigin.Begin);
        int b = DirStream.ReadByte();

        if ((b & 0x80) == 0)
        {
            return(1);
        }
        return(b & 0x7f);
    }
    /**
     * Get the compressed data of a file. (First 2 bytes are uncompressed size.)
     */
    public byte[] GetCompressedFileData(string filename, int part = 0)
    {
        /*
         * if (part == 0)
         *  Console.WriteLine(filename);
         */
        int index = GetFilenameIndex(filename);

        if (index == -1)
        {
            string newFilename = AddToFileIndex(filename, -1);
            if (newFilename != "")
            {
                try {
                    return(GetCompressedFileData(newFilename, part + 1));
                }
                catch (FileNotFoundException) {}
            }
            throw new FileNotFoundException("File \"" + filename + "\" not found.");
        }

        DirStream.Seek(index * 14 + 11, SeekOrigin.Begin);

        int indexOffset = DirStream.ReadByte() + (DirStream.ReadByte() << 8) + (DirStream.ReadByte() << 16);

        /*
         * if ((indexOffset & 1) != 0) {
         *  // This is normal for "type 2" data?
         *  Console.WriteLine("WARN: bit 0 of indexOffset is set");
         * }
         */

        if ((indexOffset & (1 << 23)) != 0)
        {
            indexOffset &= 0xFFFF;
            return(GetCompressedType2FileData(indexOffset, part));
        }
        else
        {
            indexOffset &= 0xFFFFFF;
            return(GetCompressedType1FileData(indexOffset));
        }
    }
    /**
     * Get the uncompressed data of a file.
     */
    public byte[] GetFileData(string filename, int part = 0)
    {
        LZSS.processingFile = filename;

        /*
         * if (part == 0)
         *  Console.WriteLine(filename);
         */
        int index = GetFilenameIndex(filename);

        if (index == -1)
        {
            string newFilename = AddToFileIndex(filename, -1);
            if (newFilename != "")
            {
                try {
                    return(GetFileData(newFilename, part + 1));
                }
                catch (FileNotFoundException) {}
            }
            throw new FileNotFoundException("File \"" + filename + "\" not found.");
        }

        DirStream.Seek(index * 14 + 11, SeekOrigin.Begin);

        int indexOffset = DirStream.ReadByte() + (DirStream.ReadByte() << 8) + (DirStream.ReadByte() << 16);

        if ((indexOffset & (1 << 23)) != 0)
        {
            indexOffset &= 0xFFFF;
            return(GetType2FileData(indexOffset, part));
        }
        else
        {
            indexOffset &= 0xFFFFFF;
            return(GetType1FileData(indexOffset));
        }
    }
    string GetIndexFilename(int index)
    {
        DirStream.Seek(index * 14, SeekOrigin.Begin);

        string filename = "";

        for (int i = 0; i < 8; i++)
        {
            int c = DirStream.ReadByte();
            if (c == -1)
            {
                break;
            }
            if (c != '\0')
            {
                filename += (char)c;
            }
        }

        string extension = "";

        for (int i = 0; i < 3; i++)
        {
            char c = (char)DirStream.ReadByte();
            if (c != '\0')
            {
                extension += c;
            }
        }
        if (extension.Length != 0)
        {
            filename += "." + extension;
        }

        return(filename);
    }
 /**
  * Get the number of files in the packed data.
  */
 public int GetNumFiles()
 {
     DirStream.Seek(0, SeekOrigin.Begin);
     return((int)(DirStream.Length / 14));
 }