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