public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            var instance         = MethodFactory.CreateInstance(destinationType);
            var classDescription = serializationContext.GetClassDescription(destinationType, instance);
            var source           = value as IDictionary <string, object>;

            if (source != null)
            {
                foreach (var kv in source)
                {
                    IMemberWrapper wrapper;
                    if (classDescription.TryGetMember(kv.Key, out wrapper))
                    {
                        wrapper.SetValue(instance, kv.Value);
                    }
                }
                return(instance);
            }
            return(base.ConvertTo(context, culture, value, destinationType));
        }
Example #2
0
        /// <summary>This method writes the type marker and string.</summary>
        internal void WriteAmf0TypedObject(object obj)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            if (SerializationContext == null)
            {
                throw new NullReferenceException(
                          "Cannot serialize objects because no SerializationContext was provided.");
            }

            AddAmf0Reference(obj);

            var type     = obj.GetType();
            var typeName = type.FullName;

            var classDescription = SerializationContext.GetClassDescription(type, obj);

            if (classDescription == null)
            {
                throw new SerializationException(string.Format("Couldn't get class description for {0}.", typeName));
            }

            WriteMarker(Amf0TypeMarkers.TypedObject);
            WriteUtfPrefixed(classDescription.Name);
            foreach (var member in classDescription.Members)
            {
                WriteUtfPrefixed(member.SerializedName);
                WriteAmf0Item(member.GetValue(obj));
            }

            // End of object denoted by zero-length field name, then end of object type marker
            // Field names are length-prefixed UTF8 strings, so [0 length string, end of object type marker]
            WriteUInt16(0);
            WriteMarker(Amf0TypeMarkers.ObjectEnd);
        }
        internal void WriteAmf3Object(object obj)
        {
            if (obj == null)
            {
                throw new ArgumentNullException("obj");
            }

            if (SerializationContext == null)
            {
                throw new NullReferenceException("Cannot serialize objects because no SerializationContext was provided.");
            }

            if (WriteAmf3ReferenceOnExistence(obj))
            {
                return;
            }
            AddAmf3Reference(obj);

            var classDescription = SerializationContext.GetClassDescription(obj);
            int existingDefinitionIndex;

            if (amf3ClassDefinitionReferences.TryGetValue(classDescription, out existingDefinitionIndex))
            {
                // http://download.macromedia.com/pub/labs/amf/amf3_spec_121207.pdf
                // """
                // The first (low) bit is a flag with value 1. The second bit is a flag
                // (representing whether a trait reference follows) with value 0 to imply that
                // this objects traits are  being sent by reference. The remaining 1 to 27
                // significant bits are used to encode a trait reference index (an  integer).
                // -- AMF3 specification, 3.12 Object type
                // """

                // <u27=trait-reference-index> <0=trait-reference> <1=object-inline>
                WriteAmf3InlineHeader(existingDefinitionIndex << 1);
            }
            else
            {
                amf3ClassDefinitionReferences.Add(classDescription, amf3ClassDefinitionReferences.Count);

                // write the class definition
                // we can use the same format to serialize normal and extern classes, for simplicity's sake.
                //     normal:         <u25=member-count> <u1=dynamic> <0=externalizable> <1=trait-inline> <1=object-inline>
                //     externalizable: <u25=insignificant> <u1=insignificant> <1=externalizable> <1=trait-inline> <1=object-inline>
                var header = classDescription.Members.Length;
                header = (header << 1) | (classDescription.IsDynamic ? 1 : 0);
                header = (header << 1) | (classDescription.IsExternalizable ? 1 : 0);
                header = (header << 1) | 1;
                // last shift done in this method
                WriteAmf3InlineHeader(header);
                WriteAmf3Utf(classDescription.Name);

                // write object
                if (classDescription.IsExternalizable)
                {
                    var externalizable = obj as IExternalizable;
                    if (externalizable == null)
                    {
                        throw new SerializationException("Externalizable class does not implement IExternalizable");
                    }

                    externalizable.WriteExternal(new DataOutput(this));
                }
                else
                {
                    foreach (var member in classDescription.Members)
                    {
                        WriteAmf3Utf(member.SerializedName);
                    }

                    foreach (var member in classDescription.Members)
                    {
                        WriteAmf3Item(member.GetValue(obj));
                    }

                    if (classDescription.IsDynamic)
                    {
                        var dictionary = obj as IDictionary <string, object>;
                        if (dictionary == null)
                        {
                            throw new SerializationException("Dynamic class does not implement IDictionary");
                        }

                        foreach (KeyValuePair <string, object> entry in dictionary)
                        {
                            WriteAmf3Utf(entry.Key);
                            WriteAmf3Item(entry.Value);
                        }
                        WriteAmf3Utf(string.Empty);
                    }
                }
            }
        }