private void WriteArray(IList data)
        {
            uint length = 0;

            if (data == null)
            {
                Write(length);
                return;
            }

            length = Convert.ToUInt32(data.Count);
            Write(length);
            for (int i = 0; i < data.Count; i++)
            {
                AMFData arrayData = data[i] as AMFData;
                if (arrayData != null)
                {
                    WriteAMFData(arrayData.DataType, arrayData.Data);
                }
                else
                {
                    if (data[i] == null)
                    {
                        Write((byte)AMFDataType.Null);
                    }
                    else
                    {
                        ProcessUnknownObject(data[i]);
                    }
                }
            }
        }
        private void WriteActionScriptObject(ActionScriptObject aso)
        {
            if (aso.TypeName != string.Empty && aso.TypeName != null)
            {
                Write((byte)AMFDataType.TypedObject);
                WriteUTF(aso.TypeName);
            }
            else
            {
                Write((byte)AMFDataType.Object);
            }

            foreach (KeyValuePair <string, object> kvp in aso.Properties)
            {
                WriteUTF(kvp.Key);

                AMFData data = kvp.Value as AMFData;
                if (data == null)
                {
                    Write((byte)AMFDataType.Null);
                }
                else
                {
                    //this will allow us to have nested objects as properties
                    //on our AMF objects
                    if (data.DataType == AMFDataType.AMFEnabledObject)
                    {
                        if (data.Data != null)
                        {
                            ProcessUnknownObject(data.Data);
                        }
                        else
                        {
                            Write((byte)AMFDataType.Null);
                        }
                    }
                    else
                    {
                        WriteAMFData(data.DataType, data.Data);
                    }
                }
            }

            //write out the end record
            Write(Convert.ToUInt16(0));
            Write((byte)AMFDataType.EndOfObject);
        }
Beispiel #3
0
        private static object GetArrayElementValue(AMFData sourceData, Type memberType)
        {
            switch (sourceData.DataType)
            {
            case AMFDataType.AMFEnabledObject:
            case AMFDataType.Object:
            case AMFDataType.TypedObject:
            case AMFDataType.Reference:
                return(Deserialize(sourceData.Data as ActionScriptObject, memberType));

            case AMFDataType.Number:
                switch (memberType.Name)
                {
                case "Int32":
                    return(Convert.ToInt32(sourceData.Data));

                case "Int16":
                    return(Convert.ToInt16(sourceData.Data));

                case "Int64":
                    return(Convert.ToInt64(sourceData.Data));

                    break;

                case "Decimal":
                    return(Convert.ToDecimal(sourceData.Data));
                }
                break;

            case AMFDataType.Boolean:
            case AMFDataType.Date:
            case AMFDataType.LongString:
            case AMFDataType.String:
            case AMFDataType.Xml:
                return(sourceData.Data);

            case AMFDataType.Guid:
                return(new Guid(sourceData.Data.ToString()));
            }

            return(null);
        }
        public void WriteResponse()
        {
            //output the result to Flex
            Write(_envelope.Version);
            Write((byte)_envelope.ClientType);
            Write(Convert.ToUInt16(_envelope.Headers.Count));

            foreach (AMFHeader header in _envelope.Headers)
            {
                WriteUTF(header.Name);
                Write(header.MustUnderstand);
                Write(-1);
                WriteAMFData(header.Value.DataType, header.Value.Data);
            }

            Write(Convert.ToUInt16(_envelope.Bodies.Count));

            foreach (AMFBody body in _envelope.Bodies)
            {
                WriteUTF(body.ResponseId + "/onResult");
                WriteUTF("null");
                Write(-1);

                if (body.ReturnValue == null)
                {
                    Write((byte)AMFDataType.Null);
                }
                else
                {
                    //is this AMFDATA
                    if (body.ReturnValue is AMFData)
                    {
                        AMFData amfData = body.ReturnValue as AMFData;
                        WriteAMFData(amfData.DataType, amfData.Data);
                    }
                    else
                    {
                        ProcessUnknownObject(body.ReturnValue);
                    }
                }
            }
        }
        private void WriteMixedArray(Dictionary <string, object> properties)
        {
            //always let them know we don't have any numeric indexes
            //this way it is all keyed as strings
            Write(Convert.ToUInt32(0));

            if (properties == null)
            {
                Write(Convert.ToUInt16(0));
                Write((byte)AMFDataType.EndOfObject);
                return;
            }

            foreach (KeyValuePair <string, object> kvp in properties)
            {
                WriteUTF(kvp.Key);

                AMFData data = kvp.Value as AMFData;
                if (data == null)
                {
                    if (kvp.Value == null)
                    {
                        Write((byte)AMFDataType.Null);
                    }
                    else
                    {
                        ProcessUnknownObject(kvp.Value);
                    }
                }
                else
                {
                    WriteAMFData(data.DataType, data.Data);
                }
            }

            Write(Convert.ToUInt16(0));
            Write((byte)AMFDataType.EndOfObject);
        }
        public void AddProperty(string name, AMFDataType type, object value)
        {
            AMFData data = new AMFData(type, value);

            Properties[name] = data;
        }
