diff --git a/include/tr/protocol/message_raw.h b/include/tr/protocol/message_raw.h index 8dc603c..10d842a 100644 --- a/include/tr/protocol/message_raw.h +++ b/include/tr/protocol/message_raw.h @@ -24,6 +24,7 @@ #define __TR_PROTOCOL_MESSAGE_RAW_H__ #include +#include #include "trbase.h" #include "trio.h" @@ -33,7 +34,9 @@ TR_CLASS(TR_ProtoMessageRaw) { TR_EXTENDS(TR_ProtoMessage); - TR_RemoteData data; + uint16_t size; + uint16_t size_done; + char * data; }; TR_INSTANCE_INIT(TR_ProtoMessageRaw); TR_CLASSVARS_DECL(TR_ProtoMessageRaw) {}; diff --git a/src/protocol_message_raw.c b/src/protocol_message_raw.c index 5a85599..4804317 100644 --- a/src/protocol_message_raw.c +++ b/src/protocol_message_raw.c @@ -35,7 +35,9 @@ protoMessageRawCtor(void * _this, va_list * params) return 0; } -static void protoMessageRawDtor(void * _this) {} +static void protoMessageRawDtor(void * _this) { + TR_MEM_FREE(((TR_ProtoMessageRaw)_this)->data); +} TR_INIT_IFACE(TR_Class, protoMessageRawCtor, protoMessageRawDtor, NULL); TR_CREATE_CLASS(TR_ProtoMessageRaw, TR_ProtoMessage, NULL, TR_IF(TR_Class)); diff --git a/src/protocol_raw.c b/src/protocol_raw.c index ce0a0b3..b58eaae 100644 --- a/src/protocol_raw.c +++ b/src/protocol_raw.c @@ -22,7 +22,10 @@ #include +#include #include +#include +#include #include "trbase.h" #include "trio.h" @@ -49,21 +52,69 @@ protocolRawCreateMessage(void * _this, TR_Socket remote) static TR_RemoteData -protocolRawParse(void * _this, TR_ProtoMessage _message, TR_RemoteData data) +protocolRawParse(void * _this, TR_ProtoMessage _message, TR_RemoteData _data) { - TR_ProtoMessageRaw message = (TR_ProtoMessageRaw)_message; + TR_ProtoMessageRaw message = (TR_ProtoMessageRaw)_message; + size_t size = ((TR_SizedData)_data)->size; + char * data = ((TR_SizedData)_data)->data; + TR_RemoteData retval = NULL; + + if (! message->data) { + if (message->size == 0) { + if (size == 1) { + message->size = *(char *)data << 8; + TR_delete(_data); + return NULL; + } else { + message->size = *(uint16_t *)data; + size -= 2; + data += 2; + } + } else { + message->size &= *(char *)data; + size--; + data++; + } + + message->size = ntohs(message->size); + message->data = TR_malloc(message->size); + } + + if (size >= message->size - message->size_done) { + memcpy(message->data, data, message->size - message->size_done); + size -= message->size - message->size_done; + data += message->size - message->size_done; + message->size_done = message->size; + _message->ready = 1; - message->data = data; - _message->ready = 1; + if (size) { + retval = TR_new(TR_RemoteData, data, size, _data->remote); + } + } else { + memcpy(message->data, data, size); + message->size_done = size; + } - return NULL; + TR_delete(_data); + + return retval; } static TR_RemoteData protocolRawCompose(void * _this, TR_ProtoMessage _message) { - return ((TR_ProtoMessageRaw)_message)->data; + TR_ProtoMessageRaw message = (TR_ProtoMessageRaw)_message; + TR_SizedData data; + + data = (TR_SizedData)TR_new(TR_RemoteData, NULL, 0, _message->remote); + + data->size = message->size + 2; + data->data = TR_malloc(data->size); + *(uint16_t *)data->data = htons(message->size); + memcpy(data->data+2, message->data, message->size); + + return (TR_RemoteData)data; } TR_INIT_IFACE(TR_Class, protocolRawCtor, protocolRawDtor, NULL); diff --git a/testers/test_handler.c b/testers/test_handler.c index ba50ac1..cea3c69 100644 --- a/testers/test_handler.c +++ b/testers/test_handler.c @@ -45,7 +45,7 @@ testHandlerNewMessage(TR_EventHandler this, TR_Event event) TR_ProtoMessageRaw message = event->data; ((TestHandler)this)->handled++; - ((TestHandler)this)->size += ((TR_SizedData)message->data)->size; + ((TestHandler)this)->size += message->size + 2; _event = TR_eventSubjectEmit( event->subject, diff --git a/testers/testclient.c b/testers/testclient.c index e24db17..ec2b106 100644 --- a/testers/testclient.c +++ b/testers/testclient.c @@ -20,7 +20,7 @@ main (int argc, char * argv[]) TR_SimpleClient client; TR_Protocol protocol; TR_ProtoMessageRaw message; - TR_RemoteData data; + int i; TR_logger = TR_INSTANCE_CAST(TR_Logger, mylogger2); socket = TR_new(TR_TcpSocket, TR_logger, "192.168.2.13", 5678, 0); @@ -32,17 +32,32 @@ main (int argc, char * argv[]) client = TR_new(TR_SimpleClient, connection); - message = (TR_ProtoMessageRaw)TR_protoCreateRequest(protocol, (TR_Socket)socket); - data = TR_new(TR_RemoteData, "test", sizeof("test"), (TR_Socket)socket); - message->data = data; - message = (TR_ProtoMessageRaw)TR_simpleClientIssue( - client, - (TR_ProtoMessage)message, - 10000000); - - printf("%s\n", ((TR_SizedData)message->data)->data); - TR_delete(message->data); - TR_delete(message); + for (i=0; i<100000; i++) { + message = (TR_ProtoMessageRaw)TR_protoCreateRequest( + protocol, (TR_Socket)socket); + message->size = sizeof("test"); + message->data = TR_malloc(message->size); + memcpy(message->data, "test", sizeof("test")); + + message = (TR_ProtoMessageRaw)TR_simpleClientIssue( + client, + (TR_ProtoMessage)message, + 10000000); + +#if 0 + printf("%s\n", message->data); +#else + if (0 == strncmp("test", message->data, sizeof("test")-1)) { + if (i % 1000 == 0) printf("%c", '.'); + } else { + printf("%c", 'f'); + } +#endif + fflush(stdout); + + TR_delete(message); + } + puts(""); puts("cleanup...");