Пример #1
0
        /// <summary>
        /// Parse the response header (deferred to the based class) and the result Payload.
        /// </summary>
        /// <param name="message">The byte buffer of the binary response data from the server.</param>
        internal override void ParseResponse(byte[] message)
        {
            var input = new Deserializer(message);

            // Parse header information first, deferring to base class
            this.ParseHeader(input);

            // Return immediately if header parsing failed
            if (this.ServerStatus != ResponseServerStatus.Success)
            {
                return;
            }

            // Parse the result
            try
            {
                // Unfortunately this is ugly: have to dynamically check the type to figure out which path to take
                // - no generic implementation can seamlessly deal with T, T[] and T[][]
                Type type = typeof(TResult);

                // Array type - either of:
                //  - Table[] an array of generic Tables
                //  - SingleRowTable[] an array of generic single-row Tables
                //  - T[][] an array of generic single-column Tables
                //  - T[] a single single-column Table
                if (type.IsArray)
                {
                    // Get sub-type within the array
                    Type elementType = type.GetElementType();

                    // We have a Table Array
                    if (elementType == typeof(Table))
                    {
                        this._Result = (TResult)(object)input.ReadTableArray();
                    }

                    // We have a SingleRowTable aArray
                    else if (elementType == typeof(SingleRowTable))
                    {
                        this._Result = (TResult)(object)input.ReadSingleRowTableArray();
                    }

                    // We have an array of single-column tables
                    else if (elementType.IsArray)
                    {
                        short count  = input.ReadInt16();
                        Array result = Array.CreateInstance(elementType, count);
                        for (short i = 0; i < count; i++)
                        {
                            result.SetValue(Table.FromSingleColumn(input, elementType.GetElementType()), i);
                        }
                        this._Result = (TResult)(object)result;
                    }

                    // We have a single single-column table
                    else
                    {
                        short count = input.ReadInt16();
                        if (count != 1)
                        {
                            throw new VoltInvalidDataException(Resources.InvalidResultsetSize, count);
                        }
                        if (elementType == typeof(byte))
                        {
                            elementType = typeof(byte[]);
                        }
                        this._Result = (TResult)Table.FromSingleColumn(input, elementType);
                    }
                }
                // Base type - either of:
                //  - Table
                //  - SingleRowTable
                //  - T
                else
                {
                    if (type == typeof(Null))
                    {
                        this._Result = (TResult)(object)new Null();
                    }
                    else
                    {
                        // Read count: there should be only 1 data set for those calls
                        short count = input.ReadInt16();
                        if (count != 1)
                        {
                            throw new VoltInvalidDataException(Resources.InvalidResultsetSize, count);
                        }

                        // A single Table
                        if (type == typeof(Table))
                        {
                            this._Result = (TResult)(object)new Table(input);
                        }

                        // A single single-row Table
                        else if (type == typeof(SingleRowTable))
                        {
                            this._Result = (TResult)(object)new SingleRowTable(input);
                        }

                        // A single value
                        else
                        {
                            this._Result = (TResult)Table.FromSingleValue <TResult>(input);
                        }
                    }
                }
            }
            catch (Exception x)
            {
                this.Exception = new VoltSerializationException(Resources.ResponseDeserializationFailure, x);
            }
        }