⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvmegacoencode.c

📁 h.248协议源码
💻 C
📖 第 1 页 / 共 4 页
字号:
#include "rvmegacoencode.h"
#include "rvsdpenc.h"

const char *nullStr = "";

typedef struct
{
	const char *indent0, *indent1, *indent2, *indent3;
	const char *comma, *comma0, *comma2, *comma3;
	const char *brace0, *brace3;
} RvFormatTable;

RvFormatTable rvFormatPretty =
{
	"\n", "\n\t", "\n\t\t", "\n\t\t\t",
	", ", ",\n", ",\n\t\t", ",\n\t\t\t",
	"{\n", "{\n\t\t\t"
};

RvFormatTable rvFormatSmall =
{
	"", "", "", "",
	",", ",", ",", ",",
	"{", "{"
};

typedef struct
{
	RvBool compact;
	const RvFormatTable *format;
} RvMegacoEncodeOptions;

typedef enum
{
	RV_MEGACOENCODEERROR_CORRUPTOBJECT = 1,
	RV_MEGACOENCODEERROR_MISSINGPARAMETER
} RvMegacoEncodeError;

static void rvTimeStampEncode(const RvTimeStamp *x, RvStrStream *os)
{
	char fill = '0';
	rvStrStreamWriteUIntW(os, rvTimeStampGetYear(x), 4, fill);
	rvStrStreamWriteUIntW(os, rvTimeStampGetMonth(x), 2, fill);
	rvStrStreamWriteUIntW(os, rvTimeStampGetDay(x), 2, fill);
	rvStrStreamPut(os, 'T'); 
	rvStrStreamWriteUIntW(os, rvTimeStampGetHour(x), 2, fill);
	rvStrStreamWriteUIntW(os, rvTimeStampGetMinute(x), 2, fill);
	rvStrStreamWriteUIntW(os, rvTimeStampGetHsecs(x), 4, fill);
}

static void rvMegacoEntityAddressEncode(const RvMegacoEntityAddress *x, RvStrStream *os)
{
	RvInetPort port = rvMegacoEntityAddressGetPort(x);
	switch(rvMegacoEntityAddressGetType(x))
	{
	case RV_MEGACOENTITYADDRESSTYPE_IP:
		rvStrStreamPut(os, '[');
		rvStrStreamWriteStr(os, rvMegacoEntityAddressGetAddress(x));
		rvStrStreamPut(os, ']');
		break;
	case RV_MEGACOENTITYADDRESSTYPE_DNS:
		rvStrStreamPut(os, '<');
		rvStrStreamWriteStr(os, rvMegacoEntityAddressGetAddress(x));
		rvStrStreamPut(os, '>');
		break;
	case RV_MEGACOENTITYADDRESSTYPE_DEVICE:
		rvStrStreamWriteStr(os, rvMegacoEntityAddressGetAddress(x));
		return;
	case RV_MEGACOENTITYADDRESSTYPE_MTP:
		rvStrStreamWriteStr(os, "MTP{");
		rvStrStreamWriteStr(os, rvMegacoEntityAddressGetAddress(x));
		rvStrStreamPut(os, '}');
		return;
	}
	if(port)
	{
		rvStrStreamPut(os, ':');
		rvStrStreamWriteUInt(os, port);
	}
}

static void rvMegacoTerminationIdEncode(const RvMegacoTerminationId *x, RvStrStream *os)
{
	rvStrStreamWriteStr(os, rvMegacoTerminationIdGetId(x));
}

static void rvMegacoContextIdEncode(const RvMegacoContextId *x, RvStrStream *os)
{
	switch(rvMegacoContextIdGetType(x))
	{
	case RV_MEGACOCONTEXTID_NORMAL:
		rvStrStreamWriteUInt(os, rvMegacoContextIdGetId(x)); 
		break;
	case RV_MEGACOCONTEXTID_NULL:
		rvStrStreamPut(os, '-'); 
		break;
	case RV_MEGACOCONTEXTID_CHOOSE:
		rvStrStreamPut(os, '$'); 
		break;
	case RV_MEGACOCONTEXTID_ALL:
		rvStrStreamPut(os, '*'); 
		break;
	default:
		rvStrStreamSetErrorStatus(os, RV_MEGACOENCODEERROR_CORRUPTOBJECT);
		break;
	}
}

static void rvMegacoPackageItemEncode(const RvMegacoPackageItem *x, RvStrStream *os)
{
	const char *pkg = rvMegacoPackageItemGetPackage(x);
	if(*pkg)
	{
		rvStrStreamWriteStr(os, pkg);
		rvStrStreamPut(os, '/');
	}
	rvStrStreamWriteStr(os, rvMegacoPackageItemGetItem(x));
}

