00001 // Filename: datagram.I 00002 // Created by: drose (06Jun00) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // Function: Datagram::Constructor 00021 // Access: Public 00022 // Description: Constructs an empty datagram. 00023 //////////////////////////////////////////////////////////////////// 00024 INLINE Datagram:: 00025 Datagram() { 00026 } 00027 00028 //////////////////////////////////////////////////////////////////// 00029 // Function: Datagram::Constructor 00030 // Access: Public 00031 // Description: Constructs a datagram from an existing block of data. 00032 //////////////////////////////////////////////////////////////////// 00033 INLINE Datagram:: 00034 Datagram(const void *data, size_t size) { 00035 append_data(data, size); 00036 } 00037 00038 //////////////////////////////////////////////////////////////////// 00039 // Function: Datagram::Constructor 00040 // Access: Public 00041 // Description: Constructs a datagram from an existing block of data. 00042 //////////////////////////////////////////////////////////////////// 00043 INLINE Datagram:: 00044 Datagram(const string &data) { 00045 append_data(data); 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: Datagram::Copy Constructor 00050 // Access: Public 00051 // Description: 00052 //////////////////////////////////////////////////////////////////// 00053 INLINE Datagram:: 00054 Datagram(const Datagram ©) : 00055 _data(copy._data) 00056 { 00057 } 00058 00059 //////////////////////////////////////////////////////////////////// 00060 // Function: Datagram::Copy Assignment Operator 00061 // Access: Public 00062 // Description: 00063 //////////////////////////////////////////////////////////////////// 00064 INLINE void Datagram:: 00065 operator = (const Datagram ©) { 00066 _data = copy._data; 00067 } 00068 00069 //////////////////////////////////////////////////////////////////// 00070 // Function: Datagram::add_bool 00071 // Access: Public 00072 // Description: Adds a boolean value to the datagram. 00073 //////////////////////////////////////////////////////////////////// 00074 INLINE void Datagram:: 00075 add_bool(bool b) { 00076 add_uint8(b); 00077 } 00078 00079 //////////////////////////////////////////////////////////////////// 00080 // Function: Datagram::add_int8 00081 // Access: Public 00082 // Description: Adds a signed 8-bit integer to the datagram. 00083 //////////////////////////////////////////////////////////////////// 00084 INLINE void Datagram:: 00085 add_int8(PN_int8 value) { 00086 append_data(&value, 1); 00087 } 00088 00089 //////////////////////////////////////////////////////////////////// 00090 // Function: Datagram::add_uint8 00091 // Access: Public 00092 // Description: Adds an unsigned 8-bit integer to the datagram. 00093 //////////////////////////////////////////////////////////////////// 00094 INLINE void Datagram:: 00095 add_uint8(PN_uint8 value) { 00096 append_data(&value, 1); 00097 } 00098 00099 //////////////////////////////////////////////////////////////////// 00100 // Function: Datagram::add_int16 00101 // Access: Public 00102 // Description: Adds a signed 16-bit integer to the datagram. 00103 //////////////////////////////////////////////////////////////////// 00104 INLINE void Datagram:: 00105 add_int16(PN_int16 value) { 00106 LittleEndian s(&value, sizeof(value)); 00107 append_data(s.get_data(), sizeof(value)); 00108 } 00109 00110 //////////////////////////////////////////////////////////////////// 00111 // Function: Datagram::add_int32 00112 // Access: Public 00113 // Description: Adds a signed 32-bit integer to the datagram. 00114 //////////////////////////////////////////////////////////////////// 00115 INLINE void Datagram:: 00116 add_int32(PN_int32 value) { 00117 LittleEndian s(&value, sizeof(value)); 00118 append_data(s.get_data(), sizeof(value)); 00119 } 00120 00121 //////////////////////////////////////////////////////////////////// 00122 // Function: Datagram::add_int64 00123 // Access: Public 00124 // Description: Adds a signed 64-bit integer to the datagram. 00125 //////////////////////////////////////////////////////////////////// 00126 INLINE void Datagram:: 00127 add_int64(PN_int64 value) { 00128 LittleEndian s(&value, sizeof(value)); 00129 append_data(s.get_data(), sizeof(value)); 00130 } 00131 00132 //////////////////////////////////////////////////////////////////// 00133 // Function: Datagram::add_uint16 00134 // Access: Public 00135 // Description: Adds an unsigned 16-bit integer to the datagram. 00136 //////////////////////////////////////////////////////////////////// 00137 INLINE void Datagram:: 00138 add_uint16(PN_uint16 value) { 00139 LittleEndian s(&value, sizeof(value)); 00140 append_data(s.get_data(), sizeof(value)); 00141 } 00142 00143 //////////////////////////////////////////////////////////////////// 00144 // Function: Datagram::add_uint32 00145 // Access: Public 00146 // Description: Adds an unsigned 32-bit integer to the datagram. 00147 //////////////////////////////////////////////////////////////////// 00148 INLINE void Datagram:: 00149 add_uint32(PN_uint32 value) { 00150 LittleEndian s(&value, sizeof(value)); 00151 append_data(s.get_data(), sizeof(value)); 00152 } 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Function: Datagram::add_uint64 00156 // Access: Public 00157 // Description: Adds an unsigned 64-bit integer to the datagram. 00158 //////////////////////////////////////////////////////////////////// 00159 INLINE void Datagram:: 00160 add_uint64(PN_uint64 value) { 00161 LittleEndian s(&value, sizeof(value)); 00162 append_data(s.get_data(), sizeof(value)); 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: Datagram::add_float32 00167 // Access: Public 00168 // Description: Adds a 32-bit single-precision floating-point number 00169 // to the datagram. Since this kind of float is not 00170 // necessarily portable across different architectures, 00171 // special care is required. 00172 //////////////////////////////////////////////////////////////////// 00173 INLINE void Datagram:: 00174 add_float32(float value) { 00175 // For now, we assume the float format is portable across all 00176 // architectures we are concerned with. If we come across one that 00177 // is different, we will have to convert. 00178 nassertv(sizeof(value) == 4); 00179 LittleEndian s(&value, sizeof(value)); 00180 append_data(s.get_data(), sizeof(value)); 00181 } 00182 00183 //////////////////////////////////////////////////////////////////// 00184 // Function: Datagram::add_float64 00185 // Access: Public 00186 // Description: Adds a 64-bit floating-point number to the datagram. 00187 //////////////////////////////////////////////////////////////////// 00188 INLINE void Datagram:: 00189 add_float64(PN_float64 value) { 00190 LittleEndian s(&value, sizeof(value)); 00191 append_data(s.get_data(), sizeof(value)); 00192 } 00193 00194 //////////////////////////////////////////////////////////////////// 00195 // Function: Datagram::add_be_int16 00196 // Access: Public 00197 // Description: Adds a signed 16-bit big-endian integer to the 00198 // datagram. 00199 //////////////////////////////////////////////////////////////////// 00200 INLINE void Datagram:: 00201 add_be_int16(PN_int16 value) { 00202 BigEndian s(&value, sizeof(value)); 00203 append_data(s.get_data(), sizeof(value)); 00204 } 00205 00206 //////////////////////////////////////////////////////////////////// 00207 // Function: Datagram::add_be_int32 00208 // Access: Public 00209 // Description: Adds a signed 32-bit big-endian integer to the 00210 // datagram. 00211 //////////////////////////////////////////////////////////////////// 00212 INLINE void Datagram:: 00213 add_be_int32(PN_int32 value) { 00214 BigEndian s(&value, sizeof(value)); 00215 append_data(s.get_data(), sizeof(value)); 00216 } 00217 00218 //////////////////////////////////////////////////////////////////// 00219 // Function: Datagram::add_be_int64 00220 // Access: Public 00221 // Description: Adds a signed 64-bit big-endian integer to the 00222 // datagram. 00223 //////////////////////////////////////////////////////////////////// 00224 INLINE void Datagram:: 00225 add_be_int64(PN_int64 value) { 00226 BigEndian s(&value, sizeof(value)); 00227 append_data(s.get_data(), sizeof(value)); 00228 } 00229 00230 //////////////////////////////////////////////////////////////////// 00231 // Function: Datagram::add_be_uint16 00232 // Access: Public 00233 // Description: Adds an unsigned 16-bit big-endian integer to the 00234 // datagram. 00235 //////////////////////////////////////////////////////////////////// 00236 INLINE void Datagram:: 00237 add_be_uint16(PN_uint16 value) { 00238 BigEndian s(&value, sizeof(value)); 00239 append_data(s.get_data(), sizeof(value)); 00240 } 00241 00242 //////////////////////////////////////////////////////////////////// 00243 // Function: Datagram::add_be_uint32 00244 // Access: Public 00245 // Description: Adds an unsigned 32-bit big-endian integer to the 00246 // datagram. 00247 //////////////////////////////////////////////////////////////////// 00248 INLINE void Datagram:: 00249 add_be_uint32(PN_uint32 value) { 00250 BigEndian s(&value, sizeof(value)); 00251 append_data(s.get_data(), sizeof(value)); 00252 } 00253 00254 //////////////////////////////////////////////////////////////////// 00255 // Function: Datagram::add_be_uint64 00256 // Access: Public 00257 // Description: Adds an unsigned 64-bit big-endian integer to the 00258 // datagram. 00259 //////////////////////////////////////////////////////////////////// 00260 INLINE void Datagram:: 00261 add_be_uint64(PN_uint64 value) { 00262 BigEndian s(&value, sizeof(value)); 00263 append_data(s.get_data(), sizeof(value)); 00264 } 00265 00266 //////////////////////////////////////////////////////////////////// 00267 // Function: Datagram::add_be_float32 00268 // Access: Public 00269 // Description: Adds a 32-bit single-precision big-endian 00270 // floating-point number to the datagram. Since this 00271 // kind of float is not necessarily portable across 00272 // different architectures, special care is required. 00273 //////////////////////////////////////////////////////////////////// 00274 INLINE void Datagram:: 00275 add_be_float32(float value) { 00276 // For now, we assume the float format is portable across all 00277 // architectures we are concerned with. If we come across one that 00278 // is different, we will have to convert. 00279 nassertv(sizeof(value) == 4); 00280 BigEndian s(&value, sizeof(value)); 00281 append_data(s.get_data(), sizeof(value)); 00282 } 00283 00284 //////////////////////////////////////////////////////////////////// 00285 // Function: Datagram::add_be_float64 00286 // Access: Public 00287 // Description: Adds a 64-bit big-endian floating-point number to the 00288 // datagram. 00289 //////////////////////////////////////////////////////////////////// 00290 INLINE void Datagram:: 00291 add_be_float64(PN_float64 value) { 00292 BigEndian s(&value, sizeof(value)); 00293 append_data(s.get_data(), sizeof(value)); 00294 } 00295 00296 //////////////////////////////////////////////////////////////////// 00297 // Function: Datagram::add_string 00298 // Access: Public 00299 // Description: Adds a variable-length string to the datagram. This 00300 // actually adds a count followed by n bytes. 00301 //////////////////////////////////////////////////////////////////// 00302 INLINE void Datagram:: 00303 add_string(const string &str) { 00304 // The max sendable length for a string is 2^16. 00305 nassertv(str.length() <= (PN_uint16)0xffff); 00306 00307 // Strings always are preceded by their length 00308 add_uint16(str.length()); 00309 00310 // Add the string 00311 append_data(str); 00312 } 00313 00314 //////////////////////////////////////////////////////////////////// 00315 // Function: Datagram::add_z_string 00316 // Access: Public 00317 // Description: Adds a variable-length string to the datagram, as a 00318 // NULL-terminated string. 00319 //////////////////////////////////////////////////////////////////// 00320 INLINE void Datagram:: 00321 add_z_string(string str) { 00322 // We must not have any nested null characters in the string. 00323 size_t null_pos = str.find('\0'); 00324 // Add the string (sans the null character). 00325 append_data(str.substr(0, null_pos)); 00326 00327 // And the null character. 00328 add_uint8('\0'); 00329 } 00330 00331 //////////////////////////////////////////////////////////////////// 00332 // Function: Datagram::add_fixed_string 00333 // Access: Public 00334 // Description: Adds a fixed-length string to the datagram. If the 00335 // string given is less than the requested size, this 00336 // will pad the string out with zeroes; if it is greater 00337 // than the requested size, this will silently truncate 00338 // the string. 00339 //////////////////////////////////////////////////////////////////// 00340 INLINE void Datagram:: 00341 add_fixed_string(const string &str, size_t size) { 00342 if (str.length() < size) { 00343 append_data(str); 00344 pad_bytes(size - str.length()); 00345 00346 } else { // str.length() >= size 00347 append_data(str.substr(0, size)); 00348 } 00349 } 00350 00351 //////////////////////////////////////////////////////////////////// 00352 // Function: Datagram::append_data 00353 // Access: Public 00354 // Description: Appends some more raw data to the end of the 00355 // datagram. 00356 //////////////////////////////////////////////////////////////////// 00357 INLINE void Datagram:: 00358 append_data(const string &data) { 00359 append_data(data.data(), data.length()); 00360 } 00361 00362 //////////////////////////////////////////////////////////////////// 00363 // Function: Datagram::get_message 00364 // Access: Public 00365 // Description: Returns the datagram's data as a string. 00366 //////////////////////////////////////////////////////////////////// 00367 INLINE string Datagram:: 00368 get_message() const { 00369 return string((const char *)_data.p(), _data.size()); 00370 } 00371 00372 //////////////////////////////////////////////////////////////////// 00373 // Function: Datagram::get_data 00374 // Access: Public 00375 // Description: Returns a pointer to the beginning of the datagram's 00376 // data. 00377 //////////////////////////////////////////////////////////////////// 00378 INLINE const void *Datagram:: 00379 get_data() const { 00380 return _data.p(); 00381 } 00382 00383 //////////////////////////////////////////////////////////////////// 00384 // Function: Datagram::get_length 00385 // Access: Public 00386 // Description: Returns the number of bytes in the datagram. 00387 //////////////////////////////////////////////////////////////////// 00388 INLINE size_t Datagram:: 00389 get_length() const { 00390 return _data.size(); 00391 } 00392 00393 //////////////////////////////////////////////////////////////////// 00394 // Function: Datagram::operator == 00395 // Access: Public 00396 // Description: 00397 //////////////////////////////////////////////////////////////////// 00398 INLINE bool Datagram:: 00399 operator == (const Datagram &other) const { 00400 if (_data == other._data) { 00401 return true; 00402 } 00403 if (_data != (uchar *)NULL && other._data != (uchar *)NULL) { 00404 return _data.v() == other._data.v(); 00405 } 00406 return false; 00407 } 00408 00409 //////////////////////////////////////////////////////////////////// 00410 // Function: Datagram::operator != 00411 // Access: Public 00412 // Description: 00413 //////////////////////////////////////////////////////////////////// 00414 INLINE bool Datagram:: 00415 operator != (const Datagram &other) const { 00416 return !operator == (other); 00417 } 00418 00419 //////////////////////////////////////////////////////////////////// 00420 // Function: Datagram::operator < 00421 // Access: Public 00422 // Description: 00423 //////////////////////////////////////////////////////////////////// 00424 INLINE bool Datagram:: 00425 operator < (const Datagram &other) const { 00426 if (_data == other._data) { 00427 // Same pointers. 00428 return false; 00429 } 00430 00431 if (_data != (uchar *)NULL && other._data != (uchar *)NULL) { 00432 // Different pointers, neither NULL. 00433 return _data.v() < other._data.v(); 00434 } 00435 00436 // One of the pointers is NULL, but not the other one. 00437 return _data.size() < other._data.size(); 00438 }