Beispiel #1
0
        /// <summary> int AMF_DecodeArray(AMFObject * obj, const char *pBuffer, int nSize,int nArrayLen, int bDecodeName); </summary>
        public static int AMF_DecodeArray(AMFObject obj, byte[] buf, int pBuffer, int nSize, int nArrayLen, bool bDecodeName)
        {
            int  nOriginalSize = nSize;
            bool bError        = false;

            obj.o_num   = 0;
            obj.o_props = null;
            while (nArrayLen > 0)
            {
                AMFObjectProperty prop = new AMFObjectProperty();

                nArrayLen--;

                int nRes = AMFObjectProperty.AMFProp_Decode(prop, buf, pBuffer, nSize, bDecodeName);
                if (nRes == -1)
                {
                    bError = true;
                }
                else
                {
                    nSize   -= nRes;
                    pBuffer += nRes;
                    AMF_AddProp(obj, prop);
                }
            }

            if (bError)
            {
                return(-1);
            }

            return(nOriginalSize - nSize);
        }
Beispiel #2
0
        /// <summary> void AMF_AddProp(AMFObject * obj, const AMFObjectProperty * prop); </summary>
        public static void AMF_AddProp(AMFObject obj, AMFObjectProperty prop)
        {
            if (obj.o_props == null)
            {
                obj.o_props = new List <AMFObjectProperty>();
            }

            obj.o_props.Add(prop);
            obj.o_num++;
        }
Beispiel #3
0
        /// <summary> void AMF_Dump(AMFObject* obj); </summary>
        public static void AMF_Dump(AMFObject obj)
        {
            Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "(object begin)");
            for (var n = 0; n < obj.o_num; n++)
            {
                AMFObjectProperty.AMFProp_Dump(obj.o_props[n]);
            }

            Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "(object end)");
        }
Beispiel #4
0
        /// <summary> void AMF_Reset(AMFObject * obj); </summary>
        public static void AMF_Reset(AMFObject obj)
        {
            for (var n = 0; n < obj.o_num; n++)
            {
                AMFObjectProperty.AMFProp_Reset(obj.o_props[n]);
            }

            // free(obj.o_props);
            obj.o_props = new List <AMFObjectProperty>();
            obj.o_num   = 0;
        }
Beispiel #5
0
        /// <summary> void AMFProp_Reset(AMFObjectProperty* prop) </summary>
        public static void AMFProp_Reset(AMFObjectProperty prop)
        {
            if (prop.p_type == AMFDataType.AMF_OBJECT ||
                prop.p_type == AMFDataType.AMF_ECMA_ARRAY ||
                prop.p_type == AMFDataType.AMF_STRICT_ARRAY)
            {
                AMFObject.AMF_Reset(prop.p_object);
            }
            else
            {
                prop.p_aval = null;
            }

            prop.p_type = AMFDataType.AMF_INVALID;
        }
Beispiel #6
0
        // char* AMF_Encode(AMFObject* obj, char* pBuffer, char* pBufEnd);
        // char* AMF_EncodeEcmaArray(AMFObject* obj, char* pBuffer, char* pBufEnd);
        // char* AMF_EncodeArray(AMFObject* obj, char* pBuffer, char* pBufEnd);

        /// <summary> int AMF_Decode(AMFObject * obj, const char *pBuffer, int nSize, int bDecodeName); </summary>
        public static int AMF_Decode(AMFObject obj, byte[] buf, int pbuf, int nSize, bool bDecodeName)
        {
            int  nOriginalSize = nSize;
            bool bError        = false; /* if there is an error while decoding - try to at least find the end mark AMF_OBJECT_END */

            obj.o_num   = 0;
            obj.o_props = null;
            while (nSize > 0)
            {
                if (nSize >= 3)
                {
                    if (AMF.AMF_DecodeInt24(buf, pbuf) == (uint)AMFDataType.AMF_OBJECT_END)
                    {
                        nSize -= 3;
                        bError = false;
                        break;
                    }
                }

                if (bError)
                {
                    Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGERROR, "DECODING ERROR, IGNORING BYTES UNTIL NEXT KNOWN PATTERN!");
                    nSize--;
                    pbuf++;
                    continue;
                }

                AMFObjectProperty prop = new AMFObjectProperty();
                int nRes = AMFObjectProperty.AMFProp_Decode(prop, buf, pbuf, nSize, bDecodeName);
                if (nRes == -1)
                {
                    bError = true;
                }
                else
                {
                    nSize -= nRes;
                    pbuf  += nRes;
                    AMF_AddProp(obj, prop);
                }
            }

            if (bError)
            {
                return(-1);
            }

            return(nOriginalSize - nSize);
        }
