コード例 #1
0
        /// <summary>Constructs an incoming request frame.</summary>
        /// <param name="protocol">The Ice protocol.</param>
        /// <param name="data">The frame data as an array segment.</param>
        /// <param name="sizeMax">The maximum payload size, checked during decompression.</param>
        public IncomingRequestFrame(Protocol protocol, ArraySegment <byte> data, int sizeMax)
            : base(data, protocol, sizeMax)
        {
            var istr = new InputStream(Data, Protocol.GetEncoding());

            if (Protocol == Protocol.Ice1)
            {
                Identity     = new Identity(istr);
                Facet        = istr.ReadFacet11();
                Location     = Array.Empty <string>();
                Operation    = istr.ReadString();
                IsIdempotent = istr.ReadOperationMode() != OperationMode.Normal;
                Context      = istr.ReadDictionary(minKeySize: 1,
                                                   minValueSize: 1,
                                                   InputStream.IceReaderIntoString,
                                                   InputStream.IceReaderIntoString);
                Priority = default;
            }
            else
            {
                var requestHeader = new Ice2RequestHeader(istr);
                Identity     = requestHeader.Identity;
                Facet        = requestHeader.Facet ?? "";
                Location     = requestHeader.Location ?? Array.Empty <string>();
                Operation    = requestHeader.Operation;
                IsIdempotent = requestHeader.Idempotent;
                Priority     = requestHeader.Priority ?? default;
                Context      = new Dictionary <string, string>();

                if (Location.Any(segment => segment.Length == 0))
                {
                    throw new InvalidDataException("received request with empty location segment");
                }
            }

            if (Identity.Name.Length == 0)
            {
                throw new InvalidDataException("received request with null identity");
            }

            if (Operation.Length == 0)
            {
                throw new InvalidDataException("received request with empty operation name");
            }

            (int size, int sizeLength, Encoding encoding) =
                Data.Slice(istr.Pos).AsReadOnlySpan().ReadEncapsulationHeader(Protocol.GetEncoding());

            Payload = Data.Slice(istr.Pos, size + sizeLength); // the payload is the encapsulation

            if (Protocol == Protocol.Ice2 && BinaryContext.TryGetValue(0, out ReadOnlyMemory <byte> value))
            {
                Context = value.Read(istr => istr.ReadDictionary(minKeySize: 1,
                                                                 minValueSize: 1,
                                                                 InputStream.IceReaderIntoString,
                                                                 InputStream.IceReaderIntoString));
            }

            if (protocol == Protocol.Ice1 && size + 4 + istr.Pos != data.Count)
            {
                // The payload holds an encapsulation and the encapsulation must use up the full buffer with ice1.
                // "4" corresponds to fixed-length size with the 1.1 encoding.
                throw new InvalidDataException($"invalid request encapsulation size: {size}");
            }

            Encoding             = encoding;
            HasCompressedPayload = Encoding == Encoding.V20 && Payload[sizeLength + 2] != 0;
        }