Example #1
0
 public void Reset()
 {
     numVal    = 0.0;
     stringVal = "";
     objVal    = null;
     type      = AMFDataType.AMF_INVALID;
 }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
        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.");
            }
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #8
0
        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);
        }
Example #9
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;
                            }
                        }
                    }
                }
            }
        }
Example #10
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);
        }
Example #11
0
        //look at the type code to determine what we are dealing with
        private AMFData ReadAMFData()
        {
            AMFDataType dataType = (AMFDataType)ReadByte();

            return(ParseAMFDataForType(dataType));
        }
 public void Reset()
 {
     numVal = 0.0;
     stringVal = "";
     objVal = null;
     type = AMFDataType.AMF_INVALID;
 }
        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;
            }
        }
Example #16
0
 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;
 }