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); }
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(); }
public static Stream Align(this Stream Stream, int Align) { Stream.Position = MathUtils.Align(Stream.Position, Align); return(Stream); }
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); }