Beispiel #7
0
        private static void DeserializeFields(ActionScriptObject aso, Type type, object instance)
        {
            //get the custom attributes of the object
            FieldInfo[] fields = type.GetFields();
            if (fields != null)
            {
                foreach (FieldInfo field in fields)
                {
                    object[] attributes = field.GetCustomAttributes(typeof(AMFProperty), true);
                    if (attributes != null)
                    {
                        foreach (AMFProperty propertyAttribute in attributes)
                        {
                            string      key          = propertyAttribute.Name;
                            AMFDataType propertyType = propertyAttribute.ActionScriptDataType;

                            //if we don't have let default value take over
                            if (!aso.Properties.ContainsKey(key))
                            {
                                continue;
                            }

                            AMFData data = aso.Properties[key] as AMFData;

                            if (data.Data == null)
                            {
                                continue;
                            }

                            switch (propertyType)
                            {
                            case AMFDataType.AMFEnabledObject:
                                if (field.FieldType.Name == "Object")
                                {
                                    field.SetValue(instance, data.Data);
                                }
                                else
                                {
                                    field.SetValue(instance, Deserialize(data.Data as ActionScriptObject, field.FieldType));
                                }
                                break;

                            case AMFDataType.Array:
                                ArrayList al       = data.Data as ArrayList;
                                ArrayList alValues = new ArrayList();
                                if (al != null && al.Count > 0)
                                {
                                    object[] arrayItemAttributes = field.GetCustomAttributes(typeof(AMFArrayItem), true);

                                    Dictionary <string, Type> itemMap = new Dictionary <string, Type>();
                                    if (arrayItemAttributes != null)
                                    {
                                        foreach (AMFArrayItem arrayItemAttribute in arrayItemAttributes)
                                        {
                                            itemMap.Add(arrayItemAttribute.TypeName, arrayItemAttribute.TargetType);
                                        }
                                    }

                                    foreach (AMFData alData in al)
                                    {
                                        object dataValue = null;

                                        if (alData.Data is ActionScriptObject)
                                        {
                                            ActionScriptObject arrayItemASO = alData.Data as ActionScriptObject;
                                            if (itemMap.ContainsKey(arrayItemASO.TypeName))
                                            {
                                                dataValue = GetArrayElementValue(alData, itemMap[arrayItemASO.TypeName]);
                                            }
                                            else
                                            {
                                                dataValue = GetArrayElementValue(alData, field.FieldType.GetElementType());
                                            }
                                        }
                                        else
                                        {
                                            dataValue = GetArrayElementValue(alData, field.FieldType.GetElementType());
                                        }


                                        if (dataValue != null)
                                        {
                                            alValues.Add(dataValue);
                                        }
                                    }

                                    field.SetValue(instance, alValues.ToArray(field.FieldType.GetElementType()));
                                }
                                break;

                            case AMFDataType.Boolean:
                            case AMFDataType.LongString:
                            case AMFDataType.String:
                            case AMFDataType.UTCDate:
                            case AMFDataType.Date:
                                field.SetValue(instance, data.Data);
                                break;

                            case AMFDataType.Guid:
                                field.SetValue(instance, new Guid(data.Data.ToString()));
                                break;

                            case AMFDataType.Number:
                                switch (field.FieldType.Name)
                                {
                                case "Int32":
                                    field.SetValue(instance, Convert.ToInt32(data.Data));
                                    break;

                                case "Int16":
                                    field.SetValue(instance, Convert.ToInt16(data.Data));
                                    break;

                                case "Int64":
                                    field.SetValue(instance, Convert.ToInt64(data.Data));
                                    break;

                                case "Decimal":
                                    field.SetValue(instance, Convert.ToDecimal(data.Data));
                                    break;
                                }
                                break;
                            }
                        }
                    }
                }
            }
        }