static void rvMegacoParameterValueEncode(const RvMegacoParameterValue *x, RvStrStream *os)
{
	RvMegacoEncodeOptions *opt = (RvMegacoEncodeOptions *)rvStrStreamGetUserData(os);
	size_t i;
	switch(rvMegacoParameterValueGetType(x))
	{
	case RV_RELATION_EQUAL:
		rvStrStreamPut(os, '=');
		rvStrStreamWriteStr(os, rvMegacoParameterValueGetValue(x));
		break;
	case RV_RELATION_LESS:
		rvStrStreamPut(os, '<');
		rvStrStreamWriteStr(os, rvMegacoParameterValueGetValue(x));
		break;
	case RV_RELATION_GREATER:
		rvStrStreamPut(os, '>');
		rvStrStreamWriteStr(os, rvMegacoParameterValueGetValue(x));
		break;
	case RV_RELATION_INEQUAL:
		rvStrStreamPut(os, '#');
		rvStrStreamWriteStr(os, rvMegacoParameterValueGetValue(x));
		break;
	case RV_RELATION_AND:
		rvStrStreamWriteStr(os, "=[");
		for(i=0; i<rvMegacoParameterValueGetListSize(x); ++i)
		{
			if(i) rvStrStreamWriteStr(os, opt->format->comma);
			rvStrStreamWriteStr(os, rvMegacoParameterValueGetListValue(x, i));
		}
		rvStrStreamPut(os, ']');
		break;
	case RV_RELATION_OR:
		rvStrStreamWriteStr(os, "={");
		for(i=0; i<rvMegacoParameterValueGetListSize(x); ++i)
		{
			if(i) rvStrStreamWriteStr(os, opt->format->comma);
			rvStrStreamWriteStr(os, rvMegacoParameterValueGetListValue(x, i));
		}
		rvStrStreamPut(os, '}');
		break;
	case RV_RELATION_RANGE:
		rvStrStreamWriteStr(os, "=[");
		rvStrStreamWriteStr(os,	rvMegacoParameterValueGetRangeMin(x));
		rvStrStreamPut(os, ':');
		rvStrStreamWriteStr(os, rvMegacoParameterValueGetRangeMin(x));
		rvStrStreamPut(os, ']');
		break;
	default:
		rvStrStreamSetErrorStatus(os, RV_MEGACOENCODEERROR_CORRUPTOBJECT);
		break;
	}

}

static void rvMegacoParameterListEncode(const RvMegacoParameterList *x, RvStrStream *os)
{
	RvMegacoEncodeOptions *opt = (RvMegacoEncodeOptions *)rvStrStreamGetUserData(os);
	const char *sep = nullStr;
	RvMapIter(RvMegacoPackageItem, RvMegacoParameterValue) iter;
	for(iter = rvMapBegin(RvMegacoPackageItem, RvMegacoParameterValue)(&x->list);
	    iter != rvMapEnd(RvMegacoPackageItem, RvMegacoParameterValue)(&x->list);
	    iter = rvMapIterNext(iter))
	{
		rvStrStreamWriteStr(os, sep);
		rvMegacoPackageItemEncode(rvMapIterGetKey(RvMegacoPackageItem, RvMegacoParameterValue)(iter), os);
		rvMegacoParameterValueEncode(rvMapIterGetValue(RvMegacoPackageItem, RvMegacoParameterValue)(iter), os);
		sep = opt->format->comma;
	}
}

static void rvMegacoDigitPositionEncode(const RvMegacoDigitPosition *x, RvStrStream *os)
{
	if(rvMegacoDigitPositionGetEvents(x) == (1 << 10) - 1)
	{
		rvStrStreamPut(os, 'x');
	}
	else
	{
		const char *name = "0123456789ABCDEFGHIJK";
		RvBool first = rvTrue, single = rvTrue;
		int val;
		for(val = rvMegacoDigitPositionGetEvents(x); val; val >>= 1, ++name)
		{
			if(val & 1)
			{
				if(first)
				{
					first = rvFalse;
					if(val & ~1)
						rvStrStreamPut(os, '['), single = rvFalse;
				}
				rvStrStreamPut(os, *name);
				/* compact ranges of 4 or more consecutive digits */
				if(*name <= '6')
				{
					int streak = 0, i;
					for(i=4; i<='9'+1-*name; ++i)
					{
						if(~val & (1 << i) - 1)
							break;
						streak = i;
					}
					if(streak)
					{
						val >>= streak-1, name += streak-1;
						rvStrStreamPut(os, '-');
						rvStrStreamPut(os, *name);
					}
				}
			}
		}
		if(!single)
			rvStrStreamPut(os, ']');
	}
	if(rvMegacoDigitPositionIsMultiple(x))
		rvStrStreamPut(os, '.');
}

