public override void SetUp() { base.SetUp(); externalizableClass = new ASClass("extern", ASClassLayout.Externalizable, EmptyArray <string> .Instance); externalizable = Mocks.CreateMock <IExternalizable>(); }
public void WriteObject_Objects_Externalizable_AMF3() { IExternalizable externalizableValue = Mocks.CreateMock <IExternalizable>(); externalizableValue.WriteExternal(output); LastCall.Do((WriteExternalDelegate) delegate(IDataOutput outputToUse) { // Note: outputToUse will be the same instance as output which we've already // tested so we don't need to try all combinations here. Just a few as a sanity check. outputToUse.WriteUTF("abc"); outputToUse.WriteInt(10); outputToUse.WriteObject(new ASString("def")); }); ASClass @class = new ASClass("class", ASClassLayout.Externalizable, EmptyArray <string> .Instance); ASExternalizableObject obj = new ASExternalizableObject(@class, externalizableValue); Mocks.ReplayAll(); output.ObjectEncoding = AMFObjectEncoding.AMF3; output.BeginObjectStream(); output.WriteObject(obj); output.EndObjectStream(); byte[] expected = new byte[] { (byte)AMF0ObjectTypeCode.AMF3Data, (byte)AMF3ObjectTypeCode.Object, 0x07, 0x0b, 0x63, 0x6c, 0x61, 0x73, 0x73, // class def 0x00, 0x03, 0x61, 0x62, 0x63, // write utf "abc" 0x00, 0x00, 0x00, 0x0a, // write int 10 (byte)AMF3ObjectTypeCode.String, 0x07, 0x64, 0x65, 0x66 // write object "def" }; CollectionAssert.AreElementsEqual(expected, stream.ToArray()); }
public void ReadObject_Objects_Externalizable_AMF3() { IExternalizable externalizableValue = Mocks.CreateMock <IExternalizable>(); externalizableValue.ReadExternal(input); LastCall.Do((ReadExternalDelegate) delegate(IDataInput inputToUse) { // Note: inputToUse will be the same instance of AMFDataInput which we've already // tested so we don't need to try all combinations here. Just a few as a sanity check. Assert.AreEqual("abc", inputToUse.ReadUTF()); Assert.AreEqual(10, inputToUse.ReadInt()); Assert.AreEqual(new ASString("def"), inputToUse.ReadObject()); }); Expect.Call(serializer.CreateExternalizableInstance("class")).Return(externalizableValue); Mocks.ReplayAll(); SetStreamContents(new byte[] { (byte)AMF0ObjectTypeCode.AMF3Data, (byte)AMF3ObjectTypeCode.Object, 0x07, 0x0b, 0x63, 0x6c, 0x61, 0x73, 0x73, // class def 0x00, 0x03, 0x61, 0x62, 0x63, // write utf "abc" 0x00, 0x00, 0x00, 0x0a, // write int 10 (byte)AMF3ObjectTypeCode.String, 0x07, 0x64, 0x65, 0x66 // write object "def" }); input.BeginObjectStream(); ASExternalizableObject obj = (ASExternalizableObject)input.ReadObject(); Assert.AreEqual(AMFObjectEncoding.AMF3, input.ObjectEncoding); input.EndObjectStream(); Assert.AreEqual("class", obj.Class.ClassAlias); Assert.AreEqual(ASClassLayout.Externalizable, obj.Class.Layout); Assert.AreSame(externalizableValue, obj.ExternalizableValue); }
public override void SetUp() { base.SetUp(); externalizableClass = new ASClass("extern", ASClassLayout.Externalizable, EmptyArray<string>.Instance); externalizable = Mocks.CreateMock<IExternalizable>(); }
/// <summary> /// Maps a <see cref="ASTypeKind.Object" /> value. /// </summary> /// <remarks> /// The default implementation throws an <see cref="ActionScriptException" />. /// </remarks> /// <param name="serializer">The serializer to use</param> /// <param name="nativeType">The native type to produce</param> /// <param name="class">The class of the object</param> /// <param name="memberValues">The member values of the object in member index order</param> /// <param name="dynamicProperties">The dynamic properties of the object in no particular order</param> /// <param name="externalizableValue">The externalizable value, or null if none</param> protected virtual object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { throw ToNativeNotSupported(ASTypeKind.Object, nativeType); }
protected override object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { IDictionary <TKey, TValue> dict = CreateDictionaryInstance(@class.MemberNames.Count); // Add members. int memberIndex = 0; foreach (IASValue memberValue in memberValues) { TKey key = (TKey)Convert.ChangeType(@class.MemberNames[memberIndex], typeof(TKey)); TValue value = (TValue)serializer.ToNative(memberValue, typeof(TValue)); dict.Add(key, value); memberIndex += 1; } // Add dynamic properties. foreach (KeyValuePair <string, IASValue> pair in dynamicProperties) { TKey key = (TKey)Convert.ChangeType(pair.Key, typeof(TKey)); TValue value = (TValue)serializer.ToNative(pair.Value, typeof(TValue)); dict.Add(key, value); } return(dict); }
internal object ReadAMF3Object(ClassDefinition classDefinition) { object instance = null; if (!string.IsNullOrEmpty(classDefinition.ClassName)) { instance = ObjectFactory.CreateInstance(classDefinition.ClassName); } else { instance = new ASObject(); } if (instance == null) { #if !SILVERLIGHT if (log.IsWarnEnabled) { log.Warn(__Res.GetString(__Res.TypeLoad_ASO, classDefinition.ClassName)); } #endif instance = new ASObject(classDefinition.ClassName); } AddAMF3ObjectReference(instance); if (classDefinition.IsExternalizable) { if (instance is IExternalizable) { IExternalizable externalizable = instance as IExternalizable; DataInput dataInput = new DataInput(this); externalizable.ReadExternal(dataInput); } else { string msg = __Res.GetString(__Res.Externalizable_CastFail, instance.GetType().FullName); throw new FluorineException(msg); } } else { for (int i = 0; i < classDefinition.MemberCount; i++) { string key = classDefinition.Members[i].Name; object value = ReadAMF3Data(); SetMember(instance, key, value); } if (classDefinition.IsDynamic) { string key = ReadAMF3String(); while (key != null && key != string.Empty) { object value = ReadAMF3Data(); SetMember(instance, key, value); key = ReadAMF3String(); } } } return(instance); }
public void SetPropertiesWithInitializedInstanceThrows() { IExternalizable externalizableValue = Mocks.CreateMock <IExternalizable>(); Mocks.ReplayAll(); ASExternalizableObject obj = new ASExternalizableObject(externalizableClass, externalizableValue); obj.SetProperties(externalizableValue); }
internal object ReadAMF3Object(ClassDefinition classDefinition) { //Console.WriteLine(classDefinition.ClassName + "=" + BaseStream.Position); object instance = null; if (!string.IsNullOrEmpty(classDefinition.ClassName)) { instance = ObjectFactory.CreateInstance(classDefinition.ClassName); } else { instance = new ASObject(); } if (instance == null) { instance = new ASObject(classDefinition.ClassName); } AddAMF3ObjectReference(instance); if (classDefinition.IsExternalizable) { if (instance is IExternalizable) { IExternalizable externalizable = instance as IExternalizable; DataInput dataInput = new DataInput(this); externalizable.ReadExternal(dataInput); } else { throw new Exception(classDefinition.ClassName + "是个IExternalizable类型"); } } else { for (int i = 0; i < classDefinition.MemberCount; i++) { string key = classDefinition.Members[i].Name; object value = ReadAMF3Data(); SetMember(instance, key, value); } if (classDefinition.IsDynamic) { string key = ReadAMF3String(); while (key != null && key != string.Empty) { object value = ReadAMF3Data(); SetMember(instance, key, value); key = ReadAMF3String(); } } } return(instance); }
/// <summary> /// Creates an object with the specified class and externalizable value. /// </summary> /// <param name="class">The ActionScript class</param> /// <param name="externalizableValue">The externalizable value</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="class"/> or <paramref name="externalizableValue"/> /// is null</exception> /// <exception cref="ArgumentException">Thrown when the class layout of <paramref name="class"/> is /// not <see cref="ASClassLayout.Externalizable" /></exception> public ASExternalizableObject(ASClass @class, IExternalizable externalizableValue) { if (@class == null) throw new ArgumentNullException("class"); if (externalizableValue == null) throw new ArgumentNullException("externalizableValue"); if (@class.Layout != ASClassLayout.Externalizable) throw new ArgumentException("The class layout must be Externalizable.", "class"); this.@class = @class; this.externalizableValue = externalizableValue; }
public void CreateUninitializedInstanceAndSetProperties() { IExternalizable externalizableValue = Mocks.CreateMock <IExternalizable>(); Mocks.ReplayAll(); ASExternalizableObject obj = ASExternalizableObject.CreateUninitializedInstance(externalizableClass); Assert.AreSame(externalizableClass, obj.Class); obj.SetProperties(externalizableValue); Assert.AreSame(externalizableValue, obj.ExternalizableValue); }
internal object ReadAMF3Object(ClassDefinition classDefinition) { object instance = null; string name; object obj3; if ((classDefinition.ClassName != null) && (classDefinition.ClassName != string.Empty)) { instance = ObjectFactory.CreateInstance(classDefinition.ClassName); } else { instance = new ASObject(); } if (instance == null) { if (log.get_IsWarnEnabled()) { log.Warn(__Res.GetString("TypeLoad_ASO", new object[] { classDefinition.ClassName })); } instance = new ASObject(classDefinition.ClassName); } this.AddAMF3ObjectReference(instance); if (classDefinition.IsExternalizable) { if (!(instance is IExternalizable)) { throw new FluorineException(__Res.GetString("Externalizable_CastFail", new object[] { instance.GetType().FullName })); } IExternalizable externalizable = instance as IExternalizable; DataInput input = new DataInput(this); externalizable.ReadExternal(input); return(instance); } for (int i = 0; i < classDefinition.MemberCount; i++) { name = classDefinition.Members[i].Name; obj3 = this.ReadAMF3Data(); this.SetMember(instance, name, obj3); } if (classDefinition.IsDynamic) { for (name = this.ReadAMF3String(); (name != null) && (name != string.Empty); name = this.ReadAMF3String()) { obj3 = this.ReadAMF3Data(); this.SetMember(instance, name, obj3); } } return(instance); }
/// <summary> /// Sets the properties of an instance created by <see cref="CreateUninitializedInstance" />. /// </summary> /// <remarks> /// This special case is used to resolve circular references during the construction of /// object graphs. The object should not be used until its properties have been initialized. /// </remarks> /// <param name="externalizableValue">The externalizable value</param> /// <exception cref="InvalidOperationException">Thrown if the object has already been initialized</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="externalizableValue"/> is null</exception> public void SetProperties(IExternalizable externalizableValue) { if (IsInitialized) { throw new InvalidOperationException("The object's properties may not be set once initialized."); } if (externalizableValue == null) { throw new ArgumentNullException("externalizableValue"); } this.externalizableValue = externalizableValue; }
/// <summary> /// Creates an object with the specified class and externalizable value. /// </summary> /// <param name="class">The ActionScript class</param> /// <param name="externalizableValue">The externalizable value</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="class"/> or <paramref name="externalizableValue"/> /// is null</exception> /// <exception cref="ArgumentException">Thrown when the class layout of <paramref name="class"/> is /// not <see cref="ASClassLayout.Externalizable" /></exception> public ASExternalizableObject(ASClass @class, IExternalizable externalizableValue) { if (@class == null) { throw new ArgumentNullException("class"); } if (externalizableValue == null) { throw new ArgumentNullException("externalizableValue"); } if (@class.Layout != ASClassLayout.Externalizable) { throw new ArgumentException("The class layout must be Externalizable.", "class"); } this.@class = @class; this.externalizableValue = externalizableValue; }
public object ReadData(AMFReader reader, ClassDefinition classDefinition) { object instance = ObjectFactory.CreateInstance(classDefinition.ClassName); if (instance == null) { throw new FluorineException(__Res.GetString("Type_InitError", new object[] { classDefinition.ClassName })); } reader.AddAMF3ObjectReference(instance); if (!(instance is IExternalizable)) { throw new FluorineException(__Res.GetString("Externalizable_CastFail", new object[] { instance.GetType().FullName })); } IExternalizable externalizable = instance as IExternalizable; DataInput input = new DataInput(reader); externalizable.ReadExternal(input); return(instance); }
public object ReadData(AMFReader reader, ClassDefinition classDefinition) { object instance = ObjectFactory.CreateInstance(classDefinition.ClassName); if (instance == null) { } reader.AddAMF3ObjectReference(instance); if (instance is IExternalizable) { IExternalizable externalizable = instance as IExternalizable; DataInput dataInput = new DataInput(reader); externalizable.ReadExternal(dataInput); return(instance); } else { } return(instance); }
public object ReadData(AMFReader reader, ClassDefinition classDefinition) { object instance = ObjectFactory.CreateInstance(classDefinition.ClassName); if (instance == null) { string msg = __Res.GetString(__Res.Type_InitError, classDefinition.ClassName); throw new FluorineException(msg); } reader.AddAMF3ObjectReference(instance); if (instance is IExternalizable) { IExternalizable externalizable = instance as IExternalizable; DataInput dataInput = new DataInput(reader); externalizable.ReadExternal(dataInput); return(instance); } else { string msg = __Res.GetString(__Res.Externalizable_CastFail, instance.GetType().FullName, classDefinition.ClassName); throw new FluorineException(msg); } }
internal void WriteAmf3Object(object obj) { if (obj == null) { throw new ArgumentNullException("obj"); } if (this.SerializationContext == null) { throw new NullReferenceException("Cannot serialize objects because no SerializationContext was provided."); } if (this.WriteAmf3ReferenceOnExistence(obj)) { return; } this.AddAmf3Reference(obj); ClassDescription classDescription = this.SerializationContext.GetClassDescription(obj); int num; if (this._amf3ClassDefinitionReferences.TryGetValue(classDescription, out num)) { this.WriteAmf3InlineHeader(num << 1); } else if (obj is AsObject && !(obj as AsObject).IsTyped) { this.WriteByte((byte)11); this.WriteByte((byte)1); foreach (KeyValuePair <string, object> keyValuePair in obj as AsObject) { this.WriteAmf3Utf(keyValuePair.Key); this.WriteAmf3Item(keyValuePair.Value); } this.WriteByte((byte)1); } else { this._amf3ClassDefinitionReferences.Add(classDescription, this._amf3ClassDefinitionReferences.Count); this.WriteAmf3InlineHeader(((classDescription.Members.Length << 1 | (classDescription.IsDynamic ? 1 : 0)) << 1 | (classDescription.IsExternalizable ? 1 : 0)) << 1 | 1); this.WriteAmf3Utf(classDescription.Name); if (classDescription.IsExternalizable) { IExternalizable externalizable = obj as IExternalizable; if (externalizable == null) { throw new SerializationException("Externalizable class does not implement IExternalizable"); } DataOutput dataOutput = new DataOutput(this); externalizable.WriteExternal((IDataOutput)dataOutput); } else { foreach (IMemberWrapper member in classDescription.Members) { this.WriteAmf3Utf(member.SerializedName); } foreach (IMemberWrapper member in classDescription.Members) { this.WriteAmf3Item(member.GetValue(obj)); } if (!classDescription.IsDynamic) { return; } IDictionary <string, object> dictionary = obj as IDictionary <string, object>; if (dictionary == null) { throw new SerializationException("Dynamic class does not implement IDictionary"); } foreach (KeyValuePair <string, object> keyValuePair in (IEnumerable <KeyValuePair <string, object> >)dictionary) { this.WriteAmf3Utf(keyValuePair.Key); this.WriteAmf3Item(keyValuePair.Value); } this.WriteAmf3Utf(string.Empty); } } }
public void WriteAMF3Object(object value) { int num; if (!this._objectReferences.ContainsKey(value)) { int num2; this._objectReferences.Add(value, this._objectReferences.Count); ClassDefinition classDefinition = this.GetClassDefinition(value); if ((classDefinition != null) && this._classDefinitionReferences.ContainsKey(classDefinition)) { num = this._classDefinitionReferences[classDefinition]; num = num << 2; num |= 1; this.WriteAMF3IntegerData(num); } else { classDefinition = this.CreateClassDefinition(value); this._classDefinitionReferences.Add(classDefinition, this._classDefinitionReferences.Count); num = classDefinition.MemberCount << 1; num |= classDefinition.IsDynamic ? 1 : 0; num = num << 1; num |= classDefinition.IsExternalizable ? 1 : 0; num = num << 2; num |= 3; this.WriteAMF3IntegerData(num); this.WriteAMF3UTF(classDefinition.ClassName); for (num2 = 0; num2 < classDefinition.MemberCount; num2++) { string name = classDefinition.Members[num2].Name; this.WriteAMF3UTF(name); } } if (classDefinition.IsExternalizable) { if (!(value is IExternalizable)) { throw new FluorineException(__Res.GetString("Externalizable_CastFail", new object[] { classDefinition.ClassName })); } IExternalizable externalizable = value as IExternalizable; DataOutput output = new DataOutput(this); externalizable.WriteExternal(output); } else { for (num2 = 0; num2 < classDefinition.MemberCount; num2++) { object member = this.GetMember(value, classDefinition.Members[num2]); this.WriteAMF3Data(member); } if (classDefinition.IsDynamic) { IDictionary dictionary = value as IDictionary; foreach (DictionaryEntry entry in dictionary) { this.WriteAMF3UTF(entry.Key.ToString()); this.WriteAMF3Data(entry.Value); } this.WriteAMF3UTF(string.Empty); } } } else { num = this._objectReferences[value]; num = num << 1; this.WriteAMF3IntegerData(num); } }
void IASValueVisitor.VisitObject(IActionScriptSerializer serializer, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { result = mapper.MapObjectToNative(serializer, nativeType, @class, memberValues, dynamicProperties, externalizableValue); }
protected override object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable<IASValue> memberValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties, IExternalizable externalizableValue) { try { object instance = Activator.CreateInstance(classMapping.NativeType); IDynamic dynamic = instance as IDynamic; // Set values from class members. // Note: The layout of the AS class we receive from the client may differ // from what we generated as part of the mapper. The only thing that // matters is the property name and value regardless of whether it appears as a member // or as a dynamic property. IList<string> memberNames = @class.MemberNames; int memberIndex = 0; foreach (IASValue memberValue in memberValues) { string memberName = memberNames[memberIndex]; SetMappedMemberOrDynamicProperty(serializer, instance, dynamic, memberName, memberValue); memberIndex += 1; } // Set value from dynamic properties. foreach (KeyValuePair<string, IASValue> pair in dynamicProperties) { SetMappedMemberOrDynamicProperty(serializer, instance, dynamic, pair.Key, pair.Value); } return instance; } catch (Exception ex) { throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture, "An error occurred while mapping an ActionScript value to an instance of type '{0}'.", classMapping.NativeType.FullName), ex); } }
void IASValueVisitor.VisitObject(IActionScriptSerializer serializer, ASClass @class, IEnumerable<IASValue> memberValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties, IExternalizable externalizableValue) { int objectReferenceId = AddCurrentValueToCache(AMF3ObjectTypeCode.Object); output.WriteByte((byte)AMF3ObjectTypeCode.Object); // Look for a suitable existing class definition in the cache. int classDefinitionId; if (classDefinitionCache.TryGetValue(@class, out classDefinitionId)) { // Use class definition reference. output.WriteVWInt29(classDefinitionId * 4 + 1); } else { // Include class definition inline and add it to the cache. classDefinitionCache.Add(@class, objectReferenceId); output.WriteVWInt29(@class.MemberNames.Count * 16 + (int)@class.Layout * 4 + 3); WriteStringData(@class.ClassAlias); foreach (string memberName in @class.MemberNames) { if (String.IsNullOrEmpty(memberName)) throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty member name."); WriteStringData(memberName); } } if (@class.Layout == ASClassLayout.Externalizable) { if (externalizableValue == null) throw new AMFException(ExceptionPrefix + "The class layout is Externalizable but the object does not provide an ExternalizableValue."); externalizableValue.WriteExternal(output); } else { // Write the members first as a sequence of values. int memberCount = @class.MemberNames.Count; int memberIndex = 0; foreach (IASValue memberValue in memberValues) { if (memberIndex == memberCount) throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is greater than was indicated by its class."); WriteObject(memberValue); memberIndex += 1; } if (memberIndex != memberCount) throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is less than was indicated by its class."); if (@class.Layout == ASClassLayout.Dynamic) { // Write dynamic key/value pairs. foreach (KeyValuePair<string, IASValue> pair in dynamicProperties) { if (String.IsNullOrEmpty(pair.Key)) throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty string key."); WriteStringData(pair.Key); WriteObject(pair.Value); } // Terminate with empty string. WriteStringData(""); } } }
/// <summary> /// Maps a <see cref="ASTypeKind.Object" /> value. /// </summary> /// <remarks> /// The default implementation throws an <see cref="ActionScriptException" />. /// </remarks> /// <param name="serializer">The serializer to use</param> /// <param name="nativeType">The native type to produce</param> /// <param name="class">The class of the object</param> /// <param name="memberValues">The member values of the object in member index order</param> /// <param name="dynamicProperties">The dynamic properties of the object in no particular order</param> /// <param name="externalizableValue">The externalizable value, or null if none</param> protected virtual object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable<IASValue> memberValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties, IExternalizable externalizableValue) { throw ToNativeNotSupported(ASTypeKind.Object, nativeType); }
public void WriteAMF3Object(object value) { if (!_objectReferences.ContainsKey(value)) { _objectReferences.Add(value, _objectReferences.Count); ClassDefinition classDefinition = GetClassDefinition(value); if (classDefinition == null) { Console.WriteLine("serializing:{0}", value.GetType().FullName); // DebugX.LogError("serializing:{0}", value.GetType().FullName); return; } if (_classDefinitionReferences.ContainsKey(classDefinition)) { //Existing class-def int handle = (int)_classDefinitionReferences[classDefinition];//handle = classRef 0 1 handle = handle << 2; handle = handle | 1; WriteAMF3IntegerData(handle); } else { //inline class-def //classDefinition = CreateClassDefinition(value); _classDefinitionReferences.Add(classDefinition, _classDefinitionReferences.Count); //handle = memberCount dynamic externalizable 1 1 int handle = classDefinition.MemberCount; handle = handle << 1; handle = handle | (classDefinition.IsDynamic ? 1 : 0); handle = handle << 1; handle = handle | (classDefinition.IsExternalizable ? 1 : 0); handle = handle << 2; handle = handle | 3; WriteAMF3IntegerData(handle); WriteAMF3UTF(classDefinition.ClassName); for (int i = 0; i < classDefinition.MemberCount; i++) { string key = classDefinition.Members[i].Name; WriteAMF3UTF(key); } } //write inline object if (classDefinition.IsExternalizable) { if (value is IExternalizable) { IExternalizable externalizable = value as IExternalizable; DataOutput dataOutput = new DataOutput(this); externalizable.WriteExternal(dataOutput); } else { throw new NotImplementedException(classDefinition.ClassName + " must is IExternalizable"); } } else { Type type = value.GetType(); IObjectProxy proxy = ObjectProxyRegistry.GetObjectProxy(type); for (int i = 0; i < classDefinition.MemberCount; i++) { object memberValue = proxy.GetValue(value, classDefinition.Members[i]); WriteAMF3Data(memberValue); } if (classDefinition.IsDynamic) { IDictionary dictionary = value as IDictionary; foreach (DictionaryEntry entry in dictionary) { WriteAMF3UTF(entry.Key.ToString()); WriteAMF3Data(entry.Value); } WriteAMF3UTF(string.Empty); } } } else { //handle = objectRef 0 int handle = (int)_objectReferences[value]; handle = handle << 1; WriteAMF3IntegerData(handle); } }
/// <summary> /// Sets the properties of an instance created by <see cref="CreateUninitializedInstance" />. /// </summary> /// <remarks> /// This special case is used to resolve circular references during the construction of /// object graphs. The object should not be used until its properties have been initialized. /// </remarks> /// <param name="externalizableValue">The externalizable value</param> /// <exception cref="InvalidOperationException">Thrown if the object has already been initialized</exception> /// <exception cref="ArgumentNullException">Thrown when <paramref name="externalizableValue"/> is null</exception> public void SetProperties(IExternalizable externalizableValue) { if (IsInitialized) throw new InvalidOperationException("The object's properties may not be set once initialized."); if (externalizableValue == null) throw new ArgumentNullException("externalizableValue"); this.externalizableValue = externalizableValue; }
private IASValue ReadObjectValue() { int bits = input.ReadVWInt29(); // Handle cached objects. if ((bits & 1) == 0) { int referenceId = bits >> 1; return(GetObjectFromCache(AMF3ObjectTypeCode.Object, referenceId)); } // Handle cached class definitions. ASClass classDefinition; if ((bits & 2) == 0) { int referenceId = bits >> 2; // Note: Object might be an ASExternalizableObject. IASValue obj = GetObjectFromCache(AMF3ObjectTypeCode.Object, referenceId); classDefinition = obj.Class; } else { // Read the class definition. ASClassLayout classLayout = (ASClassLayout)((bits & 0x0c) >> 2); if (classLayout > ASClassLayout.Dynamic) { throw new AMFException(String.Format(CultureInfo.CurrentCulture, ExceptionPrefix + "Encountered Object token with invalid class layout '{0}'.", classLayout)); } int memberCount = bits >> 4; if (memberCount < 0) { throw new AMFException(String.Format(CultureInfo.CurrentCulture, ExceptionPrefix + "Encountered Object token with invalid member count '{0}'.", memberCount)); } if (classLayout == ASClassLayout.Externalizable && memberCount != 0) { throw new AMFException(String.Format(CultureInfo.CurrentCulture, ExceptionPrefix + "Encountered Object token with Externalizable class layout and non-zero member count '{0}'.", memberCount)); } string classAlias = ReadStringData(); string[] memberNames; if (memberCount != 0) { memberNames = new string[memberCount]; for (int i = 0; i < memberCount; i++) { memberNames[i] = ReadStringData(); } } else { memberNames = EmptyArray <string> .Instance; } // Look up the class in the cache. classDefinition = ASClassCache.GetClass(classAlias, classLayout, memberNames); } // Read the instance data. if (classDefinition.Layout == ASClassLayout.Externalizable) { // Important: Add the object to the cache before deserializing its properties! ASExternalizableObject result = ASExternalizableObject.CreateUninitializedInstance(classDefinition); AddObjectToCache(AMF3ObjectTypeCode.Object, result); // Use custom serialization for the externalizable object. IExternalizable externalizableValue = input.Serializer.CreateExternalizableInstance(classDefinition.ClassAlias); externalizableValue.ReadExternal(input); result.SetProperties(externalizableValue); return(result); } else { // Important: Add the object to the cache before deserializing its properties! ASObject result = ASObject.CreateUninitializedInstance(classDefinition); AddObjectToCache(AMF3ObjectTypeCode.Object, result); // Read the member values. int memberCount = classDefinition.MemberNames.Count; IASValue[] memberValues; if (memberCount != 0) { memberValues = new IASValue[memberCount]; for (int i = 0; i < memberCount; i++) { memberValues[i] = ReadObject(); } } else { memberValues = EmptyArray <IASValue> .Instance; } // Read the dynamic property values. IDictionary <string, IASValue> dynamicProperties; if (classDefinition.Layout == ASClassLayout.Dynamic) { string key = ReadStringData(); if (key.Length != 0) { dynamicProperties = new Dictionary <string, IASValue>(); for (; ;) { IASValue value = ReadObject(); dynamicProperties.Add(key, value); key = ReadStringData(); if (key.Length == 0) { break; } } } else { dynamicProperties = EmptyDictionary <string, IASValue> .Instance; } } else { dynamicProperties = EmptyDictionary <string, IASValue> .Instance; } result.SetProperties(memberValues, dynamicProperties); return(result); } }
private object ReadAMF3Object(ClassDefinition classDefinition) { object instance = null; if (!string.IsNullOrEmpty(classDefinition.ClassName)) { instance = ObjectFactory.CreateInstance(classDefinition.ClassName); } else { instance = new ASObject(); } if (instance == null) { instance = new ASObject(classDefinition.ClassName); } AddAMF3ObjectReference(instance); if (classDefinition.IsExternalizable) { if (instance is IExternalizable) { IExternalizable externalizable = instance as IExternalizable; DataInput dataInput = new DataInput(this); externalizable.readExternal(dataInput); } else { throw new Exception("readExternal Fail:" + classDefinition.ClassName); } } else { for (int i = 0; i < classDefinition.MemberCount; i++) { string key = classDefinition.Members[i].Name; object value = ReadAMF3Data(); SetMember(instance, key, value); } if (classDefinition.IsDynamic) { string key = ReadAMF3String(); while (!string.IsNullOrEmpty(key)) { object value = ReadAMF3Data(); SetMember(instance, key, value); key = ReadAMF3String(); } } } return(instance); }
public IExternalizable EchoExternalizable(IExternalizable value) { return value; }
void IASValueVisitor.VisitObject(IActionScriptSerializer serializer, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { AddCurrentValueToCache(); // Externalizable not supported. if (@class.Layout == ASClassLayout.Externalizable) { throw new AMFException(ExceptionPrefix + "Externalizable class layout not supported by AMF0."); } if (@class.ClassAlias.Length != 0) { // Write class alias for typed object. output.WriteByte((byte)AMF0ObjectTypeCode.TypedObject); output.WriteShortString(@class.ClassAlias); } else { // Write header for untyped object. output.WriteByte((byte)AMF0ObjectTypeCode.Object); } // Write members as key/value pairs. IList <string> memberNames = @class.MemberNames; int memberCount = memberNames.Count; int memberIndex = 0; foreach (IASValue memberValue in memberValues) { if (memberIndex == memberCount) { throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is greater than was indicated by its class."); } string memberName = memberNames[memberIndex]; if (String.IsNullOrEmpty(memberName)) { throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty member name."); } output.WriteShortString(memberName); WriteObject(memberValue); memberIndex += 1; } if (memberIndex != memberCount) { throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is less than was indicated by its class."); } // Write dynamic key/value pairs. foreach (KeyValuePair <string, IASValue> pair in dynamicProperties) { if (String.IsNullOrEmpty(pair.Key)) { throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty string key."); } output.WriteShortString(pair.Key); WriteObject(pair.Value); } // Terminate with empty string and end of object marker. output.WriteShortString(""); output.WriteByte((byte)AMF0ObjectTypeCode.EndOfObject); }
protected override object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable<IASValue> memberValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties, IExternalizable externalizableValue) { return "Object"; }
void IASValueVisitor.VisitObject(IActionScriptSerializer serializer, ASClass @class, IEnumerable<IASValue> memberValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties, IExternalizable externalizableValue) { AddCurrentValueToCache(); // Externalizable not supported. if (@class.Layout == ASClassLayout.Externalizable) throw new AMFException(ExceptionPrefix + "Externalizable class layout not supported by AMF0."); if (@class.ClassAlias.Length != 0) { // Write class alias for typed object. output.WriteByte((byte)AMF0ObjectTypeCode.TypedObject); output.WriteShortString(@class.ClassAlias); } else { // Write header for untyped object. output.WriteByte((byte)AMF0ObjectTypeCode.Object); } // Write members as key/value pairs. IList<string> memberNames = @class.MemberNames; int memberCount = memberNames.Count; int memberIndex = 0; foreach (IASValue memberValue in memberValues) { if (memberIndex == memberCount) throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is greater than was indicated by its class."); string memberName = memberNames[memberIndex]; if (String.IsNullOrEmpty(memberName)) throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty member name."); output.WriteShortString(memberName); WriteObject(memberValue); memberIndex += 1; } if (memberIndex != memberCount) throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is less than was indicated by its class."); // Write dynamic key/value pairs. foreach (KeyValuePair<string, IASValue> pair in dynamicProperties) { if (String.IsNullOrEmpty(pair.Key)) throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty string key."); output.WriteShortString(pair.Key); WriteObject(pair.Value); } // Terminate with empty string and end of object marker. output.WriteShortString(""); output.WriteByte((byte)AMF0ObjectTypeCode.EndOfObject); }
void IASValueVisitor.VisitObject(IActionScriptSerializer serializer, ASClass @class, IEnumerable<IASValue> memberValues, IEnumerable<KeyValuePair<string, IASValue>> dynamicProperties, IExternalizable externalizableValue) { result = mapper.MapObjectToNative(serializer, nativeType, @class, memberValues, dynamicProperties, externalizableValue); }
protected override object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { try { object instance = Activator.CreateInstance(classMapping.NativeType); IDynamic dynamic = instance as IDynamic; // Set values from class members. // Note: The layout of the AS class we receive from the client may differ // from what we generated as part of the mapper. The only thing that // matters is the property name and value regardless of whether it appears as a member // or as a dynamic property. IList <string> memberNames = @class.MemberNames; int memberIndex = 0; foreach (IASValue memberValue in memberValues) { string memberName = memberNames[memberIndex]; SetMappedMemberOrDynamicProperty(serializer, instance, dynamic, memberName, memberValue); memberIndex += 1; } // Set value from dynamic properties. foreach (KeyValuePair <string, IASValue> pair in dynamicProperties) { SetMappedMemberOrDynamicProperty(serializer, instance, dynamic, pair.Key, pair.Value); } return(instance); } catch (Exception ex) { throw new ActionScriptException(String.Format(CultureInfo.CurrentCulture, "An error occurred while mapping an ActionScript value to an instance of type '{0}'.", classMapping.NativeType.FullName), ex); } }
void IASValueVisitor.VisitObject(IActionScriptSerializer serializer, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { int objectReferenceId = AddCurrentValueToCache(AMF3ObjectTypeCode.Object); output.WriteByte((byte)AMF3ObjectTypeCode.Object); // Look for a suitable existing class definition in the cache. int classDefinitionId; if (classDefinitionCache.TryGetValue(@class, out classDefinitionId)) { // Use class definition reference. output.WriteVWInt29(classDefinitionId * 4 + 1); } else { // Include class definition inline and add it to the cache. classDefinitionCache.Add(@class, objectReferenceId); output.WriteVWInt29(@class.MemberNames.Count * 16 + (int)@class.Layout * 4 + 3); WriteStringData(@class.ClassAlias); foreach (string memberName in @class.MemberNames) { if (String.IsNullOrEmpty(memberName)) { throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty member name."); } WriteStringData(memberName); } } if (@class.Layout == ASClassLayout.Externalizable) { if (externalizableValue == null) { throw new AMFException(ExceptionPrefix + "The class layout is Externalizable but the object does not provide an ExternalizableValue."); } externalizableValue.WriteExternal(output); } else { // Write the members first as a sequence of values. int memberCount = @class.MemberNames.Count; int memberIndex = 0; foreach (IASValue memberValue in memberValues) { if (memberIndex == memberCount) { throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is greater than was indicated by its class."); } WriteObject(memberValue); memberIndex += 1; } if (memberIndex != memberCount) { throw new AMFException(ExceptionPrefix + "The number of member values provided by the object is less than was indicated by its class."); } if (@class.Layout == ASClassLayout.Dynamic) { // Write dynamic key/value pairs. foreach (KeyValuePair <string, IASValue> pair in dynamicProperties) { if (String.IsNullOrEmpty(pair.Key)) { throw new AMFException(ExceptionPrefix + "Cannot serialize an object with a null or empty string key."); } WriteStringData(pair.Key); WriteObject(pair.Value); } // Terminate with empty string. WriteStringData(""); } } }
/// <summary> /// 10 /// </summary> /// <param name="value"></param> public void WriteAMF3Object(object value) { if (!amf3ObjectReferences.ContainsKey(value)) { amf3ObjectReferences.Add(value, amf3ObjectReferences.Count); ClassDefinition classDefinition = GetClassDefinition(value); if (ContainsClassDefinitionReferences(classDefinition)) { int handle = GetClassDefinitionReferencesIndex(classDefinition); handle = handle << 2; handle = handle | 1; WriteAMF3IntegerData(handle); } else { amf3ClassReferences.Add(classDefinition, amf3ClassReferences.Count); int handle = classDefinition.MemberCount; handle = handle << 1; handle = handle | (classDefinition.IsDynamic ? 1 : 0); handle = handle << 1; handle = handle | (classDefinition.IsExternalizable ? 1 : 0); handle = handle << 2; handle = handle | 3; WriteAMF3IntegerData(handle); WriteAMF3UTF(classDefinition.ClassName); for (int i = 0; i < classDefinition.MemberCount; i++) { string key = classDefinition.Members[i].Name; WriteAMF3UTF(key); } } if (classDefinition.IsExternalizable) { if (value is IExternalizable) { IExternalizable externalizable = value as IExternalizable; DataOutput dataOutput = new DataOutput(this); externalizable.writeExternal(dataOutput); } else { throw new Exception("writeExternal Fail:" + classDefinition.ClassName); } } else { Type type = value.GetType(); IObjectProxy proxy = ObjectProxyRegistry.Instance.GetObjectProxy(type); for (int i = 0; i < classDefinition.MemberCount; i++) { object memberValue = proxy.GetValue(value, classDefinition.Members[i]); WriteAMF3Data(memberValue); } if (classDefinition.IsDynamic) { IDictionary dictionary = value as IDictionary; foreach (DictionaryEntry entry in dictionary) { WriteAMF3UTF(entry.Key.ToString()); WriteAMF3Data(entry.Value); } WriteAMF3UTF(string.Empty); } } } else { int handle = amf3ObjectReferences[value]; handle = handle << 1; WriteAMF3IntegerData(handle); } }
protected override object MapObjectToNative(IActionScriptSerializer serializer, Type nativeType, ASClass @class, IEnumerable <IASValue> memberValues, IEnumerable <KeyValuePair <string, IASValue> > dynamicProperties, IExternalizable externalizableValue) { return("Object"); }
public IExternalizable EchoExternalizable(IExternalizable value) { return(value); }