Beispiel #7
0
        /// <summary> AMFObjectProperty *AMF_GetProp(AMFObject * obj, const AVal * name, int nIndex); </summary>
        public static AMFObjectProperty AMF_GetProp(AMFObject obj, AVal name, int nIndex)
        {
            if (nIndex >= 0)
            {
                if (nIndex < obj.o_num)
                {
                    return(obj.o_props[nIndex]);
                }
            }
            else
            {
                for (var n = 0; n < obj.o_num; n++)
                {
                    if (AVal.Match(obj.o_props[n].p_name, name))
                    {
                        return(obj.o_props[n]);
                    }
                }
            }

            // return (AMFObjectProperty*)&AMFProp_Invalid;
            return(AMFObjectProperty.AMFProp_Invalid);
        }
Beispiel #8
0
 /// <summary> void AMFProp_SetObject(AMFObjectProperty* prop, AMFObject* obj); </summary>
 public static void AMFProp_SetObject(AMFObjectProperty prop, AMFObject obj)
 {
     throw new NotImplementedException();
 }
Beispiel #9
0
 public AMFObjectProperty()
 {
     p_name   = new AVal();
     p_aval   = new AVal();
     p_object = new AMFObject();
 }
Beispiel #10
0
        /// <summary> void AMFProp_Dump(AMFObjectProperty *prop) </summary>
        public static void AMFProp_Dump(AMFObjectProperty prop)
        {
            if (prop.p_type == AMFDataType.AMF_INVALID)
            {
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "Property: INVALID");
                return;
            }

            if (prop.p_type == AMFDataType.AMF_NULL)
            {
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "Property: NULL");
                return;
            }

            var name = prop.p_name.av_len != 0 ? prop.p_name : AVal.AVC("no-name.");

            if (name.av_len > 18)
            {
                name.av_len = 18;
            }

            // snprintf(strRes, 255, "Name: %18.*s, ", name.av_len, name.av_val);
            var strRes = string.Format("Name: {0,18}, ", name.to_s(18));

            if (prop.p_type == AMFDataType.AMF_OBJECT)
            {
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "Property: <{0}OBJECT>", strRes);
                AMFObject.AMF_Dump(prop.p_object);
                return;
            }

            if (prop.p_type == AMFDataType.AMF_ECMA_ARRAY)
            {
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "Property: <{0}ECMA_ARRAY>", strRes);
                AMFObject.AMF_Dump(prop.p_object);
                return;
            }

            if (prop.p_type == AMFDataType.AMF_STRICT_ARRAY)
            {
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "Property: <{0}STRICT_ARRAY>", strRes);
                AMFObject.AMF_Dump(prop.p_object);
                return;
            }

            string str;

            switch (prop.p_type)
            {
            case AMFDataType.AMF_NUMBER:
                // snprintf(str, 255, "NUMBER:\t%.2f", prop.p_vu.p_number);
                str = string.Format("NUMBER:\t{0:F2}", prop.p_number);
                break;

            case AMFDataType.AMF_BOOLEAN:
                // snprintf(str, 255, "BOOLEAN:\t%s", prop.p_vu.p_number != 0.0 ? "TRUE" : "FALSE");
                str = string.Format("BOOLEAN:\t{0}", prop.p_number != 0.0 ? "TRUE" : "FALSE");
                break;

            case AMFDataType.AMF_STRING:
                // snprintf(str, 255, "STRING:\t%.*s", prop.p_vu.p_aval.av_len, prop.p_vu.p_aval.av_val);
                str = string.Format("STRING:\t{0}", prop.p_aval.to_s());
                break;

            case AMFDataType.AMF_DATE:
                // snprintf(str, 255, "DATE:\ttimestamp: %.2f, UTC offset: %d", prop.p_vu.p_number, prop.p_UTCoffset);
                str = string.Format("DATE:\ttimestamp: {0:F2}, UTC offset: {1}", prop.p_number, prop.p_UTCoffset);
                break;

            default:
                // snprintf(str, 255, "INVALID TYPE 0x%02x", (unsigned char )prop.p_type);
                str = string.Format("INVALID TYPE 0x{0:x2}", prop.p_type);
                break;
            }

            Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "Property: <{0}{1}>", strRes, str);
        }
