Panda3D

dcPackerInterface.I

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 }
 All Classes Functions Variables Enumerations