Panda3D
|
00001 // Filename: dcPackerInterface.I 00002 // Created by: drose (18Jun04) 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 //////////////////////////////////////////////////////////////////// 00017 // Function: DCPackerInterface::get_name 00018 // Access: Published 00019 // Description: Returns the name of this field, or empty string 00020 // if the field is unnamed. 00021 //////////////////////////////////////////////////////////////////// 00022 INLINE const string &DCPackerInterface:: 00023 get_name() const { 00024 return _name; 00025 } 00026 00027 //////////////////////////////////////////////////////////////////// 00028 // Function: DCPackerInterface::check_match 00029 // Access: Published 00030 // Description: Returns true if the other interface is bitwise the 00031 // same as this one--that is, a uint32 only matches a 00032 // uint32, etc. Names of components, and range limits, 00033 // are not compared. 00034 //////////////////////////////////////////////////////////////////// 00035 INLINE bool DCPackerInterface:: 00036 check_match(const DCPackerInterface *other) const { 00037 return do_check_match(other); 00038 } 00039 00040 //////////////////////////////////////////////////////////////////// 00041 // Function: DCPackerInterface::has_fixed_byte_size 00042 // Access: Public 00043 // Description: Returns true if this field type always packs to the 00044 // same number of bytes, false if it is variable. 00045 //////////////////////////////////////////////////////////////////// 00046 INLINE bool DCPackerInterface:: 00047 has_fixed_byte_size() const { 00048 return _has_fixed_byte_size; 00049 } 00050 00051 //////////////////////////////////////////////////////////////////// 00052 // Function: DCPackerInterface::get_fixed_byte_size 00053 // Access: Public 00054 // Description: If has_fixed_byte_size() returns true, this returns 00055 // the number of bytes this field type will use. 00056 //////////////////////////////////////////////////////////////////// 00057 INLINE size_t DCPackerInterface:: 00058 get_fixed_byte_size() const { 00059 return _fixed_byte_size; 00060 } 00061 00062 //////////////////////////////////////////////////////////////////// 00063 // Function: DCPackerInterface::has_fixed_structure 00064 // Access: Public 00065 // Description: Returns true if this field type always has the same 00066 // structure regardless of the data in the stream, or 00067 // false if its structure may vary. This is almost, but 00068 // not quite, the same thing as has_fixed_byte_size. 00069 // The difference is that a DCSwitch may have multiple 00070 // cases all with the same byte size, but they will 00071 // still (presumably) have different structures, in the 00072 // sense that the actual list of fields varies according 00073 // to the live data. 00074 //////////////////////////////////////////////////////////////////// 00075 INLINE bool DCPackerInterface:: 00076 has_fixed_structure() const { 00077 return _has_fixed_structure; 00078 } 00079 00080 //////////////////////////////////////////////////////////////////// 00081 // Function: DCPackerInterface::has_range_limits 00082 // Access: Public 00083 // Description: Returns true if this field, or any sub-field of this 00084 // field, has a limit imposed in the DC file on its 00085 // legal values. If this is false, then 00086 // unpack_validate() is trivial. 00087 //////////////////////////////////////////////////////////////////// 00088 INLINE bool DCPackerInterface:: 00089 has_range_limits() const { 00090 return _has_range_limits; 00091 } 00092 00093 //////////////////////////////////////////////////////////////////// 00094 // Function: DCPackerInterface::get_num_length_bytes 00095 // Access: Public 00096 // Description: Returns the number of bytes that should be written 00097 // into the stream on a push() to record the number of 00098 // bytes in the record up until the next pop(). This is 00099 // only meaningful if _has_nested_fields is true. 00100 //////////////////////////////////////////////////////////////////// 00101 INLINE size_t DCPackerInterface:: 00102 get_num_length_bytes() const { 00103 return _num_length_bytes; 00104 } 00105 00106 00107 //////////////////////////////////////////////////////////////////// 00108 // Function: DCPackerInterface::has_nested_fields 00109 // Access: Public 00110 // Description: Returns true if this field type has any nested fields 00111 // (and thus expects a push() .. pop() interface to the 00112 // DCPacker), or false otherwise. If this returns true, 00113 // get_num_nested_fields() may be called to determine 00114 // how many nested fields are expected. 00115 //////////////////////////////////////////////////////////////////// 00116 INLINE bool DCPackerInterface:: 00117 has_nested_fields() const { 00118 return _has_nested_fields; 00119 } 00120 00121 //////////////////////////////////////////////////////////////////// 00122 // Function: DCPackerInterface::get_num_nested_fields 00123 // Access: Public 00124 // Description: Returns the number of nested fields required by this 00125 // field type. These may be array elements or structure 00126 // elements. The return value may be -1 to indicate the 00127 // number of nested fields is variable. 00128 //////////////////////////////////////////////////////////////////// 00129 INLINE int DCPackerInterface:: 00130 get_num_nested_fields() const { 00131 return _num_nested_fields; 00132 } 00133 00134 //////////////////////////////////////////////////////////////////// 00135 // Function: DCPackerInterface::get_pack_type 00136 // Access: Public 00137 // Description: Returns the type of value expected by this field. 00138 //////////////////////////////////////////////////////////////////// 00139 INLINE DCPackType DCPackerInterface:: 00140 get_pack_type() const { 00141 return _pack_type; 00142 } 00143 00144 //////////////////////////////////////////////////////////////////// 00145 // Function: DCPackerInterface::do_pack_int8 00146 // Access: Public, Static 00147 // Description: 00148 //////////////////////////////////////////////////////////////////// 00149 INLINE void DCPackerInterface:: 00150 do_pack_int8(char *buffer, int value) { 00151 buffer[0] = (char)(value & 0xff); 00152 } 00153 00154 //////////////////////////////////////////////////////////////////// 00155 // Function: DCPackerInterface::do_pack_int16 00156 // Access: Public, Static 00157 // Description: 00158 //////////////////////////////////////////////////////////////////// 00159 INLINE void DCPackerInterface:: 00160 do_pack_int16(char *buffer, int value) { 00161 buffer[0] = (char)(value & 0xff); 00162 buffer[1] = (char)((value >> 8) & 0xff); 00163 } 00164 00165 //////////////////////////////////////////////////////////////////// 00166 // Function: DCPackerInterface::do_pack_int32 00167 // Access: Public, Static 00168 // Description: 00169 //////////////////////////////////////////////////////////////////// 00170 INLINE void DCPackerInterface:: 00171 do_pack_int32(char *buffer, int value) { 00172 buffer[0] = (char)(value & 0xff); 00173 buffer[1] = (char)((value >> 8) & 0xff); 00174 buffer[2] = (char)((value >> 16) & 0xff); 00175 buffer[3] = (char)((value >> 24) & 0xff); 00176 } 00177 00178 //////////////////////////////////////////////////////////////////// 00179 // Function: DCPackerInterface::do_pack_int64 00180 // Access: Public, Static 00181 // Description: 00182 //////////////////////////////////////////////////////////////////// 00183 INLINE void DCPackerInterface:: 00184 do_pack_int64(char *buffer, PN_int64 value) { 00185 buffer[0] = (char)(value & 0xff); 00186 buffer[1] = (char)((value >> 8) & 0xff); 00187 buffer[2] = (char)((value >> 16) & 0xff); 00188 buffer[3] = (char)((value >> 24) & 0xff); 00189 buffer[4] = (char)((value >> 32) & 0xff); 00190 buffer[5] = (char)((value >> 40) & 0xff); 00191 buffer[6] = (char)((value >> 48) & 0xff); 00192 buffer[7] = (char)((value >> 56) & 0xff); 00193 } 00194 00195 //////////////////////////////////////////////////////////////////// 00196 // Function: DCPackerInterface::do_pack_uint8 00197 // Access: Public, Static 00198 // Description: 00199 //////////////////////////////////////////////////////////////////// 00200 INLINE void DCPackerInterface:: 00201 do_pack_uint8(char *buffer, unsigned int value) { 00202 buffer[0] = (char)(value & 0xff); 00203 } 00204 00205 //////////////////////////////////////////////////////////////////// 00206 // Function: DCPackerInterface::do_pack_uint16 00207 // Access: Public, Static 00208 // Description: 00209 //////////////////////////////////////////////////////////////////// 00210 INLINE void DCPackerInterface:: 00211 do_pack_uint16(char *buffer, unsigned int value) { 00212 buffer[0] = (char)(value & 0xff); 00213 buffer[1] = (char)((value >> 8) & 0xff); 00214 } 00215 00216 //////////////////////////////////////////////////////////////////// 00217 // Function: DCPackerInterface::do_pack_uint32 00218 // Access: Public, Static 00219 // Description: 00220 //////////////////////////////////////////////////////////////////// 00221 INLINE void DCPackerInterface:: 00222 do_pack_uint32(char *buffer, unsigned int value) { 00223 buffer[0] = (char)(value & 0xff); 00224 buffer[1] = (char)((value >> 8) & 0xff); 00225 buffer[2] = (char)((value >> 16) & 0xff); 00226 buffer[3] = (char)((value >> 24) & 0xff); 00227 } 00228 00229 //////////////////////////////////////////////////////////////////// 00230 // Function: DCPackerInterface::do_pack_uint64 00231 // Access: Public, Static 00232 // Description: 00233 //////////////////////////////////////////////////////////////////// 00234 INLINE void DCPackerInterface:: 00235 do_pack_uint64(char *buffer, PN_uint64 value) { 00236 buffer[0] = (char)(value & 0xff); 00237 buffer[1] = (char)((value >> 8) & 0xff); 00238 buffer[2] = (char)((value >> 16) & 0xff); 00239 buffer[3] = (char)((value >> 24) & 0xff); 00240 buffer[4] = (char)((value >> 32) & 0xff); 00241 buffer[5] = (char)((value >> 40) & 0xff); 00242 buffer[6] = (char)((value >> 48) & 0xff); 00243 buffer[7] = (char)((value >> 56) & 0xff); 00244 } 00245 00246 //////////////////////////////////////////////////////////////////// 00247 // Function: DCPackerInterface::do_pack_float64 00248 // Access: Public, Static 00249 // Description: 00250 //////////////////////////////////////////////////////////////////// 00251 INLINE void DCPackerInterface:: 00252 do_pack_float64(char *buffer, double value) { 00253 #ifdef WORDS_BIGENDIAN 00254 // Reverse the byte ordering for big-endian machines. 00255 char *p = (char *)&value; 00256 for (size_t i = 0; i < 8; i++) { 00257 buffer[i] = p[7 - i]; 00258 } 00259 #else 00260 memcpy(buffer, &value, 8); 00261 #endif 00262 } 00263 00264 00265 //////////////////////////////////////////////////////////////////// 00266 // Function: DCPackerInterface::do_unpack_int8 00267 // Access: Public, Static 00268 // Description: 00269 //////////////////////////////////////////////////////////////////// 00270 INLINE int DCPackerInterface:: 00271 do_unpack_int8(const char *buffer) { 00272 return (int)(signed char)buffer[0]; 00273 } 00274 00275 //////////////////////////////////////////////////////////////////// 00276 // Function: DCPackerInterface::do_unpack_int16 00277 // Access: Public, Static 00278 // Description: 00279 //////////////////////////////////////////////////////////////////// 00280 INLINE int DCPackerInterface:: 00281 do_unpack_int16(const char *buffer) { 00282 return (int)((unsigned int)(unsigned char)buffer[0] | 00283 ((int)(signed char)buffer[1] << 8)); 00284 } 00285 00286 //////////////////////////////////////////////////////////////////// 00287 // Function: DCPackerInterface::do_unpack_int32 00288 // Access: Public, Static 00289 // Description: 00290 //////////////////////////////////////////////////////////////////// 00291 INLINE int DCPackerInterface:: 00292 do_unpack_int32(const char *buffer) { 00293 return (int)((unsigned int)(unsigned char)buffer[0] | 00294 ((unsigned int)(unsigned char)buffer[1] << 8) | 00295 ((unsigned int)(unsigned char)buffer[2] << 16) | 00296 ((int)(signed char)buffer[3] << 24)); 00297 } 00298 00299 //////////////////////////////////////////////////////////////////// 00300 // Function: DCPackerInterface::do_unpack_int64 00301 // Access: Public, Static 00302 // Description: 00303 //////////////////////////////////////////////////////////////////// 00304 INLINE PN_int64 DCPackerInterface:: 00305 do_unpack_int64(const char *buffer) { 00306 return (PN_int64)((PN_uint64)(unsigned char)buffer[0] | 00307 ((PN_uint64)(unsigned char)buffer[1] << 8) | 00308 ((PN_uint64)(unsigned char)buffer[2] << 16) | 00309 ((PN_uint64)(unsigned char)buffer[3] << 24) | 00310 ((PN_uint64)(unsigned char)buffer[4] << 32) | 00311 ((PN_uint64)(unsigned char)buffer[5] << 40) | 00312 ((PN_uint64)(unsigned char)buffer[6] << 48) | 00313 ((PN_int64)(signed char)buffer[7] << 54)); 00314 } 00315 //////////////////////////////////////////////////////////////////// 00316 // Function: DCPackerInterface::do_unpack_uint8 00317 // Access: Public, Static 00318 // Description: 00319 //////////////////////////////////////////////////////////////////// 00320 INLINE unsigned int DCPackerInterface:: 00321 do_unpack_uint8(const char *buffer) { 00322 return (unsigned int)(unsigned char)buffer[0]; 00323 } 00324 00325 //////////////////////////////////////////////////////////////////// 00326 // Function: DCPackerInterface::do_unpack_uint16 00327 // Access: Public, Static 00328 // Description: 00329 //////////////////////////////////////////////////////////////////// 00330 INLINE unsigned int DCPackerInterface:: 00331 do_unpack_uint16(const char *buffer) { 00332 return ((unsigned int)(unsigned char)buffer[0] | 00333 ((unsigned int)(unsigned char)buffer[1] << 8)); 00334 } 00335 00336 //////////////////////////////////////////////////////////////////// 00337 // Function: DCPackerInterface::do_unpack_uint32 00338 // Access: Public, Static 00339 // Description: 00340 //////////////////////////////////////////////////////////////////// 00341 INLINE unsigned int DCPackerInterface:: 00342 do_unpack_uint32(const char *buffer) { 00343 return ((unsigned int)(unsigned char)buffer[0] | 00344 ((unsigned int)(unsigned char)buffer[1] << 8) | 00345 ((unsigned int)(unsigned char)buffer[2] << 16) | 00346 ((unsigned int)(unsigned char)buffer[3] << 24)); 00347 } 00348 00349 //////////////////////////////////////////////////////////////////// 00350 // Function: DCPackerInterface::do_unpack_uint64 00351 // Access: Public, Static 00352 // Description: 00353 //////////////////////////////////////////////////////////////////// 00354 INLINE PN_uint64 DCPackerInterface:: 00355 do_unpack_uint64(const char *buffer) { 00356 return ((PN_uint64)(unsigned char)buffer[0] | 00357 ((PN_uint64)(unsigned char)buffer[1] << 8) | 00358 ((PN_uint64)(unsigned char)buffer[2] << 16) | 00359 ((PN_uint64)(unsigned char)buffer[3] << 24) | 00360 ((PN_uint64)(unsigned char)buffer[4] << 32) | 00361 ((PN_uint64)(unsigned char)buffer[5] << 40) | 00362 ((PN_uint64)(unsigned char)buffer[6] << 48) | 00363 ((PN_int64)(signed char)buffer[7] << 54)); 00364 } 00365 00366 00367 //////////////////////////////////////////////////////////////////// 00368 // Function: DCPackerInterface::do_unpack_float64 00369 // Access: Public, Static 00370 // Description: 00371 //////////////////////////////////////////////////////////////////// 00372 INLINE double DCPackerInterface:: 00373 do_unpack_float64(const char *buffer) { 00374 #ifdef WORDS_BIGENDIAN 00375 char reverse[8]; 00376 00377 // Reverse the byte ordering for big-endian machines. 00378 for (size_t i = 0; i < 8; i++) { 00379 reverse[i] = buffer[7 - i]; 00380 } 00381 return *(double *)reverse; 00382 #else 00383 return *(double *)buffer; 00384 #endif // WORDS_BIGENDIAN 00385 } 00386 00387 //////////////////////////////////////////////////////////////////// 00388 // Function: DCPackerInterface::validate_int_limits 00389 // Access: Public, Static 00390 // Description: Confirms that the signed value fits within num_bits 00391 // bits. Sets range_error true if it does not. 00392 //////////////////////////////////////////////////////////////////// 00393 INLINE void DCPackerInterface:: 00394 validate_int_limits(int value, int num_bits, bool &range_error) { 00395 // What we're really checking is that all of the bits above the 00396 // lower (num_bits - 1) bits are the same--either all 1 or all 0. 00397 00398 // First, turn on the lower (num_bits - 1). 00399 int mask = ((int)1 << (num_bits - 1)) - 1; 00400 value |= mask; 00401 00402 // The result should be either mask (all high bits are 0) or -1 (all 00403 // high bits are 1). If it is anything else we have a range error. 00404 if (value != mask && value != -1) { 00405 range_error = true; 00406 } 00407 } 00408 00409 //////////////////////////////////////////////////////////////////// 00410 // Function: DCPackerInterface::validate_int64_limits 00411 // Access: Public, Static 00412 // Description: Confirms that the signed value fits within num_bits 00413 // bits. Sets range_error true if it does not. 00414 //////////////////////////////////////////////////////////////////// 00415 INLINE void DCPackerInterface:: 00416 validate_int64_limits(PN_int64 value, int num_bits, bool &range_error) { 00417 PN_int64 mask = ((PN_int64)1 << (num_bits - 1)) - 1; 00418 value |= mask; 00419 00420 if (value != mask && value != -1) { 00421 range_error = true; 00422 } 00423 } 00424 00425 //////////////////////////////////////////////////////////////////// 00426 // Function: DCPackerInterface::validate_uint_limits 00427 // Access: Public, Static 00428 // Description: Confirms that the unsigned value fits within num_bits 00429 // bits. Sets range_error true if it does not. 00430 //////////////////////////////////////////////////////////////////// 00431 INLINE void DCPackerInterface:: 00432 validate_uint_limits(unsigned int value, int num_bits, bool &range_error) { 00433 // Here we're really checking that all of the bits above the lower 00434 // num_bits bits are all 0. 00435 00436 unsigned int mask = ((unsigned int)1 << num_bits) - 1; 00437 value &= ~mask; 00438 00439 if (value != 0) { 00440 range_error = true; 00441 } 00442 } 00443 00444 //////////////////////////////////////////////////////////////////// 00445 // Function: DCPackerInterface::validate_uint64_limits 00446 // Access: Public, Static 00447 // Description: Confirms that the unsigned value fits within num_bits 00448 // bits. Sets range_error true if it does not. 00449 //////////////////////////////////////////////////////////////////// 00450 INLINE void DCPackerInterface:: 00451 validate_uint64_limits(PN_uint64 value, int num_bits, bool &range_error) { 00452 PN_uint64 mask = ((PN_uint64)1 << num_bits) - 1; 00453 value &= ~mask; 00454 00455 if (value != 0) { 00456 range_error = true; 00457 } 00458 }