Example #1
0
        /// <summary>
        /// Read an object.
        /// </summary>
        private void ReadObject(AmfContext context, AmfStreamReader reader, XmlWriter output = null)
        {
            var reference = reader.PeekChar();
            int index;

            if ((reference & 0x1) == 0 && ReadReference(context, reader, out index, out reference))
            {
                if (output != null) WriteReference(index, output);
                return;
            }

            context.References.Track();

            int traitsindex, traitsreference;
            AmfTypeTraits traits;

            #region Read object's traits
            if ((traits = ReadTraitsReference(context, reader, out traitsindex, out traitsreference)) == null)
            {
                var isExternalizable = ((traitsreference & 0x4) == 4);
                var isDynamic = ((traitsreference & 0x8) == 8);
                var typeName = ReadString(context, reader);
                var count = (traitsreference >> 4);
                var classMembers = new string[count];

                for (var i = 0; i < count; i++)
                    classMembers[i] = ReadString(context, reader);

                traits = new AmfTypeTraits
                             {
                                 IsDynamic = isDynamic,
                                 IsExternalizable = isExternalizable,
                                 TypeName = typeName,

                                 //No property names are included for types
                                 //that are externizable or dynamic
                                 ClassMembers = isDynamic || isExternalizable
                                    ? new string[0]
                                    : classMembers
                             };

                context.TraitsReferences.Add(traits);
            }
            #endregion

            #if DEBUG
            Debug.WriteLine(string.Format(Errors.Amf3Decoder_ReadObject_Debug_Name, traits.TypeName));

            if (traits.IsDynamic)
                Debug.WriteLine(Errors.Amf3Decoder_ReadObject_Debug_Dynamic);
            else if (traits.IsExternalizable)
                Debug.WriteLine(Errors.Amf3Decoder_ReadObject_Debug_Externizable);
            else
                Debug.WriteLine(string.Format(Errors.Amf3Decoder_ReadObject_Debug_Members, traits.ClassMembers.Length));
            #endif

            

            using (var ms = new MemoryStream())
            {
                #region Reading object members
                var members = new List<string>();

                var settings = new XmlWriterSettings
                {
                 
                };

                var buffer = XmlWriter.Create(ms, settings);
                buffer.WriteStartDocument();
                buffer.WriteStartElement("buffer", AmfxContent.Namespace);

                #if DEBUG
                var memberPosition = 0;
                #endif

                //Read object's properties
                foreach (var classMember in traits.ClassMembers)
                {
                    #if DEBUG
                    Debug.WriteLine(string.Format(Errors.Amf3Decoder_ReadObject_Debug_ReadingField, memberPosition,
                                                    classMember));
                    memberPosition++;
                    #endif

                    ReadAmfValue(context, reader, buffer);
                    members.Add(classMember);
                }

                //Read dynamic properties too
                if (traits.IsDynamic)
                {
                    #if DEBUG
                    Debug.WriteLine(Errors.Amf3Decoder_ReadObject_Debug_ReadingDynamic);
                    #endif

                    var key = ReadString(context, reader);

                    while (key != string.Empty)
                    {
                        #if DEBUG
                        Debug.WriteLine(string.Format(Errors.Amf3Decoder_ReadObject_Debug_ReadingDynamicField, key));
                        #endif

                        ReadAmfValue(context, reader, buffer);
                        members.Add(key);

                        key = ReadString(context, reader);
                    }

                    #if DEBUG
                    Debug.WriteLine(Errors.Amf3Decoder_ReadObject_Debug_DynamicEnd);
                    #endif
                }

                buffer.WriteEndElement();
                buffer.WriteEndDocument();
                buffer.Flush();
                #endregion

                #if DEBUG
                Debug.WriteLine(Errors.Amf3Decoder_ReadObject_Debug_End);
                #endif

                #region Writing member values
                if (output != null)
                {
                    output.WriteStartElement(AmfxContent.Object);

                    if (traits.TypeName != AmfTypeTraits.BaseTypeAlias)
                        output.WriteAttributeString(AmfxContent.ObjectType, traits.TypeName);

                    output.WriteStartElement(AmfxContent.Traits);

                    //Regular traits object
                    //Always write traits for dynamic objects
                    if (traitsindex == -1 || traits.IsDynamic)
                    {
                        if (traits.IsExternalizable)
                        {
                            output.WriteAttributeString(AmfxContent.TraitsExternizable, AmfxContent.True);
                        }
                        else
                        {
                            //Write object members
                            foreach (var classMember in members)
                            {
                                output.WriteStartElement(AmfxContent.String);
                                output.WriteValue(classMember);
                                output.WriteEndElement();
                            }
                        }
                    }
                    //Traits object reference
                    else
                    {
                        output.WriteAttributeString(AmfxContent.TraitsId, traitsindex.ToString());
                    }

                    output.WriteEndElement(); //End of traits

                    //Write object members
                    if (members.Count > 0)
                    {
                        ms.Position = 0;
                        var bufferreader = XmlReader.Create(ms);
                        bufferreader.Read();
                        bufferreader.ReadStartElement();

                        while (bufferreader.Depth >= 1)
                            output.WriteNode(bufferreader, false);
                    }

                    output.WriteEndElement(); //End of object
                }
                #endregion
            }
        }