00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <net/NetBufferPool.h>
00023 #include <common/Logger.h>
00024 #include <string.h>
00025 #include <zlib.h>
00026
00027 static const unsigned startSize = 1024 * 10;
00028
00029 NetBuffer::NetBuffer() :
00030 buffer_(0),
00031 usedSize_(0),
00032 bufferSize_(0)
00033 {
00034 }
00035
00036 NetBuffer::NetBuffer(const NetBuffer &other) :
00037 buffer_(0),
00038 usedSize_(0),
00039 bufferSize_(0)
00040 {
00041 allocate(((NetBuffer &) other).getBufferUsed());
00042 addToBuffer(((NetBuffer &)other).getBuffer());
00043 }
00044
00045 NetBuffer::NetBuffer(unsigned startSize, void *startBuffer)
00046 {
00047 allocate(startSize);
00048 if (startBuffer)
00049 {
00050 addDataToBuffer(startBuffer, startSize);
00051 }
00052 }
00053
00054 NetBuffer::~NetBuffer()
00055 {
00056 delete [] buffer_;
00057 buffer_ = 0;
00058 }
00059
00060 void NetBuffer::allocate(unsigned size)
00061 {
00062 if (bufferSize_<size)
00063 {
00064 delete [] buffer_;
00065 buffer_ = 0;
00066 buffer_ = new char[size];
00067 bufferSize_ = size;
00068 }
00069
00070 usedSize_ = 0;
00071 }
00072
00073 void NetBuffer::reset()
00074 {
00075 usedSize_ = 0;
00076 }
00077
00078 void NetBuffer::clear()
00079 {
00080 delete [] buffer_;
00081 usedSize_ = 0;
00082 buffer_ = 0;
00083 bufferSize_ = 0;
00084 }
00085
00086 bool NetBuffer::compressBuffer()
00087 {
00088 NetBuffer *newBuffer = NetBufferPool::instance()->getFromPool();
00089
00090 unsigned long destLen = getBufferUsed() * 2;
00091 unsigned long srcLen = getBufferUsed();
00092
00093
00094 newBuffer->allocate(destLen);
00095 newBuffer->reset();
00096 newBuffer->addToBuffer((unsigned int) srcLen);
00097 if (compress2((unsigned char *) (newBuffer->getBuffer() + 4), &destLen,
00098 (unsigned char *) getBuffer(), srcLen,
00099 6) == Z_OK)
00100 {
00101 newBuffer->setBufferUsed(destLen + 4);
00102
00103
00104 reset();
00105 addDataToBuffer(newBuffer->getBuffer(), newBuffer->getBufferUsed());
00106 }
00107
00108 NetBufferPool::instance()->addToPool(newBuffer);
00109
00110 return true;
00111 }
00112
00113 bool NetBuffer::uncompressBuffer()
00114 {
00115
00116 NetBufferReader reader(*this);
00117 unsigned int dLen = 0;
00118 if (!reader.getFromBuffer(dLen)) return false;
00119
00120
00121 unsigned long srcLen = getBufferUsed() - 4;
00122 unsigned long destLen = dLen;
00123
00124 #ifdef S3D_SERVER
00125 if (destLen > 500000)
00126 {
00127 if (destLen > 2400000)
00128 {
00129 Logger::log(S3D::formatStringBuffer("ERROR: Asked to allocated %u bytes", destLen));
00130 return false;
00131 }
00132 else
00133 {
00134 Logger::log(S3D::formatStringBuffer("Warning: Asked to allocated %u bytes", destLen));
00135 }
00136 }
00137 #endif
00138
00139 NetBuffer *newBuffer = NetBufferPool::instance()->getFromPool();
00140 newBuffer->allocate(destLen);
00141 newBuffer->setBufferUsed(destLen);
00142
00143
00144 if (uncompress((unsigned char *) newBuffer->getBuffer(), &destLen,
00145 (unsigned char *) (getBuffer() + 4), srcLen) == Z_OK)
00146 {
00147
00148 reset();
00149 addDataToBuffer(newBuffer->getBuffer(), newBuffer->getBufferUsed());
00150 }
00151 NetBufferPool::instance()->addToPool(newBuffer);
00152
00153 return true;
00154 }
00155
00156 void NetBuffer::resize(unsigned newBufferSize)
00157 {
00158 if (newBufferSize < startSize) newBufferSize = startSize;
00159 char *newBuffer = new char[newBufferSize];
00160 if (buffer_)
00161 {
00162 memcpy(newBuffer, buffer_, usedSize_);
00163 delete [] buffer_;
00164 }
00165 buffer_ = newBuffer;
00166 bufferSize_ = newBufferSize;
00167 }
00168
00169 void NetBuffer::addDataToBuffer(const void *add, unsigned len)
00170 {
00171 unsigned bufferLeft = bufferSize_ - usedSize_;
00172 if (!buffer_ || (bufferLeft < len))
00173 {
00174 unsigned sizeNeeded = len + usedSize_;
00175 unsigned newBufferSize = sizeNeeded * 2;
00176
00177 resize(newBufferSize);
00178 }
00179
00180 memcpy(&buffer_[usedSize_], add, len);
00181 usedSize_ += len;
00182 }
00183
00184 void NetBuffer::addToBuffer(Vector &add)
00185 {
00186 addToBuffer(add[0]);
00187 addToBuffer(add[1]);
00188 addToBuffer(add[2]);
00189 }
00190
00191 void NetBuffer::addToBuffer(FixedVector &add)
00192 {
00193 addToBuffer(add[0]);
00194 addToBuffer(add[1]);
00195 addToBuffer(add[2]);
00196 }
00197
00198 void NetBuffer::addToBuffer(FixedVector4 &add)
00199 {
00200 addToBuffer(add[0]);
00201 addToBuffer(add[1]);
00202 addToBuffer(add[2]);
00203 addToBuffer(add[3]);
00204 }
00205
00206 void NetBuffer::addToBuffer(const fixed add)
00207 {
00208 Uint32 value = 0;
00209 SDLNet_Write32(fixed(add).getInternal(), &value);
00210 addDataToBuffer(&value, sizeof(Uint32));
00211 }
00212
00213 void NetBuffer::addToBuffer(const int add)
00214 {
00215 Uint32 value = 0;
00216 SDLNet_Write32(add, &value);
00217 addDataToBuffer(&value, sizeof(Uint32));
00218 }
00219
00220 void NetBuffer::addToBuffer(const float addf)
00221 {
00222 Uint32 value = 0;
00223 Uint32 add = 0;
00224 memcpy(&add, &addf, sizeof(Uint32));
00225 SDLNet_Write32(add, &value);
00226 addDataToBuffer(&value, sizeof(Uint32));
00227 }
00228
00229 void NetBuffer::addToBuffer(const bool add)
00230 {
00231 char c = (add?'1':'0');
00232 addDataToBuffer(&c, sizeof(char));
00233 }
00234
00235 void NetBuffer::addToBuffer(const char add)
00236 {
00237 addDataToBuffer(&add, sizeof(char));
00238 }
00239
00240 void NetBuffer::addToBuffer(const unsigned int add)
00241 {
00242 Uint32 value = 0;
00243 SDLNet_Write32(add, &value);
00244 addDataToBuffer(&value, sizeof(Uint32));
00245 }
00246
00247 void NetBuffer::addToBuffer(const char *add)
00248 {
00249 addDataToBuffer(add, (unsigned) strlen(add)+1);
00250 }
00251
00252 void NetBuffer::addToBuffer(const std::string &string)
00253 {
00254 addToBuffer(string.c_str());
00255 }
00256
00257 void NetBuffer::addToBuffer(std::string &string)
00258 {
00259 addToBuffer(string.c_str());
00260 }
00261
00262 void NetBuffer::addToBuffer(const LangString &string)
00263 {
00264 for (unsigned int i=0; i<=string.size(); i++)
00265 {
00266 addToBuffer(string.c_str()[i]);
00267 }
00268 }
00269
00270 void NetBuffer::addToBuffer(LangString &string)
00271 {
00272 addToBuffer((const LangString &) string);
00273 }
00274
00275 void NetBuffer::addToBuffer(NetBuffer &add)
00276 {
00277 addToBuffer(add.getBufferUsed());
00278 addDataToBuffer(add.getBuffer(), add.getBufferUsed());
00279 }
00280
00281 NetBufferReader::NetBufferReader() :
00282 buffer_(0),
00283 bufferSize_(0),
00284 readSize_(0)
00285 {
00286 }
00287
00288 NetBufferReader::NetBufferReader(NetBuffer &buffer) :
00289 buffer_(buffer.getBuffer()),
00290 bufferSize_(buffer.getBufferUsed()),
00291 readSize_(0)
00292 {
00293 }
00294
00295 NetBufferReader::~NetBufferReader()
00296 {
00297 }
00298
00299 void NetBufferReader::reset()
00300 {
00301 readSize_ = 0;
00302 }
00303
00304 bool NetBufferReader::getFromBuffer(Vector &result)
00305 {
00306 if (!getFromBuffer(result[0])) return false;
00307 if (!getFromBuffer(result[1])) return false;
00308 if (!getFromBuffer(result[2])) return false;
00309 return true;
00310 }
00311
00312 bool NetBufferReader::getFromBuffer(FixedVector &result)
00313 {
00314 if (!getFromBuffer(result[0])) return false;
00315 if (!getFromBuffer(result[1])) return false;
00316 if (!getFromBuffer(result[2])) return false;
00317 return true;
00318 }
00319
00320 bool NetBufferReader::getFromBuffer(FixedVector4 &result)
00321 {
00322 if (!getFromBuffer(result[0])) return false;
00323 if (!getFromBuffer(result[1])) return false;
00324 if (!getFromBuffer(result[2])) return false;
00325 if (!getFromBuffer(result[3])) return false;
00326 return true;
00327 }
00328
00329 bool NetBufferReader::getFromBuffer(int &result)
00330 {
00331 Uint32 value = 0;
00332 if (!getDataFromBuffer(&value, sizeof(value))) return false;
00333 result = SDLNet_Read32(&value);
00334 return true;
00335 }
00336
00337 bool NetBufferReader::getFromBuffer(fixed &result)
00338 {
00339 Uint32 value = 0;
00340 if (!getDataFromBuffer(&value, sizeof(value))) return false;
00341 result = fixed(true, SDLNet_Read32(&value));
00342 return true;
00343 }
00344
00345 bool NetBufferReader::getFromBuffer(float &resultf)
00346 {
00347 Uint32 value = 0;
00348 if (!getDataFromBuffer(&value, sizeof(value))) return false;
00349 Uint32 result = SDLNet_Read32(&value);
00350 memcpy(&resultf, &result, sizeof(Uint32));
00351 return true;
00352 }
00353
00354 bool NetBufferReader::getFromBuffer(bool &result)
00355 {
00356 char c = 0;
00357 if (!getDataFromBuffer(&c, sizeof(c))) return false;
00358 result = (c=='1'?true:false);
00359 return true;
00360 }
00361
00362 bool NetBufferReader::getFromBuffer(char &result)
00363 {
00364 if (!getDataFromBuffer(&result, sizeof(result))) return false;
00365 return true;
00366 }
00367
00368 bool NetBufferReader::getFromBuffer(unsigned int &result)
00369 {
00370 Uint32 value = 0;
00371 if (!getDataFromBuffer(&value, sizeof(value))) return false;
00372 result = SDLNet_Read32(&value);
00373 return true;
00374 }
00375
00376 bool NetBufferReader::getFromBuffer(std::string &result, bool safe)
00377 {
00378 int i;
00379 for (i=0; buffer_[readSize_ + i]; i++);
00380 i++;
00381
00382 char *value = new char[i+1];
00383 if (getDataFromBuffer(value, i))
00384 {
00385 if (safe)
00386 {
00387 for (int j=0; j<i; j++)
00388 {
00389 if (value[j] == '%') value[j] = ' ';
00390 }
00391 }
00392
00393 result = value;
00394 delete [] value;
00395
00396 return true;
00397 }
00398
00399 delete [] value;
00400 return false;
00401 }
00402
00403 bool NetBufferReader::getFromBuffer(LangString &result)
00404 {
00405 result.clear();
00406 unsigned int value = 0;
00407 for (;;)
00408 {
00409 if (!getFromBuffer(value)) return false;
00410 if (!value) break;
00411 result.push_back(value);
00412 }
00413
00414 return true;
00415 }
00416
00417 bool NetBufferReader::getFromBuffer(NetBuffer &buffer)
00418 {
00419 buffer.reset();
00420 unsigned int bufferSize = 0;
00421 if (!getFromBuffer(bufferSize)) return false;
00422 buffer.resize(bufferSize);
00423 buffer.setBufferUsed(bufferSize);
00424 return getDataFromBuffer(buffer.getBuffer(), bufferSize);
00425 }
00426
00427 bool NetBufferReader::getDataFromBuffer(void *dest, int len)
00428 {
00429 unsigned bufferLeft = bufferSize_ - readSize_;
00430 if (bufferLeft < (unsigned) len) return false;
00431
00432 memcpy(dest, &buffer_[readSize_], len);
00433 readSize_ += len;
00434 return true;
00435 }