private void SerializeType(SerializerBinaryWriter writer, Type type) { object obj2 = this._typeTable[type]; if (obj2 != null) { writer.Write((byte)0x2b); writer.WriteEncoded((int)obj2); } else { this.AddSerializationTypeReference(type); if (type.Assembly == HttpContext.SystemWebAssembly) { writer.Write((byte)0x2a); writer.Write(type.FullName); } else { writer.Write((byte)0x29); writer.Write(type.AssemblyQualifiedName); } } }
/// <devdoc> /// Serializes a single value using the specified writer. /// Handles exceptions to provide more information about the value being serialized. /// </devdoc> private void SerializeValue(SerializerBinaryWriter writer, object value) { try { Stack objectStack = new Stack(); objectStack.Push(value); do { value = objectStack.Pop(); if (value == null) { writer.Write(Token_Null); continue; } // NOTE: These are ordered roughly in the order of frequency. if (value is string) { string s = (string)value; if (s.Length == 0) { writer.Write(Token_EmptyString); } else { writer.Write(Token_String); writer.Write(s); } continue; } if (value is int) { int i = (int)value; if (i == 0) { writer.Write(Token_ZeroInt32); } else { writer.Write(Token_Int32); writer.WriteEncoded(i); } continue; } if (value is Pair) { writer.Write(Token_Pair); Pair p = (Pair)value; objectStack.Push(p.Second); objectStack.Push(p.First); continue; } if (value is Triplet) { writer.Write(Token_Triplet); Triplet t = (Triplet)value; objectStack.Push(t.Third); objectStack.Push(t.Second); objectStack.Push(t.First); continue; } if (value is IndexedString) { Debug.Assert(((IndexedString)value).Value != null); SerializeIndexedString(writer, ((IndexedString)value).Value); continue; } if (value.GetType() == typeof(ArrayList)) { writer.Write(Token_ArrayList); ArrayList list = (ArrayList)value; writer.WriteEncoded(list.Count); for (int i = list.Count - 1; i >= 0; i--) { objectStack.Push(list[i]); } continue; } if (value is bool) { if (((bool)value)) { writer.Write(Token_True); } else { writer.Write(Token_False); } continue; } if (value is byte) { writer.Write(Token_Byte); writer.Write((byte)value); continue; } if (value is char) { writer.Write(Token_Char); writer.Write((char)value); continue; } if (value is DateTime) { writer.Write(Token_DateTime); writer.Write(((DateTime)value).ToBinary()); continue; } if (value is double) { writer.Write(Token_Double); writer.Write((double)value); continue; } if (value is short) { writer.Write(Token_Int16); writer.Write((short)value); continue; } if (value is float) { writer.Write(Token_Single); writer.Write((float)value); continue; } if (value is IDictionary) { bool canSerializeDictionary = false; if (value.GetType() == typeof(Hashtable)) { writer.Write(Token_Hashtable); canSerializeDictionary = true; } else if (value.GetType() == typeof(HybridDictionary)) { writer.Write(Token_HybridDictionary); canSerializeDictionary = true; } if (canSerializeDictionary) { IDictionary table = (IDictionary)value; writer.WriteEncoded(table.Count); if (table.Count != 0) { foreach (DictionaryEntry entry in table) { objectStack.Push(entry.Value); objectStack.Push(entry.Key); } } continue; } } if (value is EventValidationStore) { writer.Write(Token_EventValidationStore); ((EventValidationStore)value).SerializeTo(writer.BaseStream); continue; } if (value is Type) { writer.Write(Token_Type); SerializeType(writer, (Type)value); continue; } Type valueType = value.GetType(); if (value is Array) { // We only support Arrays with rank 1 (No multi dimensional arrays if (((Array)value).Rank > 1) { continue; } Type underlyingType = valueType.GetElementType(); if (underlyingType == typeof(string)) { string[] strings = (string[])value; bool containsNulls = false; for (int i = 0; i < strings.Length; i++) { if (strings[i] == null) { // Will have to treat these as generic arrays since we // can't represent nulls in the binary stream, without // writing out string token markers. // Generic array writing includes the token markers. containsNulls = true; break; } } if (!containsNulls) { writer.Write(Token_StringArray); writer.WriteEncoded(strings.Length); for (int i = 0; i < strings.Length; i++) { writer.Write(strings[i]); } continue; } } Array values = (Array)value; // Optimize for sparse arrays, if the array is more than 3/4 nulls if (values.Length > 3) { int sparseThreshold = (values.Length / 4) + 1; int numValues = 0; List<int> items = new List<int>(sparseThreshold); for (int i = 0; i < values.Length; ++i) { if (values.GetValue(i) != null) { ++numValues; if (numValues >= sparseThreshold) { break; } items.Add(i); } } // We have enough nulls to use sparse array format <index, value, index, value, ...> if (numValues < sparseThreshold) { writer.Write(Token_SparseArray); SerializeType(writer, underlyingType); writer.WriteEncoded(values.Length); writer.WriteEncoded(numValues); // Now we need to just serialize pairs representing the index, and the item foreach (int index in items) { writer.WriteEncoded(index); SerializeValue(writer, values.GetValue(index)); } continue; } } writer.Write(Token_Array); SerializeType(writer, underlyingType); writer.WriteEncoded(values.Length); for (int i = values.Length - 1; i >= 0; i--) { objectStack.Push(values.GetValue(i)); } continue; } if (valueType.IsEnum) { Type underlyingType = Enum.GetUnderlyingType(valueType); if (underlyingType == typeof(int)) { writer.Write(Token_IntEnum); SerializeType(writer, valueType); writer.WriteEncoded((int)value); continue; } } if (valueType == typeof(Color)) { Color c = (Color)value; if (c.IsEmpty) { writer.Write(Token_EmptyColor); continue; } if (!c.IsNamedColor) { writer.Write(Token_Color); writer.Write(c.ToArgb()); continue; } else { writer.Write(Token_KnownColor); writer.WriteEncoded((int)c.ToKnownColor()); continue; } } if (value is Unit) { Unit uval = (Unit)value; if (uval.IsEmpty) { writer.Write(Token_EmptyUnit); } else { writer.Write(Token_Unit); writer.Write(uval.Value); writer.Write((int)uval.Type); } continue; } // Handle the remaining types // First try to get a type converter, and then resort to // binary serialization if all else fails TypeConverter converter = TypeDescriptor.GetConverter(valueType); bool canConvert = System.Web.UI.Util.CanConvertToFrom(converter, typeof(string)); if (canConvert) { writer.Write(Token_StringFormatted); SerializeType(writer, valueType); writer.Write(converter.ConvertToInvariantString(null, value)); } else { IFormatter formatter = new BinaryFormatter(); MemoryStream ms = new MemoryStream(256); formatter.Serialize(ms, value); byte[] buffer = ms.GetBuffer(); int length = (int)ms.Length; writer.Write(Token_BinarySerialized); writer.WriteEncoded(length); if (buffer.Length != 0) { writer.Write(buffer, 0, (int)length); } } } while (objectStack.Count > 0); } catch (Exception serializationException) { if (value != null) throw new ArgumentException(SR.GetString(SR.ErrorSerializingValue, value.ToString(), value.GetType().FullName), serializationException); throw serializationException; } }
/// <devdoc> /// Serializes a Type. If this is the first occurrence, the type name is written /// out to the underlying stream, and the type is added to the string table for future /// reference. Otherwise, a reference by index is written out. /// </devdoc> private void SerializeType(SerializerBinaryWriter writer, Type type) { object id = _typeTable[type]; if (id != null) { writer.Write(Token_TypeRef); writer.WriteEncoded((int)id); return; } AddSerializationTypeReference(type); if (type.Assembly == HttpContext.SystemWebAssembly) { writer.Write(Token_TypeRefAddLocal); writer.Write(type.FullName); } else { writer.Write(Token_TypeRefAdd); writer.Write(type.AssemblyQualifiedName); } }
private void SerializeValue(SerializerBinaryWriter writer, object value) { try { Stack stack = new Stack(); stack.Push(value); Label_000D: value = stack.Pop(); if (value == null) { writer.Write((byte)100); } else if (value is string) { string str = (string)value; if (str.Length == 0) { writer.Write((byte)0x65); } else { writer.Write((byte)5); writer.Write(str); } } else if (value is int) { int num = (int)value; if (num == 0) { writer.Write((byte)0x66); } else { writer.Write((byte)2); writer.WriteEncoded(num); } } else if (value is Pair) { writer.Write((byte)15); Pair pair = (Pair)value; stack.Push(pair.Second); stack.Push(pair.First); } else if (value is Triplet) { writer.Write((byte)0x10); Triplet triplet = (Triplet)value; stack.Push(triplet.Third); stack.Push(triplet.Second); stack.Push(triplet.First); } else if (value is IndexedString) { this.SerializeIndexedString(writer, ((IndexedString)value).Value); } else if (value.GetType() == typeof(ArrayList)) { writer.Write((byte)0x16); ArrayList list = (ArrayList)value; writer.WriteEncoded(list.Count); for (int i = list.Count - 1; i >= 0; i--) { stack.Push(list[i]); } } else if (value is bool) { if ((bool)value) { writer.Write((byte)0x67); } else { writer.Write((byte)0x68); } } else if (value is byte) { writer.Write((byte)3); writer.Write((byte)value); } else if (value is char) { writer.Write((byte)4); writer.Write((char)value); } else if (value is DateTime) { writer.Write((byte)6); writer.Write(((DateTime)value).ToBinary()); } else if (value is double) { writer.Write((byte)7); writer.Write((double)value); } else if (value is short) { writer.Write((byte)1); writer.Write((short)value); } else if (value is float) { writer.Write((byte)8); writer.Write((float)value); } else { if (value is IDictionary) { bool flag = false; if (value.GetType() == typeof(Hashtable)) { writer.Write((byte)0x17); flag = true; } else if (value.GetType() == typeof(HybridDictionary)) { writer.Write((byte)0x18); flag = true; } if (flag) { IDictionary dictionary = (IDictionary)value; writer.WriteEncoded(dictionary.Count); if (dictionary.Count != 0) { foreach (DictionaryEntry entry in dictionary) { stack.Push(entry.Value); stack.Push(entry.Key); } } goto Label_06C3; } } if (value is Type) { writer.Write((byte)0x19); this.SerializeType(writer, (Type)value); } else { Type enumType = value.GetType(); if (value is Array) { if (((Array)value).Rank <= 1) { Type elementType = enumType.GetElementType(); if (elementType == typeof(string)) { string[] strArray = (string[])value; bool flag2 = false; for (int k = 0; k < strArray.Length; k++) { if (strArray[k] == null) { flag2 = true; break; } } if (!flag2) { writer.Write((byte)0x15); writer.WriteEncoded(strArray.Length); for (int m = 0; m < strArray.Length; m++) { writer.Write(strArray[m]); } goto Label_06C3; } } Array array = (Array)value; if (array.Length > 3) { int capacity = (array.Length / 4) + 1; int num6 = 0; List <int> list2 = new List <int>(capacity); for (int n = 0; n < array.Length; n++) { if (array.GetValue(n) != null) { num6++; if (num6 >= capacity) { break; } list2.Add(n); } } if (num6 < capacity) { writer.Write((byte)60); this.SerializeType(writer, elementType); writer.WriteEncoded(array.Length); writer.WriteEncoded(num6); foreach (int num8 in list2) { writer.WriteEncoded(num8); this.SerializeValue(writer, array.GetValue(num8)); } goto Label_06C3; } } writer.Write((byte)20); this.SerializeType(writer, elementType); writer.WriteEncoded(array.Length); for (int j = array.Length - 1; j >= 0; j--) { stack.Push(array.GetValue(j)); } } } else if (enumType.IsEnum && (Enum.GetUnderlyingType(enumType) == typeof(int))) { writer.Write((byte)11); this.SerializeType(writer, enumType); writer.WriteEncoded((int)value); } else if (enumType == typeof(Color)) { Color color = (Color)value; if (color.IsEmpty) { writer.Write((byte)12); } else if (!color.IsNamedColor) { writer.Write((byte)9); writer.Write(color.ToArgb()); } else { writer.Write((byte)10); writer.WriteEncoded((int)color.ToKnownColor()); } } else if (value is Unit) { Unit unit = (Unit)value; if (unit.IsEmpty) { writer.Write((byte)0x1c); } else { writer.Write((byte)0x1b); writer.Write(unit.Value); writer.Write((int)unit.Type); } } else { TypeConverter converter = TypeDescriptor.GetConverter(enumType); if (Util.CanConvertToFrom(converter, typeof(string))) { writer.Write((byte)40); this.SerializeType(writer, enumType); writer.Write(converter.ConvertToInvariantString(null, value)); } else { IFormatter formatter = new BinaryFormatter(); MemoryStream serializationStream = new MemoryStream(0x100); formatter.Serialize(serializationStream, value); byte[] buffer = serializationStream.GetBuffer(); int length = (int)serializationStream.Length; writer.Write((byte)50); writer.WriteEncoded(length); if (buffer.Length != 0) { writer.Write(buffer, 0, length); } } } } } Label_06C3: if (stack.Count > 0) { goto Label_000D; } } catch (Exception exception) { throw new ArgumentException(System.Web.SR.GetString("ErrorSerializingValue", new object[] { value.ToString(), value.GetType().FullName }), exception); } }
private void SerializeValue(SerializerBinaryWriter writer, object value) { try { Stack stack = new Stack(); stack.Push(value); Label_000D: value = stack.Pop(); if (value == null) { writer.Write((byte) 100); } else if (value is string) { string str = (string) value; if (str.Length == 0) { writer.Write((byte) 0x65); } else { writer.Write((byte) 5); writer.Write(str); } } else if (value is int) { int num = (int) value; if (num == 0) { writer.Write((byte) 0x66); } else { writer.Write((byte) 2); writer.WriteEncoded(num); } } else if (value is Pair) { writer.Write((byte) 15); Pair pair = (Pair) value; stack.Push(pair.Second); stack.Push(pair.First); } else if (value is Triplet) { writer.Write((byte) 0x10); Triplet triplet = (Triplet) value; stack.Push(triplet.Third); stack.Push(triplet.Second); stack.Push(triplet.First); } else if (value is IndexedString) { this.SerializeIndexedString(writer, ((IndexedString) value).Value); } else if (value.GetType() == typeof(ArrayList)) { writer.Write((byte) 0x16); ArrayList list = (ArrayList) value; writer.WriteEncoded(list.Count); for (int i = list.Count - 1; i >= 0; i--) { stack.Push(list[i]); } } else if (value is bool) { if ((bool) value) { writer.Write((byte) 0x67); } else { writer.Write((byte) 0x68); } } else if (value is byte) { writer.Write((byte) 3); writer.Write((byte) value); } else if (value is char) { writer.Write((byte) 4); writer.Write((char) value); } else if (value is DateTime) { writer.Write((byte) 6); writer.Write(((DateTime) value).ToBinary()); } else if (value is double) { writer.Write((byte) 7); writer.Write((double) value); } else if (value is short) { writer.Write((byte) 1); writer.Write((short) value); } else if (value is float) { writer.Write((byte) 8); writer.Write((float) value); } else { if (value is IDictionary) { bool flag = false; if (value.GetType() == typeof(Hashtable)) { writer.Write((byte) 0x17); flag = true; } else if (value.GetType() == typeof(HybridDictionary)) { writer.Write((byte) 0x18); flag = true; } if (flag) { IDictionary dictionary = (IDictionary) value; writer.WriteEncoded(dictionary.Count); if (dictionary.Count != 0) { foreach (DictionaryEntry entry in dictionary) { stack.Push(entry.Value); stack.Push(entry.Key); } } goto Label_06C3; } } if (value is Type) { writer.Write((byte) 0x19); this.SerializeType(writer, (Type) value); } else { Type enumType = value.GetType(); if (value is Array) { if (((Array) value).Rank <= 1) { Type elementType = enumType.GetElementType(); if (elementType == typeof(string)) { string[] strArray = (string[]) value; bool flag2 = false; for (int k = 0; k < strArray.Length; k++) { if (strArray[k] == null) { flag2 = true; break; } } if (!flag2) { writer.Write((byte) 0x15); writer.WriteEncoded(strArray.Length); for (int m = 0; m < strArray.Length; m++) { writer.Write(strArray[m]); } goto Label_06C3; } } Array array = (Array) value; if (array.Length > 3) { int capacity = (array.Length / 4) + 1; int num6 = 0; List<int> list2 = new List<int>(capacity); for (int n = 0; n < array.Length; n++) { if (array.GetValue(n) != null) { num6++; if (num6 >= capacity) { break; } list2.Add(n); } } if (num6 < capacity) { writer.Write((byte) 60); this.SerializeType(writer, elementType); writer.WriteEncoded(array.Length); writer.WriteEncoded(num6); foreach (int num8 in list2) { writer.WriteEncoded(num8); this.SerializeValue(writer, array.GetValue(num8)); } goto Label_06C3; } } writer.Write((byte) 20); this.SerializeType(writer, elementType); writer.WriteEncoded(array.Length); for (int j = array.Length - 1; j >= 0; j--) { stack.Push(array.GetValue(j)); } } } else if (enumType.IsEnum && (Enum.GetUnderlyingType(enumType) == typeof(int))) { writer.Write((byte) 11); this.SerializeType(writer, enumType); writer.WriteEncoded((int) value); } else if (enumType == typeof(Color)) { Color color = (Color) value; if (color.IsEmpty) { writer.Write((byte) 12); } else if (!color.IsNamedColor) { writer.Write((byte) 9); writer.Write(color.ToArgb()); } else { writer.Write((byte) 10); writer.WriteEncoded((int) color.ToKnownColor()); } } else if (value is Unit) { Unit unit = (Unit) value; if (unit.IsEmpty) { writer.Write((byte) 0x1c); } else { writer.Write((byte) 0x1b); writer.Write(unit.Value); writer.Write((int) unit.Type); } } else { TypeConverter converter = TypeDescriptor.GetConverter(enumType); if (Util.CanConvertToFrom(converter, typeof(string))) { writer.Write((byte) 40); this.SerializeType(writer, enumType); writer.Write(converter.ConvertToInvariantString(null, value)); } else { IFormatter formatter = new BinaryFormatter(); MemoryStream serializationStream = new MemoryStream(0x100); formatter.Serialize(serializationStream, value); byte[] buffer = serializationStream.GetBuffer(); int length = (int) serializationStream.Length; writer.Write((byte) 50); writer.WriteEncoded(length); if (buffer.Length != 0) { writer.Write(buffer, 0, length); } } } } } Label_06C3: if (stack.Count > 0) { goto Label_000D; } } catch (Exception exception) { throw new ArgumentException(System.Web.SR.GetString("ErrorSerializingValue", new object[] { value.ToString(), value.GetType().FullName }), exception); } }
private void SerializeType(SerializerBinaryWriter writer, Type type) { object obj2 = this._typeTable[type]; if (obj2 != null) { writer.Write((byte) 0x2b); writer.WriteEncoded((int) obj2); } else { this.AddSerializationTypeReference(type); if (type.Assembly == HttpContext.SystemWebAssembly) { writer.Write((byte) 0x2a); writer.Write(type.FullName); } else { writer.Write((byte) 0x29); writer.Write(type.AssemblyQualifiedName); } } }