Example #1
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);
        }