00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <cstring>
00023 #include <iomanip>
00024 #include <iostream>
00025 #include <string>
00026 #include <enet/enet.h>
00027
00028 #include "net/messageout.hpp"
00029
00031 const unsigned int INITIAL_DATA_CAPACITY = 16;
00032
00034 const unsigned int CAPACITY_GROW_FACTOR = 2;
00035
00036 MessageOut::MessageOut():
00037 mPos(0)
00038 {
00039 mData = (char*) malloc(INITIAL_DATA_CAPACITY);
00040 mDataSize = INITIAL_DATA_CAPACITY;
00041 }
00042
00043 MessageOut::MessageOut(int id):
00044 mPos(0)
00045 {
00046 mData = (char*) malloc(INITIAL_DATA_CAPACITY);
00047 mDataSize = INITIAL_DATA_CAPACITY;
00048
00049 writeShort(id);
00050 }
00051
00052 MessageOut::~MessageOut()
00053 {
00054 free(mData);
00055 }
00056
00057 void MessageOut::clear()
00058 {
00059 mData = (char *) realloc(mData, INITIAL_DATA_CAPACITY);
00060 mDataSize = INITIAL_DATA_CAPACITY;
00061 mPos = 0;
00062 }
00063
00064 void
00065 MessageOut::expand(size_t bytes)
00066 {
00067 if (bytes > mDataSize)
00068 {
00069 do
00070 {
00071 mDataSize *= CAPACITY_GROW_FACTOR;
00072 }
00073 while (bytes > mDataSize);
00074
00075 mData = (char*) realloc(mData, mDataSize);
00076 }
00077 }
00078
00079 void MessageOut::writeByte(int value)
00080 {
00081 expand(mPos + 1);
00082 mData[mPos] = value;
00083 mPos += 1;
00084 }
00085
00086 void MessageOut::writeShort(int value)
00087 {
00088 expand(mPos + 2);
00089 uint16_t t = ENET_HOST_TO_NET_16(value);
00090 memcpy(mData + mPos, &t, 2);
00091 mPos += 2;
00092 }
00093
00094 void MessageOut::writeLong(int value)
00095 {
00096 expand(mPos + 4);
00097 uint32_t t = ENET_HOST_TO_NET_32(value);
00098 memcpy(mData + mPos, &t, 4);
00099 mPos += 4;
00100 }
00101
00102 void MessageOut::writeCoordinates(int x, int y)
00103 {
00104 expand(mPos + 3);
00105 char *p = mData + mPos;
00106 p[0] = x & 0x00FF;
00107 p[1] = ((x & 0x0700) >> 8) | ((y & 0x001F) << 3);
00108 p[2] = (y & 0x07E0) >> 5;
00109 mPos += 3;
00110 }
00111
00112 void
00113 MessageOut::writeString(const std::string &string, int length)
00114 {
00115 int stringLength = string.length();
00116 if (length < 0)
00117 {
00118
00119 writeShort(stringLength);
00120 length = stringLength;
00121 }
00122 else if (length < stringLength)
00123 {
00124
00125 stringLength = length;
00126 }
00127 expand(mPos + length);
00128
00129
00130 memcpy(mData + mPos, string.c_str(), stringLength);
00131
00132 if (length > stringLength)
00133 {
00134
00135 memset(mData + mPos + stringLength, '\0', length - stringLength);
00136 }
00137 mPos += length;
00138 }
00139
00140 std::ostream&
00141 operator <<(std::ostream &os, const MessageOut &msg)
00142 {
00143 if (msg.getLength() >= 2)
00144 {
00145 unsigned short id = ENET_NET_TO_HOST_16(*(short*) msg.mData);
00146 os << std::setw(6) << std::hex << std::showbase << std::internal
00147 << std::setfill('0') << id
00148 << std::dec << " (" << msg.getLength() << " B)";
00149 }
00150 else
00151 {
00152 os << "Unknown"
00153 << std::dec << " (" << msg.getLength() << " B)";
00154 }
00155 return os;
00156 }