Example #1
0
        public ArchiveDirectory CreateDirectories(string dirPath)
        {
            ArchiveDirectory dir = null;

            foreach (string dirName in dirPath.Split('/'))
            {
                var data = (dir == null) ? Data : dir.Data;
                if (data.Exists(t => t.Name == dirName))
                {
                    dir = data.Find(t => t.Name == dirName) as ArchiveDirectory;
                }
                else if (dir == null)
                {
                    var directory = new ArchiveDirectory(dirName);
                    Data.Add(directory);
                    dir = directory;
                }
                else
                {
                    var newDirectory = new ArchiveDirectory(dirName);
                    dir.Data.Add(newDirectory);
                    newDirectory.Parent = dir;
                    dir = newDirectory;
                }
            }
            return(dir);
        }
Example #2
0
        public override void Load(Stream fileStream)
        {
            // Header
            var reader  = new ExtendedBinaryReader(fileStream, true);
            var entries = new List <FileEntry>();

            uint sig = reader.ReadUInt32();

            if (sig != Signature)
            {
                throw new InvalidSignatureException(
                          Signature.ToString("X"), sig.ToString("X"));
            }

            uint fileTableOffset = reader.ReadUInt32();
            uint fileTableLength = reader.ReadUInt32();
            uint fileDataOffset  = reader.ReadUInt32();
            uint unknown5        = reader.ReadUInt32();
            uint unknown6        = reader.ReadUInt32();
            uint unknown7        = reader.ReadUInt32();
            uint unknown8        = reader.ReadUInt32();

            // File/Directory Entries
            long fileTableEnd = (fileTableOffset + fileTableLength);

            reader.JumpTo(fileTableOffset);

            while (fileStream.Position < fileTableEnd)
            {
                bool isDirectory = reader.ReadBoolean();
                byte padding1    = reader.ReadByte();

                if (padding1 != 0)
                {
                    fileStream.Position -= 2; // go bacc
                    break;
                }

                var fileEntry = new FileEntry()
                {
                    IsDirectory          = isDirectory,
                    FileNameOffset       = reader.ReadUInt16(),
                    DataOffset           = reader.ReadUInt32(),
                    DataLength           = reader.ReadUInt32(),
                    DataUncompressedSize = reader.ReadUInt32()
                };

                entries.Add(fileEntry);
            }

            // Entry Names
            uint fileNamesOffset = (uint)fileStream.Position;

            foreach (var entry in entries)
            {
                reader.JumpTo(fileNamesOffset + entry.FileNameOffset);
                entry.Name = reader.ReadNullTerminatedString();
            }

            // Entry Data
            ArchiveDirectory dir = null;

            for (int i = 0; i < entries.Count; ++i)
            {
                var entry = entries[i];

                // Directory
                if (entry.IsDirectory)
                {
                    // Generate a HedgeLib directory entry
                    if (i == 0)
                    {
                        continue;
                    }

                    if (entry.DataOffset >= i)
                    {
                        throw new Exception("Entry DataOffset is invalid");
                    }

                    var dirEntry = new ArchiveDirectory(entry.Name);
                    if (entry.DataOffset != 0)
                    {
                        var parentEntry = entries[(int)entry.DataOffset];
                        dirEntry.Parent = parentEntry.Directory;
                    }

                    if (dirEntry.Parent == null)
                    {
                        Data.Add(dirEntry);
                    }
                    else
                    {
                        dirEntry.Parent.Data.Add(dirEntry);
                    }

                    dir = entry.Directory = dirEntry;
                }

                // File
                else
                {
                    if (dir == null)
                    {
                        throw new Exception("Tried to read a file not in a directory!");
                    }

                    var data = new byte[entry.DataUncompressedSize];
                    int offset = 0, size = (int)entry.DataUncompressedSize;
                    reader.JumpTo(entry.DataOffset + 2);

                    using (var gzipStream = new DeflateStream(fileStream,
                                                              CompressionMode.Decompress, true))
                    {
                        while (offset < size)
                        {
                            offset += gzipStream.Read(data,
                                                      offset, (size - offset));
                        }
                    }

                    // Generate a HedgeLib file entry
                    dir.Data.Add(new ArchiveFile(entry.Name, data));
                }
            }
        }