public void Save(Stream stream)
        {
            using (var writer = new EndianBinaryWriter(stream, Encoding.Default, true, Endianness.BigEndian))
            {
                var fixups = new List <Tuple <long, Action> >();
                writer.Write(( long )mEntryMap.Count);

                foreach (var entry in mEntryMap.Values.OrderBy(x => x.Handle))
                {
                    fixups.Add(new Tuple <long, Action>(writer.BaseStream.Position, () =>
                    {
                        entry.GetStream().FullyCopyTo(writer.BaseStream);

                        var padBytes = AlignmentUtils.GetAlignedDifference(writer.BaseStream.Position, 4);

                        for (int i = 0; i < padBytes; i++)
                        {
                            writer.Write(( byte )0);
                        }
                    }));
                    writer.Write(( int )0);
                    writer.Write(entry.Length);
                }

                foreach (var fixup in fixups)
                {
                    var offset = writer.BaseStream.Position;
                    fixup.Item2();
                    var nextOffset = writer.BaseStream.Position;
                    writer.BaseStream.Seek(fixup.Item1, SeekOrigin.Begin);
                    writer.Write((int)offset);
                    writer.BaseStream.Seek(nextOffset, SeekOrigin.Begin);
                }
            }
        }
Пример #2
0
        public void Save(Stream stream)
        {
            using (var writer = new EndianBinaryWriter(stream, Encoding.Default, true, IsBigEndian ? Endianness.BigEndian : Endianness.LittleEndian))
            {
                if (Version == FormatVersion.Version2 || Version == FormatVersion.Version2BE || Version == FormatVersion.Version3 || Version == FormatVersion.Version3BE)
                {
                    writer.Write(mEntryMap.Count);
                }

                int nameLength;
                switch (Version)
                {
                case FormatVersion.Version1:
                    nameLength = 252;
                    break;

                case FormatVersion.Version2:
                case FormatVersion.Version2BE:
                    nameLength = 32;
                    break;

                case FormatVersion.Version3:
                case FormatVersion.Version3BE:
                    nameLength = 24;
                    break;

                default:
                    throw new NotImplementedException("Invalid format version");
                }

                foreach (var entry in mEntryMap.Values)
                {
                    // write entry name
                    for (int j = 0; j < nameLength; j++)
                    {
                        byte b = 0;
                        if (j < entry.FileName.Length)
                        {
                            b = ( byte )entry.FileName[j];
                        }

                        writer.Write(b);
                    }

                    var entryLength      = entry.Length;
                    var paddingByteCount = 0;

                    if (Version != FormatVersion.Version1)
                    {
                        paddingByteCount = AlignmentUtils.GetAlignedDifference(entry.Length, 32);
                        entryLength     += paddingByteCount;
                    }

                    // write entry length
                    writer.Write(entryLength);

                    // write data
                    var dataStream = entry.GetStream();
                    dataStream.FullyCopyTo(writer.BaseStream);

                    switch (Version)
                    {
                    case FormatVersion.Version1:
                    {
                        paddingByteCount = AlignmentUtils.GetAlignedDifference(writer.BaseStream.Position, 64);
                        for (int i = 0; i < paddingByteCount; i++)
                        {
                            writer.Write(( byte )0);
                        }
                    }
                    break;

                    case FormatVersion.Version2:
                    case FormatVersion.Version2BE:
                    case FormatVersion.Version3:
                    case FormatVersion.Version3BE:
                    {
                        for (int i = 0; i < paddingByteCount; i++)
                        {
                            writer.Write(( byte )0);
                        }
                    }
                    break;

                    default:
                        throw new NotImplementedException("Invalid format version");
                    }
                }

                if (Version == FormatVersion.Version1)
                {
                    for (int i = 0; i < 256; i++)
                    {
                        writer.Write(( byte )0);
                    }
                }
            }
        }