/// <summary> /// Initializes a new <see cref="FileEntry"/> instance using the supplied <see cref="ENTRY"/> object. /// </summary> /// <param name="entry">The entry object.</param> internal FileEntry(ENTRY entry) { filename = string.Empty; offset = (int)entry.Offset; length = (int)entry.Length; created = entry.Created.Ticks; modified = entry.Modified.Ticks; accessed = entry.Accessed.Ticks; data = new byte[0]; }
/// <summary> /// Saves this Abide Update package file to the specified stream. /// </summary> /// <param name="outStream">The stream where the package will be saved.</param> /// <exception cref="ArgumentNullException"><paramref name="outStream"/> is null.</exception> /// <exception cref="ArgumentException"><paramref name="outStream"/> does not support seeking.</exception> /// <exception cref="AbideUpdatePackageException">A write error occured.</exception> public void Save(Stream outStream) { //Setup Header header.AupTag = AupFourCc; header.EntryCount = (uint)fileEntries.Count; //Prepare ENTRY[] entries = new ENTRY[header.EntryCount]; byte[] data = null; uint length = 0; //Compress and copy data... using (MemoryStream ms = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(ms)) { //Loop through entries for (int i = 0; i < header.EntryCount; i++) { //Get Data... data = fileEntries[i].Data; //Check... if (data != null) { //Setup entries[i] = new ENTRY(); entries[i].Length = (uint)data.Length; entries[i].Offset = (uint)ms.Position; entries[i].Created = fileEntries[i].Created; entries[i].Modified = fileEntries[i].Modified; entries[i].Accessed = fileEntries[i].Accessed; //Write writer.Write(data); //Increment length += (uint)data.Length; } else { throw new ArgumentNullException("data"); } } //Copy data = new byte[length]; Array.Copy(ms.GetBuffer(), 0, data, 0, data.Length); } //Create Writer using (BinaryWriter writer = new BinaryWriter(outStream)) { //Goto entries start... outStream.Seek(HEADER.RuntimeSize, SeekOrigin.Begin); //Get File index offset... header.FileIndexOffset = (uint)outStream.Seek(ENTRY.RuntimeSize * entries.Length, SeekOrigin.Current); //Get File names offset... header.FileNamesOffset = (uint)outStream.Seek(header.EntryCount * 4L, SeekOrigin.Current); //Write File Names foreach (string filename in fileEntries.Select(e => e.Filename)) { writer.WriteUTF8NullTerminated(filename); } //Get Data Offset header.DataOffset = (uint)outStream.Position; //Write Files Index int offset = 0; outStream.Seek(header.FileIndexOffset, SeekOrigin.Begin); foreach (string filename in fileEntries.Select(e => e.Filename)) { writer.Write(offset); offset += filename.Length + 1; } //Setup File Length header.Length = header.DataOffset + (uint)data.Length; //Write Header outStream.Seek(0, SeekOrigin.Begin); writer.Write(header); //Write Entries foreach (ENTRY entry in entries) { writer.Write(entry); } //Write Data outStream.Seek(header.DataOffset, SeekOrigin.Begin); writer.Write(data); } }