Exemplo n.º 1
0
bool RTMPProtocolSerializer::Serialize(Channel &channel,
		Variant &message, IOBuffer &buffer, uint32_t chunkSize) {
	bool result = false;
	_internalBuffer.Ignore(GETAVAILABLEBYTESCOUNT(_internalBuffer));

	switch ((uint32_t) VH_MT(message)) {
		case RM_HEADER_MESSAGETYPE_INVOKE:
		{
			result = SerializeInvoke(_internalBuffer, message[RM_INVOKE]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_NOTIFY:
		{
			result = SerializeNotify(_internalBuffer, message[RM_NOTIFY]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND:
		{
			result = SerializeFlexStreamSend(_internalBuffer, message[RM_FLEXSTREAMSEND]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_FLEXSHAREDOBJECT:
		{
			result = SerializeFlexSharedObject(_internalBuffer, message[RM_SHAREDOBJECT]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_SHAREDOBJECT:
		{
			result = SerializeSharedObject(_internalBuffer, message[RM_SHAREDOBJECT]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_ACK:
		{
			result = SerializeAck(_internalBuffer, message[RM_ACK]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_USRCTRL:
		{
			result = SerializeUsrCtrl(_internalBuffer, message[RM_USRCTRL]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_CHUNKSIZE:
		{
			result = SerializeChunkSize(_internalBuffer, message[RM_CHUNKSIZE]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_WINACKSIZE:
		{
			result = SerializeWinAckSize(_internalBuffer, message[RM_WINACKSIZE]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_PEERBW:
		{
			result = SerializeClientBW(_internalBuffer, message[RM_PEERBW]);
			break;
		}
		case RM_HEADER_MESSAGETYPE_ABORTMESSAGE:
		{
			result = SerializeAbortMessage(_internalBuffer, message[RM_ABORTMESSAGE]);
			break;
		}
		default:
		{
			FATAL("Invalid message type:\n%s", STR(message.ToString()));
		}
	}

	//2. Check out the result
	if (!result) {
		FATAL("Unable to serialize message body");
		return false;
	}

	//3. Update the message length
	VH_ML(message) = GETAVAILABLEBYTESCOUNT(_internalBuffer);

	//4. Extract the header
	Header header;
	if (!Header::GetFromVariant(header, message[RM_HEADER])) {
		FATAL("Unable to read RTMP header: %s", STR(message.ToString()));
		return false;
	}

	//5. Chunk and send the data
	uint32_t available = 0;
	while ((available = GETAVAILABLEBYTESCOUNT(_internalBuffer)) != 0) {
		if (!header.Write(channel, buffer)) {
			FATAL("Unable to serialize message header");
			result = false;
		}
		if (available >= chunkSize) {
			buffer.ReadFromInputBuffer(&_internalBuffer, 0, chunkSize);
			channel.lastOutProcBytes += chunkSize;
			_internalBuffer.Ignore(chunkSize);
		} else {
			buffer.ReadFromInputBuffer(&_internalBuffer, 0, available);
			channel.lastOutProcBytes += available;
			_internalBuffer.Ignore(available);
		}
	}
	channel.lastOutProcBytes = 0;

	//6. Done
	return result;
}