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); }