/// <summary>Writes a request header body This implementation is slightly more efficient than the generated code /// because it avoids the allocation of a string[] to write the location.</summary> internal static void WriteIce2RequestHeaderBody( this OutputStream ostr, Identity identity, string facet, IReadOnlyList <string> location, string operation, bool idempotent, DateTime deadline, IReadOnlyDictionary <string, string> context) { Debug.Assert(ostr.Encoding == Encoding); // All bits are set to true by default, and true means the corresponding value is set. BitSequence bitSequence = ostr.WriteBitSequence(5); identity.IceWrite(ostr); if (facet.Length > 0) { ostr.WriteString(facet); } else { bitSequence[0] = false; } if (location.Count > 0) { ostr.WriteSequence(location, OutputStream.IceWriterFromString); } else { bitSequence[1] = false; } ostr.WriteString(operation); if (idempotent) { ostr.WriteBool(true); } else { bitSequence[2] = false; } bitSequence[3] = false; // TODO: source for priority. // DateTime.MaxValue represents an infinite deadline and it is encoded as -1 ostr.WriteVarLong( deadline == DateTime.MaxValue ? -1 : (long)(deadline - DateTime.UnixEpoch).TotalMilliseconds); if (context.Count > 0) { ostr.WriteDictionary(context, OutputStream.IceWriterFromString, OutputStream.IceWriterFromString); } else { bitSequence[4] = false; } }
internal override async ValueTask SendAsync( long streamId, OutgoingFrame frame, bool fin, CancellationToken cancel) { var data = new List <ArraySegment <byte> >(); var ostr = new OutputStream(Encoding, data); FrameType frameType = fin ? FrameType.StreamLast : FrameType.Stream; ostr.WriteByte((byte)frameType); OutputStream.Position sizePos = ostr.StartFixedLengthSize(4); ostr.WriteVarLong(streamId); OutputStream.Position ice2HeaderPos = ostr.Tail; if (frame is OutgoingRequestFrame requestFrame) { ostr.WriteByte((byte)Ice2Definitions.FrameType.Request); } else if (frame is OutgoingResponseFrame responseFrame) { ostr.WriteByte((byte)Ice2Definitions.FrameType.Response); } else { Debug.Assert(false); return; } ostr.WriteSize(frame.Size); int ice2HeaderSize = ostr.Tail.Offset - ice2HeaderPos.Offset; data[^ 1] = data[^ 1].Slice(0, ostr.Tail.Offset); // TODO: Shouldn't this be the job of ostr.Finish()?