/// <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)); } }