static void rvMegacoDigitStringEncode(const RvMegacoDigitString *x, RvStrStream *os)
{
	size_t i;
	for(i=0; i<rvMegacoDigitStringGetSize(x); ++i)
		rvMegacoDigitPositionEncode(rvMegacoDigitStringGetElem(x, i), os);
}

static void rvMegacoDigitMapEncode(const RvMegacoDigitMap *x, RvStrStream *os)
{
	size_t i, size = rvMegacoDigitMapGetSize(x);
	if(rvMegacoDigitMapGetStartTimeout(x) != rvMegacoDigitMapDefaultStartTimeout)
	{
		rvStrStreamWriteStr(os, "T:"); 
		rvStrStreamWriteUInt(os, rvMegacoDigitMapGetStartTimeout(x));
		rvStrStreamPut(os, ','); 
	}
	if(rvMegacoDigitMapGetShortTimeout(x) != rvMegacoDigitMapDefaultShortTimeout)
	{
		rvStrStreamWriteStr(os, "S:"); 
		rvStrStreamWriteUInt(os, rvMegacoDigitMapGetShortTimeout(x));
		rvStrStreamPut(os, ','); 
	}
	if(rvMegacoDigitMapGetLongTimeout(x) != rvMegacoDigitMapDefaultLongTimeout)
	{
		rvStrStreamWriteStr(os, "L:"); 
		rvStrStreamWriteUInt(os, rvMegacoDigitMapGetLongTimeout(x));
		rvStrStreamPut(os, ','); 
	}
	if(size > 1)
		rvStrStreamPut(os, '(');
	for(i=0; i<size; ++i)
	{
		if(i) rvStrStreamPut(os, '|');
		rvMegacoDigitStringEncode(rvMegacoDigitMapGetElem(x, i), os);
	}
	if(size > 1)
		rvStrStreamPut(os, ')');
}

static void rvMegacoDigitMapDescriptorEncode(const RvMegacoDigitMapDescriptor *x, RvStrStream *os)
{
	RvMegacoEncodeOptions *opt = (RvMegacoEncodeOptions *)rvStrStreamGetUserData(os);
	const char *name = rvMegacoDigitMapDescriptorGetName(x);
	const RvMegacoDigitMap *dm = rvMegacoDigitMapDescriptorGetDigitMap(x);
	size_t sz =	rvMegacoDigitMapGetSize(dm);

	rvStrStreamWriteStr(os, opt->compact ? "DM" : "DigitMap");
	if(*name || sz)
	{
		rvStrStreamPut(os, '=');
		rvStrStreamWriteStr(os, name);
		if(sz)
		{
			rvStrStreamPut(os, '{');
			rvMegacoDigitMapEncode(dm, os);
			rvStrStreamPut(os, '}');
		}
	}	
}

static void rvMegacoEventEncode(const RvMegacoEvent *x, RvStrStream *os)
{
	unsigned int streamId = rvMegacoEventGetStreamId(x);
	const RvMegacoParameterList *params = rvMegacoEventGetParameterList(x);
	rvMegacoPackageItemEncode(rvMegacoEventGetName(x), os);
	if(streamId || !rvMegacoParameterListIsEmpty(params))
	{
		rvStrStreamPut(os, '{');
		if(streamId)
		{
			RvMegacoEncodeOptions *opt = (RvMegacoEncodeOptions *)rvStrStreamGetUserData(os);
			rvStrStreamWriteStr(os, opt->compact ? "ST=" : "Stream=");
			rvStrStreamWriteUInt(os, streamId);
			rvStrStreamWriteStr(os, opt->format->comma);
		}
		rvMegacoParameterListEncode(params, os);
		rvStrStreamPut(os, '}');
	}
}

