Beispiel #1
0
        public async Task <FastcgiPacket> WriteToAsync(Stream ClientStream)
        {
            if (Content.Count > ushort.MaxValue)
            {
                throw(new InvalidDataException("Data too long"));
            }
            var ContentLength = (ushort)Content.Count;
            var PaddingLength = (byte)(MathUtils.Align(ContentLength, 8) - ContentLength);

            var Header = new byte[8];

            Header[0] = Version;
            Header[1] = (byte)Type;
            Header[2] = (byte)((RequestId >> 8) & 0xFF);
            Header[3] = (byte)((RequestId >> 0) & 0xFF);
            Header[4] = (byte)((ContentLength >> 8) & 0xFF);
            Header[5] = (byte)((ContentLength >> 0) & 0xFF);
            Header[6] = PaddingLength;
            Header[7] = 0;
            await ClientStream.WriteAsync(Header, 0, Header.Length);

            if (ContentLength > 0)
            {
                await ClientStream.WriteAsync(Content.Array, Content.Offset, Content.Count);
            }
            if (PaddingLength > 0)
            {
                await ClientStream.WriteAsync(PaddingWrite, 0, PaddingLength);
            }

            //await Console.Out.WriteLineAsync(String.Format("WRITE: Packet({0}): {1}({2}:{3})", RequestId, Type, ContentLength, PaddingLength));

            return(this);
        }
Beispiel #2
0
        public override void SaveTo(Stream Stream, bool DoAlign = true)
        {
            var EntryListWithLinks    = EntryList.Union(new Entry[] { new Entry(FPS4: this, Stream: new MemoryStream(), Name: "") }).ToArray();
            var EntryListWithoutLinks = EntryListWithLinks.Where(Entry => !Entry.IsLinked).ToArray();

            var  SectorPadding         = DoAlign ? 0x800 : 0x10;
            var  BinaryWriter          = new BinaryWriter(Stream);
            var  OriginalFilePathBytes = Encoding.GetEncoding("Shift-JIS").GetBytes(OriginalFilePath);
            long NamesStartOffset      = Header.ListStart + Header.EntrySizeof * EntryListWithLinks.Length + OriginalFilePathBytes.Length;
            long DataStartOffset       = NamesStartOffset;

            // Strings at the end of the entry list.
            if ((int)Header.EntryFormat == 0x47)
            {
                foreach (var Entry in EntryListWithLinks)
                {
                    DataStartOffset += Encoding.UTF8.GetByteCount(Entry.Name) + 1;
                }
            }

            DataStartOffset = MathUtils.Align(DataStartOffset, SectorPadding);

            Header.Magic     = Encoding.ASCII.GetBytes("FPS4");
            Header.ListCount = (uint)EntryListWithLinks.Length;
            Header.ListStart = (uint)Marshal.SizeOf(typeof(HeaderStruct));
            Header.ListEnd   = (uint)(DataStartOffset);
            var ExtraEntrySizeof = Header.EntrySizeof - 0x0C;

            Stream.WriteStruct(Header);
            long CurrentOffset = DataStartOffset;

            // PASS1. First we calculate all the pointers for non-linked entries.
            foreach (var Entry in EntryListWithoutLinks)
            {
                var LengthReal          = Entry.Length;
                var LengthSectorAligned = (uint)MathUtils.NextAligned((long)LengthReal, (long)SectorPadding);

                Entry.EntryStruct = new EntryStruct()
                {
                    Offset = (uint)CurrentOffset,
                    LengthSectorAligned = (uint)LengthSectorAligned,
                    LengthReal          = (uint)LengthReal,
                };

                CurrentOffset += LengthSectorAligned;
            }

            var EndStringNames = new MemoryStream();

            // PASS2. We then write all the EntryListWithLinks.
            foreach (var Entry in EntryListWithLinks)
            {
                Stream.WriteStruct(Entry.LinkedEntryStruct);

                switch (ExtraEntrySizeof)
                {
                case 0:
                    break;

                case 4:
                    // Pointer to string name.

                    /*
                     * if (Offset != 0)
                     * {
                     *      throw (new NotImplementedException());
                     * }
                     * //var Offset = BinaryReader.ReadUInt32();
                     */
                    int NameIndex = -1;
                    if (!int.TryParse(Entry.Name, out NameIndex))
                    {
                        NameIndex = -1;
                    }

                    if ((Entry.Name == "") || (Entry.Index == NameIndex))
                    {
                        Stream.WriteStruct((uint_be)(uint)(0));
                        //Console.Error.WriteLine("Zero '{0}' : {1} : {2}", Entry.Name, Entry.Index, NameIndex);
                    }
                    else
                    {
                        Stream.WriteStruct((uint_be)(uint)(NamesStartOffset + EndStringNames.Length));
                        EndStringNames.WriteStringz(Entry.Name);
                        //Console.Error.WriteLine("Problem?");
                        //throw (new NotImplementedException());
                    }
                    break;

                default:
                    Console.WriteLine("{0}", Entry.Name);
                    Stream.WriteStringz(Entry.Name, ExtraEntrySizeof);
                    break;
                }
            }

            Stream.WriteBytes(OriginalFilePathBytes);
            Stream.WriteZeroToOffset(DataStartOffset);

            // PASS3: Write Names
            if ((int)Header.EntryFormat == 0x47)
            {
                //Console.WriteLine("PASS3: Write Names");
                Stream.SliceWithBounds(NamesStartOffset, DataStartOffset).WriteStream(EndStringNames.Slice());
            }

            foreach (var Entry in EntryListWithoutLinks)
            {
                Entry.Open().CopyToFast(Stream);
                Stream.WriteZeroToAlign(SectorPadding);
            }

            Stream.Flush();

            //throw new NotImplementedException();
        }
Beispiel #3
0
 public static Stream Align(this Stream Stream, int Align)
 {
     Stream.Position = MathUtils.Align(Stream.Position, Align);
     return(Stream);
 }
Beispiel #4
0
 static public Stream WriteZeroToAlign(this Stream Stream, int Align)
 {
     Stream.WriteZeroBytes((int)(MathUtils.Align(Stream.Position, Align) - Stream.Position));
     return(Stream);
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="stream"></param>
 /// <param name="align"></param>
 /// <returns></returns>
 public static Stream Align(this Stream stream, int align)
 {
     stream.Position = MathUtils.Align(stream.Position, align);
     return(stream);
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="stream"></param>
 /// <param name="align"></param>
 /// <returns></returns>
 public static Stream WriteZeroToAlign(this Stream stream, int align)
 {
     stream.WriteZeroBytes((int)(MathUtils.Align(stream.Position, align) - stream.Position));
     return(stream);
 }