public void Reset() { numVal = 0.0; stringVal = ""; objVal = null; type = AMFDataType.AMF_INVALID; }
public override void call(string methodName, fMethodCallback callbackFunc, params object[] pobject) { outputBuff.Position = 0; AMFHeader header = new AMFHeader(AMFHeader.HEADER_12, 0x3); header.EndPoint = 0; header.TimeStamp = 1; header.RTMPType = AMFHeader.RTMP_TYPE_FUNCTION; header.BodySize = 0; AMFString func = new AMFString(methodName); func.write(outputBuff); outputBuff.Write(c_reserved, 0, c_reserved.Length); new AMFNull().write(outputBuff); foreach (object o in pobject) { AMFDataType dObj = AMFDataType.findDataHandler(o); dObj.write(outputBuff); } header.BodySize = (int)outputBuff.Position; chunkBufferAndSend(header); }
private object ReadActionScriptObject(bool typed) { ActionScriptObject aso = new ActionScriptObject(); if (typed) { aso.TypeName = ReadUTF(); } Dictionary <string, object> values = aso.Properties; //get the first key string key = ReadUTF(); //get the first type AMFDataType dataType = (AMFDataType)ReadByte(); while (dataType != AMFDataType.EndOfObject) { values[key] = ParseAMFDataForType(dataType); key = ReadUTF(); dataType = (AMFDataType)ReadByte(); } return(aso); }
public AMFProperty(AMFDataType type, string name) { ActionScriptDataType = type; Name = name; switch (type) { case AMFDataType.AMF3: case AMFDataType.EndOfObject: case AMFDataType.Movie: case AMFDataType.Null: case AMFDataType.Object: case AMFDataType.Recordset: case AMFDataType.Reference: case AMFDataType.TypedObject: case AMFDataType.Undefined: case AMFDataType.Unsupported: throw new Exception("The AMFDataType specified [" + type.ToString() + "] for [" + name + "] is not allowed for return to flex applications."); } }
private Dictionary <string, object> ReadMixedArray() { uint highestIndex = ReadUInt32(); //doesn't matter Dictionary <string, object> values = new Dictionary <string, object>(); //get the first key string key = ReadUTF(); //get the first type AMFDataType dataType = (AMFDataType)ReadByte(); while (dataType != AMFDataType.EndOfObject) { values[key] = ParseAMFDataForType(dataType); key = ReadUTF(); dataType = (AMFDataType)ReadByte(); } return(values); }
public int Decode(byte[] pBuffer, int bufferOffset, int nSize, bool bDecodeName) { int nOriginalSize = nSize; if (nSize == 0 || pBuffer == null) return -1; if (pBuffer[bufferOffset] == 0x05) { m_type = AMFDataType.AMF_NULL; return 1; } if (bDecodeName && nSize < 4) // at least name (length + at least 1 byte) and 1 byte of data return -1; if (bDecodeName) { ushort nNameSize = RTMP.ReadInt16(pBuffer, bufferOffset); if (nNameSize > nSize - (short)sizeof(short)) return -1; m_strName = RTMP.ReadString(pBuffer, bufferOffset); nSize -= sizeof(short) + m_strName.Length; bufferOffset += sizeof(short) + m_strName.Length; } if (nSize == 0) return -1; nSize--; switch (pBuffer[bufferOffset]) { case (byte)AMFDataType.AMF_NUMBER: if (nSize < (int)sizeof(double)) return -1; m_dNumVal = RTMP.ReadNumber(pBuffer, bufferOffset + 1); nSize -= sizeof(double); m_type = AMFDataType.AMF_NUMBER; break; case (byte)AMFDataType.AMF_BOOLEAN: if (nSize < 1) return -1; m_dNumVal = Convert.ToDouble(RTMP.ReadBool(pBuffer, bufferOffset + 1)); nSize--; m_type = AMFDataType.AMF_BOOLEAN; break; case (byte)AMFDataType.AMF_STRING: { ushort nStringSize = RTMP.ReadInt16(pBuffer, bufferOffset + 1); if (nSize < nStringSize + (int)sizeof(short)) return -1; m_strVal = RTMP.ReadString(pBuffer, bufferOffset + 1); nSize -= sizeof(short) + nStringSize; m_type = AMFDataType.AMF_STRING; break; } case (byte)AMFDataType.AMF_OBJECT: { m_objVal = new AMFObject(); int nRes = m_objVal.Decode(pBuffer, bufferOffset + 1, nSize, true); if (nRes == -1) return -1; nSize -= nRes; m_type = AMFDataType.AMF_OBJECT; break; } case (byte)AMFDataType.AMF_MOVIECLIP: { Logger.Log("AMF_MOVIECLIP reserved!"); return -1; } case (byte)AMFDataType.AMF_NULL: case (byte)AMFDataType.AMF_UNDEFINED: case (byte)AMFDataType.AMF_UNSUPPORTED: { m_type = AMFDataType.AMF_NULL; break; } case (byte)AMFDataType.AMF_REFERENCE: { Logger.Log("AMF_REFERENCE not supported!"); return -1; } case (byte)AMFDataType.AMF_ECMA_ARRAY: { //int nMaxIndex = RTMP_LIB::CRTMP::ReadInt32(pBuffer+1); // can be zero for unlimited nSize -= 4; // next comes the rest, mixed array has a final 0x000009 mark and names, so its an object m_objVal = new AMFObject(); int nRes = m_objVal.Decode(pBuffer, bufferOffset + 5, nSize, true); if (nRes == -1) return -1; nSize -= nRes; m_type = AMFDataType.AMF_OBJECT; break; } case (byte)AMFDataType.AMF_OBJECT_END: { return -1; } case (byte)AMFDataType.AMF_STRICT_ARRAY: { int nArrayLen = RTMP.ReadInt32(pBuffer, bufferOffset + 1); nSize -= 4; m_objVal = new AMFObject(); int nRes = m_objVal.DecodeArray(pBuffer, bufferOffset + 5, nSize, nArrayLen, false); if (nRes == -1) return -1; nSize -= nRes; m_type = AMFDataType.AMF_OBJECT; break; } case (byte)AMFDataType.AMF_DATE: { if (nSize < 10) return -1; p_number = RTMP.ReadNumber(pBuffer, bufferOffset + 1); p_UTCoffset = RTMP.ReadInt16(pBuffer, bufferOffset + 9); nSize -= 10; break; } case (byte)AMFDataType.AMF_LONG_STRING: { int nStringSize = RTMP.ReadInt32(pBuffer, bufferOffset + 1); if (nSize < nStringSize + 4) return -1; m_strVal = RTMP.ReadLongString(pBuffer, bufferOffset + 1); nSize -= (4 + nStringSize); m_type = AMFDataType.AMF_STRING; break; } case (byte)AMFDataType.AMF_RECORDSET: { Logger.Log("AMF_RECORDSET reserved!"); return -1; } case (byte)AMFDataType.AMF_XML_DOC: { Logger.Log("AMF_XML_DOC not supported!"); return -1; } case (byte)AMFDataType.AMF_TYPED_OBJECT: { Logger.Log("AMF_TYPED_OBJECT not supported!"); return -1; } default: Logger.Log(string.Format("unknown datatype {0}", pBuffer[bufferOffset])); return -1; } return nOriginalSize - nSize; }
private static ActionScriptObject ProcessDataTable(DataTable dt) { ActionScriptObject aso = new ActionScriptObject(); aso.TypeName = "Kamacho.DNF.DTO.DataTableDTO"; List <ActionScriptObject> columns = new List <ActionScriptObject>(); //now go through the columns Dictionary <string, AMFDataType> dataTypes = new Dictionary <string, AMFDataType>(); foreach (DataColumn dc in dt.Columns) { ActionScriptObject column = new ActionScriptObject(); column.TypeName = "Kamacho.DNF.DTO.DataColumnDTO"; column.Properties.Add("name", new AMFData(AMFDataType.String, dc.ColumnName)); AMFDataType columnType = AMFDataType.Unsupported; Type dataType = dc.DataType; if (dataType == typeof(Boolean)) { columnType = AMFDataType.Boolean; } else if (dataType == typeof(String)) { columnType = AMFDataType.LongString; } else if (dataType == typeof(DateTime)) { columnType = AMFDataType.Date; } else if (dataType == typeof(Byte) || dataType == typeof(Decimal) || dataType == typeof(Double) || dataType == typeof(Int16) || dataType == typeof(Int32) || dataType == typeof(SByte) || dataType == typeof(Single) || dataType == typeof(TimeSpan) || dataType == typeof(UInt16) || dataType == typeof(UInt32) || dataType == typeof(UInt64)) { columnType = AMFDataType.Number; } else { columnType = AMFDataType.String; } column.Properties.Add("dataType", new AMFData(AMFDataType.String, columnType)); dataTypes.Add(dc.ColumnName, columnType); columns.Add(column); } aso.Properties.Add("columns", new AMFData(AMFDataType.Array, columns)); //now we can go through the rows List <ActionScriptObject> rows = new List <ActionScriptObject>(); foreach (DataRow dr in dt.Rows) { ActionScriptObject row = new ActionScriptObject(); row.TypeName = "Kamacho.DNF.DTO.DataRowDTO"; //get the values for the row List <ActionScriptObject> values = new List <ActionScriptObject>(); foreach (DataColumn dc2 in dt.Columns) { ActionScriptObject rowValue = new ActionScriptObject(); rowValue.TypeName = "Kamacho.DNF.DTO.DataRowValueDTO"; rowValue.Properties.Add("name", new AMFData(AMFDataType.String, dc2.ColumnName)); rowValue.Properties.Add("data", new AMFData(dataTypes[dc2.ColumnName], dr[dc2])); values.Add(rowValue); } row.Properties.Add("values", new AMFData(AMFDataType.Array, values)); rows.Add(row); } aso.Properties.Add("rows", new AMFData(AMFDataType.Array, rows)); return(aso); }
public int Decode(byte[] buffer, int bufferOffset, int size, bool bDecodeName) { int originalSize = size; if (size == 0 || buffer == null) { return(-1); } if (buffer[bufferOffset] == 0x05) { type = AMFDataType.AMF_NULL; return(1); } if (bDecodeName && size < 4) // at least name (length + at least 1 byte) and 1 byte of data { return(-1); } if (bDecodeName) { ushort nNameSize = RTMPHelper.ReadInt16(buffer, bufferOffset); if (nNameSize > size - (short)sizeof(short)) { return(-1); } stringName = RTMPHelper.ReadString(buffer, bufferOffset); size -= sizeof(short) + stringName.Length; bufferOffset += sizeof(short) + stringName.Length; } if (size == 0) { return(-1); } size--; int stringSize = 0; int result = 0; switch (buffer[bufferOffset]) { case (byte)AMFDataType.AMF_NUMBER: if (size < (int)sizeof(double)) { return(-1); } numVal = RTMPHelper.ReadNumber(buffer, bufferOffset + 1); size -= sizeof(double); type = AMFDataType.AMF_NUMBER; break; case (byte)AMFDataType.AMF_BOOLEAN: if (size < 1) { return(-1); } numVal = Convert.ToDouble(RTMPHelper.ReadBool(buffer, bufferOffset + 1)); size--; type = AMFDataType.AMF_BOOLEAN; break; case (byte)AMFDataType.AMF_STRING: stringSize = RTMPHelper.ReadInt16(buffer, bufferOffset + 1); if (size < stringSize + (int)sizeof(short)) { return(-1); } stringVal = RTMPHelper.ReadString(buffer, bufferOffset + 1); size -= sizeof(short) + stringSize; type = AMFDataType.AMF_STRING; break; case (byte)AMFDataType.AMF_OBJECT: objVal = new AMFObject(); result = objVal.Decode(buffer, bufferOffset + 1, size, true); if (result == -1) { return(-1); } size -= result; type = AMFDataType.AMF_OBJECT; break; case (byte)AMFDataType.AMF_MOVIECLIP: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMF_MOVIECLIP reserved!"); return(-1); case (byte)AMFDataType.AMF_NULL: case (byte)AMFDataType.AMF_UNDEFINED: case (byte)AMFDataType.AMF_UNSUPPORTED: type = AMFDataType.AMF_NULL; break; case (byte)AMFDataType.AMF_REFERENCE: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMF_REFERENCE not supported!"); return(-1); case (byte)AMFDataType.AMF_ECMA_ARRAY: size -= 4; // next comes the rest, mixed array has a final 0x000009 mark and names, so its an object objVal = new AMFObject(); result = objVal.Decode(buffer, bufferOffset + 5, size, true); if (result == -1) { return(-1); } size -= result; type = AMFDataType.AMF_OBJECT; break; case (byte)AMFDataType.AMF_OBJECT_END: return(-1); case (byte)AMFDataType.AMF_STRICT_ARRAY: int nArrayLen = RTMPHelper.ReadInt32(buffer, bufferOffset + 1); size -= 4; objVal = new AMFObject(); result = objVal.DecodeArray(buffer, bufferOffset + 5, size, nArrayLen, false); if (result == -1) { return(-1); } size -= result; type = AMFDataType.AMF_OBJECT; break; case (byte)AMFDataType.AMF_DATE: if (size < 10) { return(-1); } date = RTMPHelper.ReadNumber(buffer, bufferOffset + 1); dateUTCOffset = RTMPHelper.ReadInt16(buffer, bufferOffset + 9); size -= 10; break; case (byte)AMFDataType.AMF_LONG_STRING: stringSize = RTMPHelper.ReadInt32(buffer, bufferOffset + 1); if (size < stringSize + 4) { return(-1); } stringVal = RTMPHelper.ReadLongString(buffer, bufferOffset + 1); size -= (4 + stringSize); type = AMFDataType.AMF_STRING; break; case (byte)AMFDataType.AMF_RECORDSET: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMFObjectProperty.Decode AMF_RECORDSET reserved!"); return(-1); case (byte)AMFDataType.AMF_XML_DOC: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMFObjectProperty.Decode AMF_XML_DOC not supported!"); return(-1); case (byte)AMFDataType.AMF_TYPED_OBJECT: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMFObjectProperty.Decode AMF_TYPED_OBJECT not supported!"); return(-1); default: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, string.Format("AMFObjectProperty.Decode Unknown datatype {0}", buffer[bufferOffset])); return(-1); } //switch return(originalSize - size); }
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; } } } } } }
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); }
//look at the type code to determine what we are dealing with private AMFData ReadAMFData() { AMFDataType dataType = (AMFDataType)ReadByte(); return(ParseAMFDataForType(dataType)); }
public int Decode(byte[] buffer, int bufferOffset, int size, bool bDecodeName) { int originalSize = size; if (size == 0 || buffer == null) { return -1; } if (buffer[bufferOffset] == 0x05) { type = AMFDataType.AMF_NULL; return 1; } if (bDecodeName && size < 4) // at least name (length + at least 1 byte) and 1 byte of data { return -1; } if (bDecodeName) { ushort nNameSize = RTMPHelper.ReadInt16(buffer, bufferOffset); if (nNameSize > size - (short)sizeof(short)) { return -1; } stringName = RTMPHelper.ReadString(buffer, bufferOffset); size -= sizeof(short) + stringName.Length; bufferOffset += sizeof(short) + stringName.Length; } if (size == 0) { return -1; } size--; int stringSize = 0; int result = 0; switch (buffer[bufferOffset]) { case (byte)AMFDataType.AMF_NUMBER: if (size < (int)sizeof(double)) { return -1; } numVal = RTMPHelper.ReadNumber(buffer, bufferOffset + 1); size -= sizeof(double); type = AMFDataType.AMF_NUMBER; break; case (byte)AMFDataType.AMF_BOOLEAN: if (size < 1) { return -1; } numVal = Convert.ToDouble(RTMPHelper.ReadBool(buffer, bufferOffset + 1)); size--; type = AMFDataType.AMF_BOOLEAN; break; case (byte)AMFDataType.AMF_STRING: stringSize = RTMPHelper.ReadInt16(buffer, bufferOffset + 1); if (size < stringSize + (int)sizeof(short)) { return -1; } stringVal = RTMPHelper.ReadString(buffer, bufferOffset + 1); size -= sizeof(short) + stringSize; type = AMFDataType.AMF_STRING; break; case (byte)AMFDataType.AMF_OBJECT: objVal = new AMFObject(); result = objVal.Decode(buffer, bufferOffset + 1, size, true); if (result == -1) { return -1; } size -= result; type = AMFDataType.AMF_OBJECT; break; case (byte)AMFDataType.AMF_MOVIECLIP: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMF_MOVIECLIP reserved!"); return -1; case (byte)AMFDataType.AMF_NULL: case (byte)AMFDataType.AMF_UNDEFINED: case (byte)AMFDataType.AMF_UNSUPPORTED: type = AMFDataType.AMF_NULL; break; case (byte)AMFDataType.AMF_REFERENCE: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMF_REFERENCE not supported!"); return -1; case (byte)AMFDataType.AMF_ECMA_ARRAY: size -= 4; // next comes the rest, mixed array has a final 0x000009 mark and names, so its an object objVal = new AMFObject(); result = objVal.Decode(buffer, bufferOffset + 5, size, true); if (result == -1) { return -1; } size -= result; type = AMFDataType.AMF_OBJECT; break; case (byte)AMFDataType.AMF_OBJECT_END: return -1; case (byte)AMFDataType.AMF_STRICT_ARRAY: int nArrayLen = RTMPHelper.ReadInt32(buffer, bufferOffset + 1); size -= 4; objVal = new AMFObject(); result = objVal.DecodeArray(buffer, bufferOffset + 5, size, nArrayLen, false); if (result == -1) { return -1; } size -= result; type = AMFDataType.AMF_OBJECT; break; case (byte)AMFDataType.AMF_DATE: if (size < 10) { return -1; } date = RTMPHelper.ReadNumber(buffer, bufferOffset + 1); dateUTCOffset = RTMPHelper.ReadInt16(buffer, bufferOffset + 9); size -= 10; break; case (byte)AMFDataType.AMF_LONG_STRING: stringSize = RTMPHelper.ReadInt32(buffer, bufferOffset + 1); if (size < stringSize + 4) { return -1; } stringVal = RTMPHelper.ReadLongString(buffer, bufferOffset + 1); size -= (4 + stringSize); type = AMFDataType.AMF_STRING; break; case (byte)AMFDataType.AMF_RECORDSET: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMFObjectProperty.Decode AMF_RECORDSET reserved!"); return -1; case (byte)AMFDataType.AMF_XML_DOC: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMFObjectProperty.Decode AMF_XML_DOC not supported!"); return -1; case (byte)AMFDataType.AMF_TYPED_OBJECT: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, "AMFObjectProperty.Decode AMF_TYPED_OBJECT not supported!"); return -1; default: LibRTMPLogger.Log(LibRTMPLogLevel.Trace, string.Format("AMFObjectProperty.Decode Unknown datatype {0}", buffer[bufferOffset])); return -1; } //switch return originalSize - size; }
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); } }
private void WriteAMFData(AMFDataType dataType, object data) { switch (dataType) { case AMFDataType.AMF3: case AMFDataType.Movie: case AMFDataType.Null: case AMFDataType.Recordset: case AMFDataType.Reference: case AMFDataType.Undefined: case AMFDataType.Unsupported: Write((byte)AMFDataType.Null); break; case AMFDataType.Array: Write((byte)AMFDataType.Array); WriteArray((IList)data); break; case AMFDataType.Boolean: Write((byte)AMFDataType.Boolean); Write((bool)data); break; case AMFDataType.Date: Write((byte)AMFDataType.Date); DateTime date = ((DateTime)data).ToUniversalTime(); TimeSpan millisecondsSinceGroundZero = date.Subtract(_groundZero); Write(millisecondsSinceGroundZero.TotalMilliseconds); //don't have the timezone, so we will just fake one Write(Convert.ToUInt16(0)); break; case AMFDataType.UTCDate: //treat date time as a UTC date Write((byte)AMFDataType.Date); DateTime localDate = ((DateTime)data); TimeSpan localMillisecondsSinceGroundZero = localDate.Subtract(_localGroundZero); Write(localMillisecondsSinceGroundZero.TotalMilliseconds); //don't have the timezone, so we will just fake one Write(Convert.ToUInt16(0)); break; case AMFDataType.LongString: Write((byte)AMFDataType.LongString); WriteLongUTF((string)data); break; case AMFDataType.MixedArray: Write((byte)AMFDataType.MixedArray); WriteMixedArray(data as Dictionary <string, object>); break; case AMFDataType.Number: Write((byte)AMFDataType.Number); Write(Convert.ToDouble(data)); break; case AMFDataType.Object: WriteActionScriptObject(data as ActionScriptObject); break; case AMFDataType.String: Write((byte)AMFDataType.String); WriteUTF((string)data); break; case AMFDataType.Guid: Write((byte)AMFDataType.String); WriteUTF(data.ToString()); break; case AMFDataType.TypedObject: WriteActionScriptObject(data as ActionScriptObject); break; case AMFDataType.Xml: Write((byte)AMFDataType.Xml); XmlDocument doc = data as XmlDocument; if (doc == null) { WriteLongUTF(string.Empty); } else { WriteLongUTF(doc.OuterXml); } break; } }
public void Reset() { m_dNumVal = 0.0; m_strVal = ""; m_objVal = null; m_type = AMFDataType.AMF_INVALID; }
public void AddProperty(string name, AMFDataType type, object value) { AMFData data = new AMFData(type, value); Properties[name] = data; }
public AMFData(AMFDataType type, object data) { DataType = type; Data = data; }