Ejemplo n.º 1
0
        /// <devdoc>
        /// Deserializes a single value from the underlying stream.
        /// Essentially a token is read, followed by as much data needed to recreate
        /// the single value.
        /// </devdoc>
        private object DeserializeValue(SerializerBinaryReader reader) {
            byte token = reader.ReadByte();

            // NOTE: Preserve the order here with the order of the logic in
            //       the SerializeValue method.

            switch (token) {
                case Token_Null:
                    return null;
                case Token_EmptyString:
                    return String.Empty;
                case Token_String:
                    return reader.ReadString();
                case Token_ZeroInt32:
                    return 0;
                case Token_Int32:
                    return reader.ReadEncodedInt32();
                case Token_Pair:
                    return new Pair(DeserializeValue(reader),
                                    DeserializeValue(reader));
                case Token_Triplet:
                    return new Triplet(DeserializeValue(reader),
                                       DeserializeValue(reader),
                                       DeserializeValue(reader));
                case Token_IndexedString:
                case Token_IndexedStringAdd:
                    return DeserializeIndexedString(reader, token);
                case Token_ArrayList:
                    {
                        int count = reader.ReadEncodedInt32();
                        ArrayList list = new ArrayList(count);
                        for (int i = 0; i < count; i++) {
                            list.Add(DeserializeValue(reader));
                        }

                        return list;
                    }
                case Token_True:
                    return true;
                case Token_False:
                    return false;
                case Token_Byte:
                    return reader.ReadByte();
                case Token_Char:
                    return reader.ReadChar();
                case Token_DateTime:
                    return DateTime.FromBinary(reader.ReadInt64());
                case Token_Double:
                    return reader.ReadDouble();
                case Token_Int16:
                    return reader.ReadInt16();
                case Token_Single:
                    return reader.ReadSingle();
                case Token_Hashtable:
                case Token_HybridDictionary:
                    {
                        int count = reader.ReadEncodedInt32();

                        IDictionary table;
                        if (token == Token_Hashtable) {
                            table = new Hashtable(count);
                        }
                        else {
                            table = new HybridDictionary(count);
                        }
                        for (int i = 0; i < count; i++) {
                            table.Add(DeserializeValue(reader),
                                      DeserializeValue(reader));
                        }

                        return table;
                    }
                case Token_Type:
                    return DeserializeType(reader);
                case Token_StringArray:
                    {
                        int count = reader.ReadEncodedInt32();

                        string[] array = new string[count];
                        for (int i = 0; i < count; i++) {
                            array[i] = reader.ReadString();
                        }

                        return array;
                    }
                case Token_Array:
                    {
                        Type elementType = DeserializeType(reader);
                        int count = reader.ReadEncodedInt32();

                        Array list = Array.CreateInstance(elementType, count);
                        for (int i = 0; i < count; i++) {
                            list.SetValue(DeserializeValue(reader), i);
                        }

                        return list;
                    }
                case Token_IntEnum:
                    {
                        Type enumType = DeserializeType(reader);
                        int enumValue = reader.ReadEncodedInt32();

                        return Enum.ToObject(enumType, enumValue);
                    }
                case Token_Color:
                    return Color.FromArgb(reader.ReadInt32());
                case Token_EmptyColor:
                    return Color.Empty;
                case Token_KnownColor:
                    return Color.FromKnownColor((KnownColor)reader.ReadEncodedInt32());
                case Token_Unit:
                    return new Unit(reader.ReadDouble(), (UnitType)reader.ReadInt32());
                case Token_EmptyUnit:
                    return Unit.Empty;
                case Token_EventValidationStore:
                    return EventValidationStore.DeserializeFrom(reader.BaseStream);
                case Token_SparseArray:
                    {
                        Type elementType = DeserializeType(reader);
                        int count = reader.ReadEncodedInt32();
                        int itemCount = reader.ReadEncodedInt32();

                        // Guard against bad data
                        if (itemCount > count) {
                            throw new InvalidOperationException(SR.GetString(SR.InvalidSerializedData));
                        }

                        Array list = Array.CreateInstance(elementType, count);
                        for (int i = 0; i < itemCount; ++i) {
                            // Data is encoded as <index, Item>
                            int nextPos = reader.ReadEncodedInt32();

                            // Guard against bad data (nextPos way too big, or nextPos not increasing)
                            if (nextPos >= count || nextPos < 0) {
                                throw new InvalidOperationException(SR.GetString(SR.InvalidSerializedData));
                            }
                            list.SetValue(DeserializeValue(reader), nextPos);
                        }

                        return list;
                    }
                case Token_StringFormatted:
                    {
                        object result = null;

                        Type valueType = DeserializeType(reader);
                        string formattedValue = reader.ReadString();

                        if (valueType != null) {
                            TypeConverter converter = TypeDescriptor.GetConverter(valueType);
                            // TypeDescriptor.GetConverter() will never return null.  The ref docs
                            // for this method are incorrect.
                            try {
                                result = converter.ConvertFromInvariantString(formattedValue);
                            }
                            catch (Exception exception) {
                                if (_throwOnErrorDeserializing) {
                                    throw;
                                }
                                else {
                                    WebBaseEvent.RaiseSystemEvent(
                                        SR.GetString(SR.Webevent_msg_OSF_Deserialization_String, valueType.AssemblyQualifiedName),
                                        this, 
                                        WebEventCodes.WebErrorObjectStateFormatterDeserializationError, 
                                        WebEventCodes.UndefinedEventDetailCode, 
                                        exception);
                                }
                            }
                        }

                        return result;
                    }
                case Token_BinarySerialized:
                    {
                        int length = reader.ReadEncodedInt32();

                        byte[] buffer = new byte[length];
                        if (length != 0) {
                            reader.Read(buffer, 0, length);
                        }

                        object result = null;
                        MemoryStream ms = GetMemoryStream();
                        try {
                            ms.Write(buffer, 0, length);
                            ms.Position = 0;
                            IFormatter formatter = new BinaryFormatter();

                            result = formatter.Deserialize(ms);
                        }
                        catch (Exception exception) {
                            if (_throwOnErrorDeserializing) {
                                throw;
                            }
                            else {
                                WebBaseEvent.RaiseSystemEvent(
                                    SR.GetString(SR.Webevent_msg_OSF_Deserialization_Binary), 
                                    this, 
                                    WebEventCodes.WebErrorObjectStateFormatterDeserializationError, 
                                    WebEventCodes.UndefinedEventDetailCode, 
                                    exception);
                            }
                        }
                        finally {
                            ReleaseMemoryStream(ms);
                        }
                        return result;
                    }
                default:
                    throw new InvalidOperationException(SR.GetString(SR.InvalidSerializedData));
            }
        }