static void rvMegacoSignalEncode(const RvMegacoSignal *x, RvStrStream *os)
{
	RvMegacoEncodeOptions *opt = (RvMegacoEncodeOptions *)rvStrStreamGetUserData(os);
	unsigned int reasons = rvMegacoSignalGetNotifyReasons(x);
	const RvMegacoParameterList *params = rvMegacoSignalGetParameterList(x);
	const char *sep = "{";
	rvMegacoPackageItemEncode(rvMegacoSignalGetName(x), os);
	
	if(rvMegacoSignalGetStreamId(x))
	{
		rvStrStreamWriteStr(os, sep);
		rvStrStreamWriteStr(os, opt->compact ? "ST=" : "Stream=");
		rvStrStreamWriteUInt(os, rvMegacoSignalGetStreamId(x));
		sep = opt->format->comma;
	}

	if(rvMegacoSignalGetType(x) != RV_MEGACOSIGNAL_DEFAULTTYPE)
	{
		rvStrStreamWriteStr(os, sep);
		rvStrStreamWriteStr(os, opt->compact ? "SY=" : "SignalType=");
		switch(rvMegacoSignalGetType(x))
		{
		case RV_MEGACOSIGNAL_ONOFF:	
			rvStrStreamWriteStr(os, opt->compact ? "OO" : "OnOff");
			break;
		case RV_MEGACOSIGNAL_TIMEOUT:
			rvStrStreamWriteStr(os, opt->compact ? "TO" : "TimeOut"); 
			if(rvMegacoSignalGetDuration(x))
			{
				rvStrStreamWriteStr(os, opt->format->comma); 
				rvStrStreamWriteStr(os, opt->compact ? "DR=" : "Duration=");
				rvStrStreamWriteUInt(os, rvMegacoSignalGetDuration(x));
			}
			break;
		case RV_MEGACOSIGNAL_BRIEF:
			rvStrStreamWriteStr(os, opt->compact ? "BR" : "Brief");
			break;
		default:
			rvStrStreamSetErrorStatus(os, RV_MEGACOENCODEERROR_CORRUPTOBJECT);
			break;
		}
		sep = opt->format->comma;
	}

	if(!rvMegacoParameterListIsEmpty(params))
	{
		rvStrStreamWriteStr(os, sep);
		rvMegacoParameterListEncode(params, os);
		sep = opt->format->comma;
	}

	if(reasons)
	{
		const char *sep2 = nullStr; 
		rvStrStreamWriteStr(os, sep);
		rvStrStreamWriteStr(os, opt->compact ? "NC={" : "NotifyCompletion={");
		if(reasons & RV_MEGACOSIGNAL_COMPLETED)
		{
			rvStrStreamWriteStr(os, opt->compact ? "TO" : "TimeOut");
			sep2 = opt->format->comma;
		}
		if(reasons & RV_MEGACOSIGNAL_GOTEVENT)
		{
			rvStrStreamWriteStr(os, sep2);
			rvStrStreamWriteStr(os, opt->compact ? "IBE" : "IntByEvent");
			sep2 = opt->format->comma;
		}
		if(reasons & RV_MEGACOSIGNAL_NEWSIGDESCR)
		{
			rvStrStreamWriteStr(os, sep2);
			rvStrStreamWriteStr(os, opt->compact ? "IBS" : "IntBySigDescr");
			sep2 = opt->format->comma;
		}
		if(reasons & RV_MEGACOSIGNAL_OTHERREASON)
		{
			rvStrStreamWriteStr(os, sep2);
			rvStrStreamWriteStr(os, opt->compact ? "OR" : "OtherReason");
		}
		rvStrStreamPut(os, '}');
		sep = opt->format->comma;
	}

	if(rvMegacoSignalGetKeepActiveFlag(x))
	{
		rvStrStreamWriteStr(os, sep);
		rvStrStreamWriteStr(os, opt->compact ? "KA" : "KeepActive");
		sep = opt->format->comma;
	}

	if(sep == opt->format->comma)
	{
		rvStrStreamPut(os, '}');
	}
}

static void rvMegacoSignalListEncode(const RvMegacoSignalList *x, RvStrStream *os)
{
	RvMegacoEncodeOptions *opt = (RvMegacoEncodeOptions *)rvStrStreamGetUserData(os);
	size_t i;
	rvStrStreamWriteStr(os, opt->compact ? "SL=" : "SignalList=");
	rvStrStreamWriteUInt(os, rvMegacoSignalListGetId(x));
	rvStrStreamPut(os, '{');
	for(i=0; i<rvMegacoSignalListGetSize(x); ++i)
	{
		if(i) rvStrStreamWriteStr(os, opt->format->comma);
		rvMegacoSignalEncode(rvMegacoSignalListGetElem(x, i), os);
	}
	rvStrStreamPut(os, '}');
}

static void rvMegacoSignalsDescriptorEncode(const RvMegacoSignalsDescriptor *x, RvStrStream *os)
{
	RvMegacoEncodeOptions *opt = (RvMegacoEncodeOptions *)rvStrStreamGetUserData(os);
	rvStrStreamWriteStr(os, opt->compact ? "SG" : "Signals");
	if(rvMegacoSignalsDescriptorIsSet(x))
	{
		const char *sep = nullStr;
		size_t i;
		rvStrStreamPut(os, '{');
		for(i=0; i<rvMegacoSignalsDescriptorGetNumSignalLists(x); ++i)
		{
			rvStrStreamWriteStr(os, sep);
			rvMegacoSignalListEncode(rvMegacoSignalsDescriptorGetSignalList(x, i), os);
			sep = opt->format->comma;
		}
		for(i=0; i<rvMegacoSignalsDescriptorGetNumSignals(x); ++i)
		{
			rvStrStreamWriteStr(os, sep);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -