/// <summary> char *AMF_EncodeString(char *output, char *outend, const AVal * str);</summary> public static int AMF_EncodeString(byte[] buf, int output, int outend, AVal str) { if ((str.av_len < 65536 && output + 1 + 2 + str.av_len > outend) || output + 1 + 4 + str.av_len > outend) { return(0); } if (str.av_len < 65536) { // *output++ = AMF_STRING; buf[output++] = (byte)AMFDataType.AMF_STRING; output = AMF_EncodeInt16(buf, output, outend, (ushort)str.av_len); } else { buf[output++] = (byte)AMFDataType.AMF_LONG_STRING; output = AMF_EncodeInt32(buf, output, outend, (uint)str.av_len); } memcpy(buf, output, str.av_val, str.av_len); output += str.av_len; return(output); }
/// <summary> void AMF_DecodeLongString(const char *data, AVal * str);</summary> public static void AMF_DecodeLongString(byte[] buf, int offset, out AVal str) { var len = AMF_DecodeInt32(buf, offset); var data = new byte[len]; Array.Copy(buf, offset + 4, data, 0, len); str = new AVal(data); }
/* Shortcuts for AMFProp_Encode */ /// <summary> char *AMF_EncodeNamedString(char *output, char *outend, const AVal * name, const AVal * value);</summary> public static int AMF_EncodeNamedString(byte[] buf, int output, int outend, AVal name, AVal value) { if (output + 2 + name.av_len > outend) { return(0); } output = AMF_EncodeInt16(buf, output, outend, (ushort)name.av_len); memcpy(buf, output, name.av_val, name.av_len); output += name.av_len; return(AMF_EncodeString(buf, output, outend, value)); }
/// <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); }
/// <summary> void AMFProp_SetString(AMFObjectProperty* prop, AVal* str); </summary> public static void AMFProp_SetString(AMFObjectProperty prop, AVal str) { throw new NotImplementedException(); }
public AMFObjectProperty() { p_name = new AVal(); p_aval = new AVal(); p_object = new AMFObject(); }
/// <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); }
/// <summary> void AMFProp_GetString(AMFObjectProperty* prop, AVal* str); </summary> public static void AMFProp_GetString(AMFObjectProperty prop, out AVal str) { str = prop.p_aval; }
/// <summary> void AMFProp_SetName(AMFObjectProperty* prop, AVal* name); </summary> public static void AMFProp_SetName(AMFObjectProperty prop, AVal name) { throw new NotImplementedException(); }
/// <summary> AVMATCH(a1,a2) </summary> public static bool Match(AVal a1, AVal a2) { return(a1.av_len == a2.av_len && a1.av_val.SequenceEqual(a2.av_val)); }