Beispiel #8
0
        private AMFData ParseAMFDataForType(AMFDataType dataType)
        {
            AMFData data = new AMFData();

            data.DataType = dataType;

            switch (dataType)
            {
            case AMFDataType.AMF3:
                throw new Exception("Flex AMF3 is not supported");

            case AMFDataType.Array:
                data.Data = ReadArrayList();
                if (data.Data != null)
                {
                    _references[_references.Count] = data;
                }
                break;

            case AMFDataType.Boolean:
                data.Data = ReadBoolean();
                break;

            case AMFDataType.Date:

                double   millisecondsFromGroundZero = ReadDouble();
                DateTime adjusted = _groundZero.AddMilliseconds(millisecondsFromGroundZero);

                data          = new AMFDateData();
                data.DataType = dataType;
                data.Data     = adjusted;


                //read the timezone
                //comes in as minutes off of gmt
                int tzOffset = Convert.ToInt32(ReadUInt16());
                if (tzOffset > 720)     //per AMF anything over 12 hours is subtracted from 2^16
                {
                    tzOffset = (65536 - tzOffset) * -1;
                }

                int totalOffset = tzOffset * 60000 * -1;     //gives us total milliseconds offset

                //use the offset to add milliseconds to the date
                //adjusted.AddMilliseconds(totalOffset)
                ((AMFDateData)data).TimezoneOffset = totalOffset;
                if (adjusted == DateTime.MinValue)
                {
                    ((AMFDateData)data).ClientDate = DateTime.MinValue;
                }
                else
                {
                    ((AMFDateData)data).ClientDate = adjusted.AddMilliseconds(totalOffset);
                }

                //now we need to set the actual data to be represented
                //as a date for the server timezone
                data.Data = DateTime.Parse(data.Data.ToString(), null, System.Globalization.DateTimeStyles.AssumeUniversal);

                break;

            case AMFDataType.LongString:
                data.Data = ReadLongUTF();
                break;

            case AMFDataType.MixedArray:
                data.Data = ReadMixedArray();
                if (data.Data != null)
                {
                    _references[_references.Count] = data;
                }
                break;


            case AMFDataType.Number:
                data.Data = ReadDouble();
                break;

            case AMFDataType.Object:
                data.Data = ReadActionScriptObject(false);
                if (data.Data != null)
                {
                    _references[_references.Count] = data;
                }
                break;


            case AMFDataType.Reference:
                int referenceCounter = Convert.ToInt32(ReadUInt16()) - 1;
                if (!_references.ContainsKey(referenceCounter))
                {
                    return(null);
                }
                else
                {
                    data = _references[referenceCounter];
                }
                break;

            case AMFDataType.String:
                data.Data = ReadUTF();
                break;

            case AMFDataType.TypedObject:
                data.Data = ReadActionScriptObject(true);
                if (data.Data != null)
                {
                    _references[_references.Count] = data;
                }
                break;

            case AMFDataType.Xml:
                string      xml = ReadLongUTF();
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
                data.Data = doc;
                break;
            }

            return(data);
        }
        private void ProcessUnknownObject(object data)
        {
            //if no data, then get out
            if (data == null)
            {
                return;
            }

            //could be anything, but we are going to send it back
            //as a typed object
            Type t = data.GetType();

            object[] attributes = t.GetCustomAttributes(true);
            bool     ok         = false;

            ActionScriptObject aso = new ActionScriptObject();

            if (attributes != null)
            {
                foreach (Attribute attribute in attributes)
                {
                    if (attribute is AMFEnabled)
                    {
                        ok           = true;
                        aso.TypeName = ((AMFEnabled)attribute).ActionScriptTypeName;
                        break;
                    }
                }

                if (ok)
                {
                    //get the properties and fields for this type and then we can get those attributes
                    //that we need to export
                    FieldInfo[] fields = t.GetFields();
                    if (fields != null)
                    {
                        foreach (FieldInfo field in fields)
                        {
                            attributes = field.GetCustomAttributes(typeof(AMFProperty), true);
                            if (attributes != null)
                            {
                                foreach (AMFProperty propertyAttribute in attributes)
                                {
                                    string      key          = propertyAttribute.Name;
                                    AMFDataType propertyType = propertyAttribute.ActionScriptDataType;

                                    //get the value
                                    object propertyValue = field.GetValue(data);

                                    //save it
                                    AMFData amfData = new AMFData();
                                    amfData.DataType    = propertyType;
                                    amfData.Data        = propertyValue;
                                    aso.Properties[key] = amfData;
                                }
                            }
                        }
                    }

                    //do the same thing for the props
                    PropertyInfo[] properties = t.GetProperties();
                    if (properties != null)
                    {
                        foreach (PropertyInfo property in properties)
                        {
                            attributes = property.GetCustomAttributes(typeof(AMFProperty), true);
                            if (attributes != null)
                            {
                                foreach (AMFProperty propertyAttribute in attributes)
                                {
                                    string      key          = propertyAttribute.Name;
                                    AMFDataType propertyType = propertyAttribute.ActionScriptDataType;

                                    //get the value

                                    object propertyValue = property.GetValue(data, null);

                                    //save it
                                    AMFData amfData = new AMFData();
                                    amfData.DataType    = propertyType;
                                    amfData.Data        = propertyValue;
                                    aso.Properties[key] = amfData;
                                }
                            }
                        }
                    }
                }
            }

            if (!ok)
            {
                if (data is ActionScriptObject)
                {
                    WriteActionScriptObject(data as ActionScriptObject);
                }
                else if (data is int)
                {
                    Write((byte)AMFDataType.Number);
                    Write(Convert.ToDouble(data));
                }
                else
                {
                    throw new Exception("Type returned for Flex was not marked as AMFEnabled: " + t.ToString());
                }
            }
            else
            {
                WriteActionScriptObject(aso);
            }
        }