SFML logo
  • Main Page
  • Namespaces
  • Classes
  • Files
  • File List

Packet.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Network/Packet.hpp>
00029 #include <SFML/Network/SocketHelper.hpp>
00030 #include <SFML/System/String.hpp>
00031 #include <string.h>
00032 
00033 
00034 namespace sf
00035 {
00039 Packet::Packet() :
00040 myReadPos(0),
00041 myIsValid(true)
00042 {
00043 
00044 }
00045 
00046 
00050 Packet::~Packet()
00051 {
00052 
00053 }
00054 
00055 
00059 void Packet::Append(const void* data, std::size_t sizeInBytes)
00060 {
00061     if (data && (sizeInBytes > 0))
00062     {
00063         std::size_t start = myData.size();
00064         myData.resize(start + sizeInBytes);
00065         memcpy(&myData[start], data, sizeInBytes);
00066     }
00067 }
00068 
00069 
00073 void Packet::Clear()
00074 {
00075     myData.clear();
00076     myReadPos = 0;
00077     myIsValid = true;
00078 }
00079 
00080 
00086 const char* Packet::GetData() const
00087 {
00088     return !myData.empty() ? &myData[0] : NULL;
00089 }
00090 
00091 
00095 std::size_t Packet::GetDataSize() const
00096 {
00097     return myData.size();
00098 }
00099 
00100 
00104 bool Packet::EndOfPacket() const
00105 {
00106     return myReadPos >= myData.size();
00107 }
00108 
00109 
00113 Packet::operator bool() const
00114 {
00115     return myIsValid;
00116 }
00117 
00118 
00122 Packet& Packet::operator >>(bool& data)
00123 {
00124     Uint8 value;
00125     if (*this >> value)
00126         data = (value != 0);
00127 
00128     return *this;
00129 }
00130 Packet& Packet::operator >>(Int8& data)
00131 {
00132     if (CheckSize(sizeof(data)))
00133     {
00134         data = *reinterpret_cast<const Int8*>(GetData() + myReadPos);
00135         myReadPos += sizeof(data);
00136     }
00137 
00138     return *this;
00139 }
00140 Packet& Packet::operator >>(Uint8& data)
00141 {
00142     if (CheckSize(sizeof(data)))
00143     {
00144         data = *reinterpret_cast<const Uint8*>(GetData() + myReadPos);
00145         myReadPos += sizeof(data);
00146     }
00147 
00148     return *this;
00149 }
00150 Packet& Packet::operator >>(Int16& data)
00151 {
00152     if (CheckSize(sizeof(data)))
00153     {
00154         data = ntohs(*reinterpret_cast<const Int16*>(GetData() + myReadPos));
00155         myReadPos += sizeof(data);
00156     }
00157 
00158     return *this;
00159 }
00160 Packet& Packet::operator >>(Uint16& data)
00161 {
00162     if (CheckSize(sizeof(data)))
00163     {
00164         data = ntohs(*reinterpret_cast<const Uint16*>(GetData() + myReadPos));
00165         myReadPos += sizeof(data);
00166     }
00167 
00168     return *this;
00169 }
00170 Packet& Packet::operator >>(Int32& data)
00171 {
00172     if (CheckSize(sizeof(data)))
00173     {
00174         data = ntohl(*reinterpret_cast<const Int32*>(GetData() + myReadPos));
00175         myReadPos += sizeof(data);
00176     }
00177 
00178     return *this;
00179 }
00180 Packet& Packet::operator >>(Uint32& data)
00181 {
00182     if (CheckSize(sizeof(data)))
00183     {
00184         data = ntohl(*reinterpret_cast<const Uint32*>(GetData() + myReadPos));
00185         myReadPos += sizeof(data);
00186     }
00187 
00188     return *this;
00189 }
00190 Packet& Packet::operator >>(float& data)
00191 {
00192     if (CheckSize(sizeof(data)))
00193     {
00194         data = *reinterpret_cast<const float*>(GetData() + myReadPos);
00195         myReadPos += sizeof(data);
00196     }
00197 
00198     return *this;
00199 }
00200 Packet& Packet::operator >>(double& data)
00201 {
00202     if (CheckSize(sizeof(data)))
00203     {
00204         data = *reinterpret_cast<const double*>(GetData() + myReadPos);
00205         myReadPos += sizeof(data);
00206     }
00207 
00208     return *this;
00209 }
00210 Packet& Packet::operator >>(char* data)
00211 {
00212     // First extract string length
00213     Uint32 length;
00214     *this >> length;
00215 
00216     if ((length > 0) && CheckSize(length))
00217     {
00218         // Then extract characters
00219         memcpy(data, GetData() + myReadPos, length);
00220         data[length] = '\0';
00221 
00222         // Update reading position
00223         myReadPos += length;
00224     }
00225 
00226     return *this;
00227 }
00228 Packet& Packet::operator >>(std::string& data)
00229 {
00230     // First extract string length
00231     Uint32 length;
00232     *this >> length;
00233 
00234     data.clear();
00235     if ((length > 0) && CheckSize(length))
00236     {
00237         // Then extract characters
00238         data.assign(GetData() + myReadPos, length);
00239 
00240         // Update reading position
00241         myReadPos += length;
00242     }
00243 
00244     return *this;
00245 }
00246 Packet& Packet::operator >>(wchar_t* data)
00247 {
00248     // First extract string length
00249     Uint32 length;
00250     *this >> length;
00251 
00252     if ((length > 0) && CheckSize(length * sizeof(Uint32)))
00253     {
00254         // Then extract characters
00255         for (Uint32 i = 0; i < length; ++i)
00256         {
00257             Uint32 character;
00258             *this >> character;
00259             data[i] = static_cast<wchar_t>(character);
00260         }
00261         data[length] = L'\0';
00262     }
00263 
00264     return *this;
00265 }
00266 Packet& Packet::operator >>(std::wstring& data)
00267 {
00268     // First extract string length
00269     Uint32 length;
00270     *this >> length;
00271 
00272     data.clear();
00273     if ((length > 0) && CheckSize(length * sizeof(Uint32)))
00274     {
00275         // Then extract characters
00276         for (Uint32 i = 0; i < length; ++i)
00277         {
00278             Uint32 character;
00279             *this >> character;
00280             data += static_cast<wchar_t>(character);
00281         }
00282     }
00283 
00284     return *this;
00285 }
00286 Packet& Packet::operator >>(String& data)
00287 {
00288     // First extract the string length
00289     Uint32 length;
00290     *this >> length;
00291 
00292     data.Clear();
00293     if ((length > 0) && CheckSize(length * sizeof(Uint32)))
00294     {
00295         // Then extract characters
00296         for (Uint32 i = 0; i < length; ++i)
00297         {
00298             Uint32 character;
00299             *this >> character;
00300             data += character;
00301         }
00302     }
00303 
00304     return *this;
00305 }
00306 
00307 
00311 Packet& Packet::operator <<(bool data)
00312 {
00313     *this << static_cast<Uint8>(data);
00314     return *this;
00315 }
00316 Packet& Packet::operator <<(Int8 data)
00317 {
00318     Append(&data, sizeof(data));
00319     return *this;
00320 }
00321 Packet& Packet::operator <<(Uint8 data)
00322 {
00323     Append(&data, sizeof(data));
00324     return *this;
00325 }
00326 Packet& Packet::operator <<(Int16 data)
00327 {
00328     Int16 toWrite = htons(data);
00329     Append(&toWrite, sizeof(toWrite));
00330     return *this;
00331 }
00332 Packet& Packet::operator <<(Uint16 data)
00333 {
00334     Uint16 toWrite = htons(data);
00335     Append(&toWrite, sizeof(toWrite));
00336     return *this;
00337 }
00338 Packet& Packet::operator <<(Int32 data)
00339 {
00340     Int32 toWrite = htonl(data);
00341     Append(&toWrite, sizeof(toWrite));
00342     return *this;
00343 }
00344 Packet& Packet::operator <<(Uint32 data)
00345 {
00346     Uint32 toWrite = htonl(data);
00347     Append(&toWrite, sizeof(toWrite));
00348     return *this;
00349 }
00350 Packet& Packet::operator <<(float data)
00351 {
00352     Append(&data, sizeof(data));
00353     return *this;
00354 }
00355 Packet& Packet::operator <<(double data)
00356 {
00357     Append(&data, sizeof(data));
00358     return *this;
00359 }
00360 Packet& Packet::operator <<(const char* data)
00361 {
00362     // First insert string length
00363     Uint32 length = 0;
00364     for (const char* c = data; *c != '\0'; ++c)
00365         ++length;
00366     *this << length;
00367 
00368     // Then insert characters
00369     Append(data, length * sizeof(char));
00370 
00371     return *this;
00372 }
00373 Packet& Packet::operator <<(const std::string& data)
00374 {
00375     // First insert string length
00376     Uint32 length = static_cast<Uint32>(data.size());
00377     *this << length;
00378 
00379     // Then insert characters
00380     if (length > 0)
00381     {
00382         Append(data.c_str(), length * sizeof(std::string::value_type));
00383     }
00384 
00385     return *this;
00386 }
00387 Packet& Packet::operator <<(const wchar_t* data)
00388 {
00389     // First insert string length
00390     Uint32 length = 0;
00391     for (const wchar_t* c = data; *c != L'\0'; ++c)
00392         ++length;
00393     *this << length;
00394 
00395     // Then insert characters
00396     for (const wchar_t* c = data; *c != L'\0'; ++c)
00397         *this << static_cast<Uint32>(*c);
00398 
00399     return *this;
00400 }
00401 Packet& Packet::operator <<(const std::wstring& data)
00402 {
00403     // First insert string length
00404     Uint32 length = static_cast<Uint32>(data.size());
00405     *this << length;
00406 
00407     // Then insert characters
00408     if (length > 0)
00409     {
00410         for (std::wstring::const_iterator c = data.begin(); c != data.end(); ++c)
00411             *this << static_cast<Uint32>(*c);
00412     }
00413 
00414     return *this;
00415 }
00416 Packet& Packet::operator <<(const String& data)
00417 {
00418     // First insert the string length
00419     Uint32 length = static_cast<Uint32>(data.GetSize());
00420     *this << length;
00421 
00422     // Then insert characters
00423     if (length > 0)
00424     {
00425         for (String::ConstIterator c = data.Begin(); c != data.End(); ++c)
00426             *this << *c;
00427     }
00428 
00429     return *this;
00430 }
00431 
00432 
00436 bool Packet::CheckSize(std::size_t size)
00437 {
00438     myIsValid = myIsValid && (myReadPos + size <= myData.size());
00439 
00440     return myIsValid;
00441 }
00442 
00443 
00447 const char* Packet::OnSend(std::size_t& dataSize)
00448 {
00449     dataSize = GetDataSize();
00450     return GetData();
00451 }
00452 
00453 
00457 void Packet::OnReceive(const char* data, std::size_t dataSize)
00458 {
00459     Append(data, dataSize);
00460 }
00461 
00462 } // namespace sf

 ::  Copyright © 2007-2008 Laurent Gomila, all rights reserved  ::  Documentation generated by doxygen 1.5.2  ::