internal static List <ArraySegment <byte> > GetResponseData(OutgoingResponseFrame frame, int requestId) { byte[] headerData = new byte[HeaderSize + 4]; ReplyHeader.CopyTo(headerData.AsSpan()); OutputStream.WriteInt(frame.Size + HeaderSize + 4, headerData.AsSpan(10, 4)); OutputStream.WriteInt(requestId, headerData.AsSpan(HeaderSize, 4)); var data = new List <ArraySegment <byte> >() { headerData }; data.AddRange(frame.Data); return(data); }
/// <summary>Creates a new outgoing response frame with an OK reply status and a return value.</summary> /// <param name="current">The Current object for the corresponding incoming request.</param> /// <param name="format">The format type used to marshal classes and exceptions, when this parameter is null /// the communicator's default format is used.</param> /// <param name="value">The return value to marshal.</param> /// <param name="writer">A delegate that must write the value to the frame.</param> /// <returns>A new OutgoingResponseFrame.</returns> public static OutgoingResponseFrame WithReturnValue <T>(Current current, FormatType?format, T value, OutputStreamWriter <T> writer) { var response = new OutgoingResponseFrame(current.Encoding); byte[] buffer = new byte[256]; buffer[0] = (byte)ReplyStatus.OK; response.Data.Add(buffer); var ostr = new OutputStream(response.Encoding, response.Data, new OutputStream.Position(0, 1), format ?? current.Adapter.Communicator.DefaultFormat); writer(ostr, value); ostr.Save(); response.Finish(); return(response); }
// TODO avoid copy payload (ToArray) creates a copy, that should be possible when // the frame has a single segment. public IncomingResponseFrame(Communicator communicator, OutgoingResponseFrame frame) : this(communicator, frame.Payload.ToArray()) { }
private async ValueTask InvokeAllAsync(Ice.OutputStream os, int requestId) { // The object adapter DirectCount was incremented by the caller and we are responsible to decrement it // upon completion. Ice.Instrumentation.IDispatchObserver?dispatchObserver = null; try { if (_traceLevels.Protocol >= 1) { FillInValue(os, new Ice.OutputStream.Position(0, 10), os.Size); if (requestId > 0) { FillInValue(os, new Ice.OutputStream.Position(0, Ice1Definitions.HeaderSize), requestId); } TraceUtil.TraceSend(os, _logger, _traceLevels); } // TODO Avoid copy OutputStream buffer var requestFrame = new Ice.InputStream(os.Communicator, os.Encoding, os.ToArray()); requestFrame.Pos = Ice1Definitions.RequestHeader.Length; int start = requestFrame.Pos; var current = new Ice.Current(requestId, requestFrame, _adapter); // Then notify and set dispatch observer, if any. Ice.Instrumentation.ICommunicatorObserver?communicatorObserver = _adapter.Communicator.Observer; if (communicatorObserver != null) { int encapsSize = requestFrame.GetEncapsulationSize(); dispatchObserver = communicatorObserver.GetDispatchObserver(current, requestFrame.Pos - start + encapsSize); dispatchObserver?.Attach(); } bool amd = true; try { Ice.IObject?servant = current.Adapter.Find(current.Id, current.Facet); if (servant == null) { amd = false; throw new Ice.ObjectNotExistException(current.Id, current.Facet, current.Operation); } ValueTask <Ice.OutputStream> vt = servant.DispatchAsync(requestFrame, current); amd = !vt.IsCompleted; if (requestId != 0) { Ice.OutputStream responseFrame = await vt.ConfigureAwait(false); dispatchObserver?.Reply(responseFrame.Size - Ice1Definitions.HeaderSize - 4); SendResponse(requestId, responseFrame, amd); } } catch (System.Exception ex) { if (requestId != 0) { Ice.RemoteException actualEx; if (ex is Ice.RemoteException remoteEx && !remoteEx.ConvertToUnhandled) { actualEx = remoteEx; } else { actualEx = new UnhandledException(current.Id, current.Facet, current.Operation, ex); } Incoming.ReportException(actualEx, dispatchObserver, current); var responseFrame = new Ice.OutgoingResponseFrame(current, actualEx); dispatchObserver?.Reply(responseFrame.Size - Ice1Definitions.HeaderSize - 4); SendResponse(requestId, responseFrame, amd); } } }