Ejemplo n.º 1
0
        /// <summary>
        /// Creates an entry in the file table with the specified path.
        /// </summary>
        /// <param name="path">The complete path of the entry to add.</param>
        /// <param name="entryType">The type of entry to add.</param>
        public FileTableEntry CreateEntry(string path, EntryType entryType)
        {
            //if (path == @"levels\b30\decals-environment\bitmaps\decal fore symb blue b.bitmap")
            //  Debugger.Break();
            // Seperate the path into its different levels.
            string[] parts = path.Split('\\');

            // Locate the corresponsing node for each level of the path.
            // If a level does not exist, create it.
            FileTableEntry result = rootEntry;

            for (int x = 0; x < parts.Length; x++)
            {
                EntryType             currentType   = (x < parts.Length - 1) ? (EntryType.Folder) : entryType;
                List <FileTableEntry> searchResults = result.GetChildren(
                    new NameFilter(parts[x]), new EntryTypeFilter(currentType));
                if (searchResults.Count == 0)
                {
                    // We didn't find this level of the path, so create the node.
                    // Set it to the proper type if it is the last piece, otherwise it's a folder.
                    result = result.AddChild(parts[x], (x < parts.Length - 1) ? EntryType.Folder : entryType);

                    // Add to the table.
                    AddEntryToTable(result);
                }
                else
                {
                    result = searchResults[0];
                }
            }
            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adds a child entry with the specified name of the specified type.
        /// </summary>
        public FileTableEntry AddChild(string name, EntryType type)
        {
            // See if the entry already exists in this node's children
            if (ParentEntry != null)
            {
                List <FileTableEntry> entries = GetChildren(new NameFilter(name));
                if (entries.Count > 0)
                {
                    return(entries[0]);
                }
            }

            // Creat the new entry and assign it's values.
            FileTableEntry newNode = CreateEntry(type);

            newNode.ParentEntry = this;
            newNode.Name        = name;

            // If this is the first child of this entry, set the reference.
            if (ChildEntry == null)
            {
                ChildEntry = newNode;
            }
            else
            {
                // If not, set it up as a sibling to the existing child.
                ChildEntry.AddSibling(newNode);
            }
            return(newNode);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Locates and returns the entry that matches the specified criteria.
        /// Returns null if no matching entry is found.
        /// </summary>
        public FileTableEntry GetEntry(string path, EntryType type)
        {
            // If there's no path, return the root.
            if (path == "")
            {
                return(rootEntry);
            }

            // Split the string, and make sure that it has parts.
            string[] parts = path.Split('\\');
            if (parts.Length == 0)
            {
                return(null);
            }

            // Locate the entry.
            FileTableEntry result = rootEntry;

            for (int x = 0; x < parts.Length; x++)
            {
                List <FileTableEntry> results = result.GetChildren(new NameFilter(parts[x]),
                                                                   new EntryTypeFilter((x < (parts.Length - 1)) ? EntryType.Folder : type));
                if (results.Count < 1)
                {
                    result = null;
                    break;
                }
                result = results[0];
            }
            return(result != rootEntry ? result : null);
        }
Ejemplo n.º 4
0
 protected virtual void WriteData(FileTableEntry entry, byte[] data)
 {
     bw.BaseStream.Position = entry.DataOffset;
     bw.Write(Encoding.ASCII.GetBytes("_BIN"));
     bw.Write(entry.Offset);
     bw.Write(data);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Adds a file to the archive.
        /// </summary>
        public virtual void AddFile(string filename, byte[] buffer)
        {
            // See if the file already exists in the archive
            if (fileTable.GetEntry(filename, EntryType.File) == null)
            {
                uint offset = GetDataDescriptor(fileTable.NextEntryOffset);
                if (offset != FileTableEntry.NullOffset)
                {
                    if (offset <= fileTable.NextEntryOffset)
                    {
                        // We have reached the data area of the archive, and will need to move
                        // this entry's data to the end of the file, in order to make room
                        // for more entries in the filetable.
                        FileTableEntry moveMe = fileTable.GetEntry(offset);
                        byte[]         data   = ReadFile(moveMe);
                        moveMe.DataOffset = (uint)archiveFile.Length;
                        moveMe.Save(bw);
                        WriteData(moveMe, data);
                    }
                }

                FileTableEntry entry = fileTable.CreateEntry(filename, EntryType.File);
                AddFile(entry, buffer);
            }
        }
Ejemplo n.º 6
0
        public void RemoveEntry(string path, EntryType type)
        {
            FileTableEntry entry           = GetEntry(path, type);
            FileTableEntry parent          = entry.ParentEntry;
            FileTableEntry previousSibling = entry.PreviousSiblingEntry;
            FileTableEntry sibling         = entry.SiblingEntry;
            FileTableEntry child           = entry.ChildEntry;

            if (parent != null)
            {
                parent.ChildEntry = entry.FirstSiblingInChain;
                if (parent.ChildEntry == entry)
                {
                    parent.ChildEntry = null;
                }
                entry.FirstSiblingInChain.ParentEntry = parent;
                entry.FirstSiblingInChain.Save(diskWriter);
                parent.Save(diskWriter);
            }
            if (previousSibling != null)
            {
                previousSibling.SiblingEntry = sibling;
                previousSibling.Save(diskWriter);
            }
            if (sibling != null)
            {
                sibling.PreviousSiblingEntry = previousSibling;
                sibling.Save(diskWriter);
            }
            if (child != null)
            {
                child.ParentEntry = null;
                child.Save(diskWriter);
            }
        }
Ejemplo n.º 7
0
        protected void AddFile(FileTableEntry entry, byte[] buffer)
        {
            entry.DataSize = (uint)buffer.Length;

            // Set the offset to the end of the file.
            entry.DataOffset = (uint)archiveFile.Length;
            entry.Save(bw);
            WriteData(entry, buffer);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Adds a new sibling to the node.
 /// </summary>
 public void AddSibling(FileTableEntry newSibling)
 {
     // TODO: Verify that the sibling doesnt already exist.
     // (Do this the same way that AddChild does)
     if (SiblingEntry == null)
     {
         newSibling.PreviousSiblingEntry = this;
         SiblingEntry = newSibling;
     }
     else
     {
         SiblingEntry.AddSibling(newSibling);
     }
 }
Ejemplo n.º 9
0
        public virtual string[] GetFolderList(string path)
        {
            // Make sure that the path we are looking in exists.
            FileTableEntry folder = fileTable.GetEntry(path, EntryType.Folder);

            if (folder == null)
            {
                return(new string[0]);
            }

            // Get the results.
            List <FileTableEntry> entries = folder.GetChildren(new EntryTypeFilter(EntryType.Folder));

            return(FileTableEntry.EntriesToPaths(entries.ToArray()));
        }
Ejemplo n.º 10
0
        public virtual byte[] ReadFile(FileTableEntry entry)
        {
            if (entry.DataOffset == FileTableEntry.NullOffset)
            {
                throw new Exception("No data exists in the archive for entry " + entry.FullPath);
            }

            if (GetDataDescriptor(entry.DataOffset) != entry.Offset)
            {
                throw new Exception("Error reading data element for entry " + entry.FullPath);
            }

            br.BaseStream.Position = entry.DataOffset + 8;
            byte[] data = br.ReadBytes((int)entry.DataSize);
            return(data);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Writes the entry and all child entries to disk.
        /// </summary>
        protected void WriteEntries(FileTableEntry startEntry)
        {
            // Get a recursive list of all of the child folders that exist beneath this node.
            List <FileTableEntry> folderEntries = startEntry.GetChildren(true, new EntryTypeFilter(EntryType.Folder));

            foreach (FileTableEntry folderEntry in folderEntries)
            {
                // Write the folder entry.
                folderEntry.Save(diskWriter);

                // Write all of the direct child file entry nodes.
                foreach (FileTableEntry fileEntry in folderEntry.GetChildren(new EntryTypeFilter(EntryType.File)))
                {
                    fileEntry.Save(diskWriter);
                }
            }
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Adds the specified entry to the end of the filetable, and updates the heder values.
 /// </summary>
 protected void AddEntryToTable(FileTableEntry entry)
 {
     // Set the offset accordingly.
     entry.Offset          = NextEntryOffset;
     header.FileTableSize += (uint)entry.Size;
     header.FileEntryCount++;
     // Update the header and save the entry to disk.
     WriteHeader();
     entry.Save(diskWriter);
     if (entry.ParentEntry != null)
     {
         entry.ParentEntry.Save(diskWriter);
     }
     if (entry.PreviousSiblingEntry != null)
     {
         entry.PreviousSiblingEntry.Save(diskWriter);
     }
 }
Ejemplo n.º 13
0
        /// <summary>
        /// Returns a list of the entry's children that match the specified criteria.
        /// Optionally recursive.
        /// </summary>
        public List <FileTableEntry> GetChildren(bool recursive, params IEntryFilter[] filters)
        {
            List <FileTableEntry> entryList = new List <FileTableEntry>();
            FileTableEntry        child     = ChildEntry;

            while (child != null)
            {
                // Test the entry against all of the supplied filters.
                bool match = true;
                foreach (IEntryFilter filter in filters)
                {
                    if (!filter.Match(child))
                    {
                        match = false;
                        break;
                    }
                }

                // Add to the list of results if it matched every filter.
                if (match)
                {
                    entryList.Add(child);
                }

                // Test the entry's sibling next.
                child = child.SiblingEntry;
            }

            if (recursive)
            {
                // Get all of the items from any subfolders as well.
                List <FileTableEntry> folderList = GetChildren(new EntryTypeFilter(EntryType.Folder));
                foreach (FileTableEntry folder in folderList)
                {
                    entryList.AddRange(folder.GetChildren(true, filters));
                }
            }
            return(entryList);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Loads an entry, and all of it's referenced entries.
        /// </summary>
        protected void Load(BinaryReader reader, uint offset, FileTableEntry parentEntry,
                            FileTableEntry previousSiblingEntry)
        {
            if (offset != NullOffset)
            {
                reader.BaseStream.Position = offset;
                entryType  = (EntryType)reader.ReadByte();
                Offset     = offset;
                DataOffset = reader.ReadUInt32();
                DataSize   = reader.ReadUInt32();
                uint siblingOffset = reader.ReadUInt32();
                uint childOffset   = reader.ReadUInt32();
                ReadExtendedData(reader);
                Name = reader.ReadString();

                if (SiblingOffset < 16 || ChildOffset < 16)
                {
                    Debugger.Break();
                }

                // Load the referenced entries.
                ParentEntry          = parentEntry;
                PreviousSiblingEntry = previousSiblingEntry;

                if (siblingOffset != NullOffset)
                {
                    SiblingEntry = CreateEntry(EntryType.Folder);
                    SiblingEntry.Load(reader, siblingOffset, parentEntry);
                }

                if (childOffset != NullOffset)
                {
                    ChildEntry = CreateEntry(EntryType.Folder);
                    ChildEntry.Load(reader, childOffset, this);
                }
            }
        }
Ejemplo n.º 15
0
 public void Load(BinaryReader reader, uint offset, FileTableEntry parentEntry)
 {
     Load(reader, offset, parentEntry, null);
 }
Ejemplo n.º 16
0
        public byte[] ReadFile(string filename)
        {
            FileTableEntry entry = fileTable.GetEntry(filename, EntryType.File);

            return(ReadFile(entry));
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Creates the root file entry node.
 /// Override this method to create a root entry of a different type.
 /// </summary>
 protected virtual void CreateRootEntry()
 {
     rootEntry = new FileTableEntry(EntryType.Folder);
 }