示例#1
0
        public override void SetUp()
        {
            base.SetUp();

            externalizableClass = new ASClass("extern", ASClassLayout.Externalizable, EmptyArray <string> .Instance);
            externalizable      = Mocks.CreateMock <IExternalizable>();
        }
示例#2
0
        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());
        }
示例#3
0
        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>();
        }
示例#5
0
 /// <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);
 }
示例#6
0
            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);
            }
示例#7
0
        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);
        }
示例#8
0
        public void SetPropertiesWithInitializedInstanceThrows()
        {
            IExternalizable externalizableValue = Mocks.CreateMock <IExternalizable>();

            Mocks.ReplayAll();

            ASExternalizableObject obj = new ASExternalizableObject(externalizableClass, externalizableValue);

            obj.SetProperties(externalizableValue);
        }
示例#9
0
        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;
        }
示例#11
0
        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);
        }
示例#12
0
        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);
        }
示例#13
0
        /// <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;
        }
示例#14
0
        /// <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;
        }
示例#15
0
        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);
        }
示例#17
0
        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);
            }
        }
示例#18
0
        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);
                }
            }
        }
示例#19
0
        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);
            }
        }
示例#20
0
 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);
                }
            }
示例#22
0
        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("");
                }
            }
        }
示例#23
0
 /// <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);
 }
示例#24
0
        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;
        }
示例#26
0
        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);
            }
        }
示例#27
0
        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);
        }
示例#28
0
		public IExternalizable EchoExternalizable(IExternalizable value)
		{
			return value;
		}
示例#29
0
        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";
 }
示例#31
0
        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);
        }
示例#32
0
 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);
 }
示例#33
0
            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);
                }
            }
示例#34
0
        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("");
                }
            }
        }
示例#35
0
        /// <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);
            }
        }
示例#36
0
 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);
 }