Beispiel #11
0
        /// <summary> int AMFProp_Decode(AMFObjectProperty *prop, const char *pBuffer, int nSize, int bDecodeName)</summary>
        public static int AMFProp_Decode(AMFObjectProperty prop, byte[] buf, int pBuffer, int nSize, bool bDecodeName)
        {
            const string __FUNCTION__  = "AMFProp_Decode";
            int          nOriginalSize = nSize;

            prop.p_name = new AVal();

            if (nSize == 0 || pBuffer > buf.Length)
            {
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "{0}: Empty buffer/no buffer pointer!", __FUNCTION__);
                return(-1);
            }

            if (bDecodeName && nSize < 4)
            {
                /* at least name (length + at least 1 byte) and 1 byte of data */
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "{0}: Not enough data for decoding with name, less than 4 bytes!", __FUNCTION__);
                return(-1);
            }

            if (bDecodeName)
            {
                var nNameSize = AMF.AMF_DecodeInt16(buf, pBuffer);
                if (nNameSize > nSize - 2)
                {
                    Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG,
                                 "{0}: Name size out of range: namesize ({1}) > len ({2}) - 2",
                                 __FUNCTION__, nNameSize, nSize);
                    return(-1);
                }

                AVal name;
                AMF.AMF_DecodeString(buf, pBuffer, out name);
                prop.p_name = name;
                nSize      -= 2 + nNameSize;
                pBuffer    += 2 + nNameSize;
            }

            if (nSize == 0)
            {
                return(-1);
            }

            nSize--;

            prop.p_type = (AMFDataType)buf[pBuffer++]; // *pBuffer++;
            switch (prop.p_type)
            {
            case AMFDataType.AMF_NUMBER:
                if (nSize < 8)
                {
                    return(-1);
                }

                prop.p_number = AMF.AMF_DecodeNumber(buf, pBuffer);
                nSize        -= 8;
                break;

            case AMFDataType.AMF_BOOLEAN:
                if (nSize < 1)
                {
                    return(-1);
                }

                prop.p_number = AMF.AMF_DecodeBoolean(buf, pBuffer) ? 1 : 0;
                nSize--;
                break;

            case AMFDataType.AMF_STRING:
            {
                var nStringSize = AMF.AMF_DecodeInt16(buf, pBuffer);

                if (nSize < (long)nStringSize + 2)
                {
                    return(-1);
                }

                AVal v;
                AMF.AMF_DecodeString(buf, pBuffer, out v);
                prop.p_aval = v;
                nSize      -= (2 + nStringSize);
                break;
            }

            case AMFDataType.AMF_OBJECT:
            {
                int nRes = AMFObject.AMF_Decode(prop.p_object, buf, pBuffer, nSize, true);
                if (nRes == -1)
                {
                    return(-1);
                }

                nSize -= nRes;
                break;
            }

            case AMFDataType.AMF_MOVIECLIP:
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGERROR, "AMF_MOVIECLIP reserved!");
                return(-1);

            case AMFDataType.AMF_NULL:
            case AMFDataType.AMF_UNDEFINED:
            case AMFDataType.AMF_UNSUPPORTED:
                prop.p_type = AMFDataType.AMF_NULL;
                break;

            case AMFDataType.AMF_REFERENCE:
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGERROR, "AMF_REFERENCE not supported!");
                return(-1);

            case AMFDataType.AMF_ECMA_ARRAY:
            {
                nSize -= 4;

                /* next comes the rest, mixed array has a final 0x000009 mark and names, so its an object */
                var nRes = AMFObject.AMF_Decode(prop.p_object, buf, pBuffer + 4, nSize, true);
                if (nRes == -1)
                {
                    return(-1);
                }

                nSize -= nRes;
            }
            break;

            case AMFDataType.AMF_OBJECT_END:
                return(-1);

            case AMFDataType.AMF_STRICT_ARRAY:
            {
                var nArrayLen = AMF.AMF_DecodeInt32(buf, pBuffer);
                nSize -= 4;

                var nRes = AMFObject.AMF_DecodeArray(prop.p_object, buf, pBuffer + 4, nSize, (int)nArrayLen, false);
                if (nRes == -1)
                {
                    return(-1);
                }

                nSize -= nRes;
            }
            break;

            case AMFDataType.AMF_DATE:
            {
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "AMF_DATE");

                if (nSize < 10)
                {
                    return(-1);
                }

                prop.p_number    = AMF.AMF_DecodeNumber(buf, pBuffer);
                prop.p_UTCoffset = (short)AMF.AMF_DecodeInt16(buf, pBuffer + 8);

                nSize -= 10;
                break;
            }

            case AMFDataType.AMF_LONG_STRING:
            case AMFDataType.AMF_XML_DOC:
            {
                var nStringSize = AMF.AMF_DecodeInt32(buf, pBuffer);
                if (nSize < (long)nStringSize + 4)
                {
                    return(-1);
                }

                AVal v;
                AMF.AMF_DecodeLongString(buf, pBuffer, out v);
                prop.p_aval = v;
                nSize      -= (int)(4 + nStringSize);
                if (prop.p_type == AMFDataType.AMF_LONG_STRING)
                {
                    prop.p_type = AMFDataType.AMF_STRING;
                }

                break;
            }

            case AMFDataType.AMF_RECORDSET:
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGERROR, "AMF_RECORDSET reserved!");
                return(-1);

            case AMFDataType.AMF_TYPED_OBJECT:
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGERROR, "AMF_TYPED_OBJECT not supported!");
                return(-1);

            case AMFDataType.AMF_AVMPLUS:
            {
                var nRes = AMFObject.AMF3_Decode(prop.p_object, buf, pBuffer, nSize, true);
                if (nRes == -1)
                {
                    return(-1);
                }
                nSize      -= nRes;
                prop.p_type = AMFDataType.AMF_OBJECT;
                break;
            }

            default:
                Log.RTMP_Log(Log.RTMP_LogLevel.RTMP_LOGDEBUG, "{0} - unknown datatype 0x{1:x2}, @{2}", __FUNCTION__, prop.p_type, pBuffer - 1);
                return(-1);
            }

            return(nOriginalSize - nSize);
        }
Beispiel #12
0
 /// <summary> void AMFProp_GetObject(AMFObjectProperty* prop, AMFObject* obj); </summary>
 public static void AMFProp_GetObject(AMFObjectProperty prop, out AMFObject obj)
 {
     obj = prop.p_object;
 }
Beispiel #13
0
 /// <summary> int AMF_CountProp(AMFObject * obj); </summary>
 public static int AMF_CountProp(AMFObject o)
 {
     throw new NotImplementedException();
 }
Beispiel #14
0
 /// <summary> int AMF3_Decode(AMFObject * obj, const char *pBuffer, int nSize, int bDecodeName); </summary>
 public static int AMF3_Decode(AMFObject obj, byte[] buffer, int pBuffer, int nSize, bool bDecodeName)
 {
     throw new NotImplementedException();
 }