From d077760f33bae5558041cc71580fd7701c8c685d Mon Sep 17 00:00:00 2001 From: meh Date: Mon, 28 Feb 2011 17:48:09 +0100 Subject: [PATCH] Improve Buffer usability with CD_Buffer(Add|Remove)Format. --- include/craftd/Buffer.h | 46 +++++++++++++++++++-- src/Buffer.c | 69 +++++++++++++++++++++++++++++--- src/Packet.c | 88 +++++++++++++++++++++++++---------------- 3 files changed, 160 insertions(+), 43 deletions(-) diff --git a/include/craftd/Buffer.h b/include/craftd/Buffer.h index 87f43d3..587e02c 100644 --- a/include/craftd/Buffer.h +++ b/include/craftd/Buffer.h @@ -66,9 +66,26 @@ int CD_BufferDrain (CDBuffer* self, size_t length); void CD_BufferAdd (CDBuffer* self, CDPointer data, size_t length); -void CD_BufferAddBuffer (CDBuffer* self, CDBuffer* data); +/** + * Add data to a buffer with data from the given format. + * + * Format types: + * b: MCByte + * s: MCShort + * i: MCInteger + * l: MCLong + * + * f: MCFloat + * d: MCDouble + * + * B: MCBoolean + * S: MCString + * + * @param format The format string + */ +void CD_BufferAddFormat (CDBuffer* self, const char* format, ...); -void CD_BufferAddBoolean (CDBuffer* self, MCBoolean data); +void CD_BufferAddBuffer (CDBuffer* self, CDBuffer* data); void CD_BufferAddByte (CDBuffer* self, MCByte data); @@ -82,13 +99,32 @@ void CD_BufferAddFloat (CDBuffer* self, MCFloat data); void CD_BufferAddDouble (CDBuffer* self, MCDouble data); +void CD_BufferAddBoolean (CDBuffer* self, MCBoolean data); + void CD_BufferAddString (CDBuffer* self, MCString data); CDPointer CD_BufferRemove (CDBuffer* self, size_t length); -CDBuffer* CD_BufferRemoveBuffer (CDBuffer* self); +/** + * Remove data from a buffer with data from the given format. + * + * Format types: + * b: MCByte + * s: MCShort + * i: MCInteger + * l: MCLong + * + * f: MCFloat + * d: MCDouble + * + * B: MCBoolean + * S: MCString + * + * @param format The format string + */ +void CD_BufferRemoveFormat (CDBuffer* self, const char* format, ...); -MCBoolean CD_BufferRemoveBoolean (CDBuffer* self); +CDBuffer* CD_BufferRemoveBuffer (CDBuffer* self); MCByte CD_BufferRemoveByte (CDBuffer* self); @@ -102,6 +138,8 @@ MCFloat CD_BufferRemoveFloat (CDBuffer* self); MCDouble CD_BufferRemoveDouble (CDBuffer* self); +MCBoolean CD_BufferRemoveBoolean (CDBuffer* self); + MCString CD_BufferRemoveString (CDBuffer* self); #endif diff --git a/src/Buffer.c b/src/Buffer.c index c934dd3..6df1b8f 100644 --- a/src/Buffer.c +++ b/src/Buffer.c @@ -94,19 +94,40 @@ CD_BufferAdd (CDBuffer* self, CDPointer data, size_t length) } void -CD_BufferAddBuffer (CDBuffer* self, CDBuffer* data) +CD_BufferAddFormat (CDBuffer* self, const char* format, ...) { - CDPointer stuff = CD_BufferContent(data); + va_list ap; - evbuffer_add(self->raw, (void*) stuff, CD_BufferLength(data)); + va_start(ap, format); - CD_free((void*) stuff); + while (*format != '\0') { + switch (*format) { + case 'b': CD_BufferAddByte(self, va_arg(ap, int)); break; + case 's': CD_BufferAddShort(self, va_arg(ap, int)); break; + case 'i': CD_BufferAddInteger(self, va_arg(ap, int)); break; + case 'l': CD_BufferAddLong(self, va_arg(ap, long)); break; + + case 'f': CD_BufferAddFloat(self, va_arg(ap, double)); break; + case 'd': CD_BufferAddDouble(self, va_arg(ap, double)); break; + + case 'B': CD_BufferAddBoolean(self, va_arg(ap, int)); break; + case 'S': CD_BufferAddString(self, va_arg(ap, CDString*)); break; + } + + format++; + } + + va_end(ap); } void -CD_BufferAddBoolean (CDBuffer* self, MCBoolean data) +CD_BufferAddBuffer (CDBuffer* self, CDBuffer* data) { - evbuffer_add(self->raw, &data, MCBooleanSize); + CDPointer stuff = CD_BufferContent(data); + + evbuffer_add(self->raw, (void*) stuff, CD_BufferLength(data)); + + CD_free((void*) stuff); } void @@ -155,6 +176,12 @@ CD_BufferAddDouble (CDBuffer* self, MCDouble data) evbuffer_add(self->raw, &data, MCDoubleSize); } +void +CD_BufferAddBoolean (CDBuffer* self, MCBoolean data) +{ + evbuffer_add(self->raw, &data, MCBooleanSize); +} + void CD_BufferAddString (CDBuffer* self, CDString* data) { @@ -174,6 +201,36 @@ CD_BufferRemove (CDBuffer* self, size_t length) return result; } +void +CD_BufferRemoveFormat (CDBuffer* self, const char* format, ...) +{ + va_list ap; + + va_start(ap, format); + + while (*format != '\0') { + CDPointer pointer = va_arg(ap, CDPointer); + + switch (*format) { + case 'b': *((MCByte*) pointer) = CD_BufferRemoveByte(self); break; + case 's': *((MCShort*) pointer) = CD_BufferRemoveShort(self); break; + case 'i': *((MCInteger*) pointer) = CD_BufferRemoveInteger(self); break; + case 'l': *((MCLong*) pointer) = CD_BufferRemoveLong(self); break; + + case 'f': *((MCFloat*) pointer) = CD_BufferRemoveFloat(self); break; + case 'd': *((MCDouble*) pointer) = CD_BufferRemoveDouble(self); break; + + case 'B': *((MCBoolean*) pointer) = CD_BufferRemoveBoolean(self); break; + case 'S': *((MCString*) pointer) = CD_BufferRemoveString(self); break; + } + + format++; + } + + va_end(ap); +} + + CDBuffer* CD_BufferRemoveBuffer (CDBuffer* self) { diff --git a/src/Packet.c b/src/Packet.c index 475dd2f..dac510f 100644 --- a/src/Packet.c +++ b/src/Packet.c @@ -177,11 +177,13 @@ CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input) case CDLogin: { CDPacketLogin* packet = (CDPacketLogin*) CD_malloc(sizeof(CDPacketLogin)); - packet->request.version = CD_BufferRemoveInteger(input); - packet->request.username = CD_BufferRemoveString(input); - packet->request.password = CD_BufferRemoveString(input); - packet->request.mapSeed = CD_BufferRemoveLong(input); - packet->request.dimension = CD_BufferRemoveByte(input); + CD_BufferRemoveFormat(input, "iSSlb", + &packet->request.version, + &packet->request.username, + &packet->request.password, + &packet->request.mapSeed, + &packet->request.dimension + ); return (CDPointer) packet; } @@ -189,7 +191,9 @@ CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input) case CDHandshake: { CDPacketHandshake* packet = (CDPacketHandshake*) CD_malloc(sizeof(CDPacketHandshake)); - packet->request.username = CD_BufferRemoveString(input); + CD_BufferRemoveFormat(input, "S", + &packet->request.username + ); return (CDPointer) packet; } @@ -197,7 +201,9 @@ CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input) case CDChat: { CDPacketChat* packet = (CDPacketChat*) CD_malloc(sizeof(CDPacketChat)); - packet->request.message = CD_BufferRemoveString(input); + CD_BufferRemoveFormat(input, "S", + &packet->request.message + ); return (CDPointer) packet; } @@ -205,9 +211,11 @@ CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input) case CDUseEntity: { CDPacketUseEntity* packet = (CDPacketUseEntity*) CD_malloc(sizeof(CDPacketUseEntity)); - packet->request.user = CD_BufferRemoveInteger(input); - packet->request.target = CD_BufferRemoveInteger(input); - packet->request.leftClick = CD_BufferRemoveByte(input); + CD_BufferRemoveFormat(input, "iib", + &packet->request.user, + &packet->request.target, + &packet->request.leftClick + ); return (CDPointer) packet; } @@ -219,7 +227,9 @@ CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input) case CDOnGround: { CDPacketOnGround* packet = (CDPacketOnGround*) CD_malloc(sizeof(CDPacketOnGround)); - packet->request.onGround = CD_BufferRemoveBoolean(input); + CD_BufferRemoveFormat(input, "B", + &packet->request.onGround + ); return (CDPointer) packet; } @@ -227,11 +237,13 @@ CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input) case CDPlayerPosition: { CDPacketPlayerPosition* packet = (CDPacketPlayerPosition*) CD_malloc(sizeof(CDPacketPlayerPosition)); - packet->request.position.x = CD_BufferRemoveDouble(input); - packet->request.position.y = CD_BufferRemoveDouble(input); - packet->request.stance = CD_BufferRemoveDouble(input); - packet->request.position.z = CD_BufferRemoveDouble(input); - packet->request.is.onGround = CD_BufferRemoveBoolean(input); + CD_BufferRemoveFormat(input, "ddddb", + &packet->request.position.x, + &packet->request.position.y, + &packet->request.stance, + &packet->request.position.z, + &packet->request.is.onGround + ); return (CDPointer) packet; } @@ -239,9 +251,11 @@ CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input) case CDPlayerLook: { CDPacketPlayerLook* packet = (CDPacketPlayerLook*) CD_malloc(sizeof(CDPacketPlayerLook)); - packet->request.yaw = CD_BufferRemoveFloat(input); - packet->request.pitch = CD_BufferRemoveFloat(input); - packet->request.is.onGround = CD_BufferRemoveBoolean(input); + CD_BufferRemoveFormat(input, "ffb", + &packet->request.yaw, + &packet->request.pitch, + &packet->request.is.onGround + ); return (CDPointer) packet; } @@ -249,13 +263,15 @@ CD_GetPacketDataFromBuffer (CDPacket* self, CDBuffer* input) case CDPlayerMoveLook: { CDPacketPlayerMoveLook* packet = (CDPacketPlayerMoveLook*) CD_malloc(sizeof(CDPacketPlayerMoveLook)); - packet->request.position.x = CD_BufferRemoveDouble(input); - packet->request.stance = CD_BufferRemoveDouble(input); - packet->request.position.y = CD_BufferRemoveDouble(input); - packet->request.position.z = CD_BufferRemoveDouble(input); - packet->request.yaw = CD_BufferRemoveFloat(input); - packet->request.pitch = CD_BufferRemoveFloat(input); - packet->request.is.onGround = CD_BufferRemoveBoolean(input); + CD_BufferRemoveFormat(input, "ddddffb", + &packet->request.position.x, + &packet->request.stance, + &packet->request.position.y, + &packet->request.position.z, + &packet->request.yaw, + &packet->request.pitch, + &packet->request.is.onGround + ); return (CDPointer) packet; } @@ -284,23 +300,29 @@ CD_PacketToBuffer (CDPacket* self) case CDLogin: { CDPacketLogin* packet = (CDPacketLogin*) self->data; - CD_BufferAddInteger(data, packet->response.id); - CD_BufferAddString(data, packet->response.serverName); - CD_BufferAddString(data, packet->response.motd); - CD_BufferAddLong(data, packet->response.mapSeed); - CD_BufferAddByte(data, packet->response.dimension); + CD_BufferAddFormat(data, "iSSlb", + packet->response.id, + packet->response.serverName, + packet->response.motd, + packet->response.mapSeed, + packet->response.dimension + ); } break; case CDHandshake: { CDPacketHandshake* packet = (CDPacketHandshake*) self->data; - CD_BufferAddString(data, packet->response.hash); + CD_BufferAddFormat(data, "S", + packet->response.hash + ); } break; case CDChat: { CDPacketChat* packet = (CDPacketChat*) self->data; - CD_BufferAddString(data, packet->response.message); + CD_BufferAddFormat(data, "S", + packet->response.message + ); } break; } } break;