Panda3D

dcPacker.I

00001 // Filename: dcPacker.I
00002 // Created by:  drose (15Jun04)
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: DCPacker::clear_data
00018 //       Access: Published
00019 //  Description: Empties the data in the pack buffer and unpack
00020 //               buffer.  This should be called between calls to
00021 //               begin_pack(), unless you want to concatenate all of
00022 //               the pack results together.
00023 ////////////////////////////////////////////////////////////////////
00024 INLINE void DCPacker::
00025 clear_data() {
00026   _pack_data.clear();
00027 
00028   if (_owns_unpack_data) {
00029     delete[] _unpack_data;
00030     _owns_unpack_data = false;
00031   }
00032   _unpack_data = NULL;
00033 }
00034 
00035 ////////////////////////////////////////////////////////////////////
00036 //     Function: DCPacker::has_nested_fields
00037 //       Access: Published
00038 //  Description: Returns true if the current field has any nested
00039 //               fields (and thus expects a push() .. pop()
00040 //               interface), or false otherwise.  If this returns
00041 //               true, get_num_nested_fields() may be called to
00042 //               determine how many nested fields are expected.
00043 ////////////////////////////////////////////////////////////////////
00044 INLINE bool DCPacker::
00045 has_nested_fields() const {
00046   if (_current_field == NULL) {
00047     return false;
00048   } else {
00049     return _current_field->has_nested_fields();
00050   }
00051 }
00052 
00053 ////////////////////////////////////////////////////////////////////
00054 //     Function: DCPacker::get_num_nested_fields
00055 //       Access: Published
00056 //  Description: Returns the number of nested fields associated with
00057 //               the current field, if has_nested_fields() returned
00058 //               true.
00059 //
00060 //               The return value may be -1 to indicate that a
00061 //               variable number of nested fields are accepted by this
00062 //               field type (e.g. a variable-length array).
00063 //
00064 //               Note that this method is unreliable to determine how
00065 //               many fields you must traverse before you can call
00066 //               pop(), since particularly in the presence of a
00067 //               DCSwitch, it may change during traversal.  Use
00068 //               more_nested_fields() instead.
00069 ////////////////////////////////////////////////////////////////////
00070 INLINE int DCPacker::
00071 get_num_nested_fields() const {
00072   return _num_nested_fields;
00073 }
00074 
00075 ////////////////////////////////////////////////////////////////////
00076 //     Function: DCPacker::more_nested_fields
00077 //       Access: Published
00078 //  Description: Returns true if there are more nested fields to pack
00079 //               or unpack in the current push sequence, false if it
00080 //               is time to call pop().
00081 ////////////////////////////////////////////////////////////////////
00082 INLINE bool DCPacker::
00083 more_nested_fields() const {
00084   return (_current_field != (DCPackerInterface *)NULL && !_pack_error);
00085 }
00086 
00087 ////////////////////////////////////////////////////////////////////
00088 //     Function: DCPacker::get_current_parent
00089 //       Access: Published
00090 //  Description: Returns the field that we left in our last call to
00091 //               push(): the owner of the current level of fields.
00092 //               This may be NULL at the beginning of the pack
00093 //               operation.
00094 ////////////////////////////////////////////////////////////////////
00095 INLINE const DCPackerInterface *DCPacker::
00096 get_current_parent() const {
00097   return _current_parent;
00098 }
00099 
00100 ////////////////////////////////////////////////////////////////////
00101 //     Function: DCPacker::get_current_field
00102 //       Access: Published
00103 //  Description: Returns the field that will be referenced by the next
00104 //               call to pack_*() or unpack_*().  This will be NULL if
00105 //               we have unpacked (or packed) all fields, or if it is
00106 //               time to call pop().
00107 ////////////////////////////////////////////////////////////////////
00108 INLINE const DCPackerInterface *DCPacker::
00109 get_current_field() const {
00110   return _current_field;
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////
00114 //     Function: DCPacker::get_last_switch
00115 //       Access: Published
00116 //  Description: Returns a pointer to the last DCSwitch instance that
00117 //               we have passed by and selected one case of during the
00118 //               pack/unpack process.  Each time we encounter a new
00119 //               DCSwitch and select a case, this will change state.
00120 //
00121 //               This may be used to detect when a DCSwitch has been
00122 //               selected.  At the moment this changes state,
00123 //               get_current_parent() will contain the particular
00124 //               SwitchCase that was selected by the switch.
00125 ////////////////////////////////////////////////////////////////////
00126 INLINE const DCSwitchParameter *DCPacker::
00127 get_last_switch() const {
00128   return _last_switch;
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: DCPacker::get_pack_type
00133 //       Access: Published
00134 //  Description: Returns the type of value expected by the current
00135 //               field.  See the enumerated type definition at the top
00136 //               of DCPackerInterface.h.  If this returns one of
00137 //               PT_double, PT_int, PT_int64, or PT_string, then you
00138 //               should call the corresponding pack_double(),
00139 //               pack_int() function (or unpack_double(),
00140 //               unpack_int(), etc.) to transfer data.  Otherwise, you
00141 //               should call push() and begin packing or unpacking the
00142 //               nested fields.
00143 ////////////////////////////////////////////////////////////////////
00144 INLINE DCPackType DCPacker::
00145 get_pack_type() const {
00146   if (_current_field == NULL) {
00147     return PT_invalid;
00148   } else {
00149     return _current_field->get_pack_type();
00150   }
00151 }
00152 
00153 ////////////////////////////////////////////////////////////////////
00154 //     Function: DCPacker::get_current_field_name
00155 //       Access: Published
00156 //  Description: Returns the name of the current field, if it has a
00157 //               name, or the empty string if the field does not have
00158 //               a name or there is no current field.
00159 ////////////////////////////////////////////////////////////////////
00160 INLINE string DCPacker::
00161 get_current_field_name() const {
00162   if (_current_field == NULL) {
00163     return string();
00164   } else {
00165     return _current_field->get_name();
00166   }
00167 }
00168 
00169 ////////////////////////////////////////////////////////////////////
00170 //     Function: DCPacker::pack_double
00171 //       Access: Published
00172 //  Description: Packs the indicated numeric or string value into the
00173 //               stream.
00174 ////////////////////////////////////////////////////////////////////
00175 INLINE void DCPacker::
00176 pack_double(double value) {
00177   nassertv(_mode == M_pack || _mode == M_repack);
00178   if (_current_field == NULL) {
00179     _pack_error = true;
00180   } else {
00181     _current_field->pack_double(_pack_data, value, _pack_error, _range_error);
00182     advance();
00183   }
00184 }
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: DCPacker::pack_int
00188 //       Access: Published
00189 //  Description: Packs the indicated numeric or string value into the
00190 //               stream.
00191 ////////////////////////////////////////////////////////////////////
00192 INLINE void DCPacker::
00193 pack_int(int value) {
00194   nassertv(_mode == M_pack || _mode == M_repack);
00195   if (_current_field == NULL) {
00196     _pack_error = true;
00197   } else {
00198     _current_field->pack_int(_pack_data, value, _pack_error, _range_error);
00199     advance();
00200   }
00201 }
00202 
00203 ////////////////////////////////////////////////////////////////////
00204 //     Function: DCPacker::pack_uint
00205 //       Access: Published
00206 //  Description: Packs the indicated numeric or string value into the
00207 //               stream.
00208 ////////////////////////////////////////////////////////////////////
00209 INLINE void DCPacker::
00210 pack_uint(unsigned int value) {
00211   nassertv(_mode == M_pack || _mode == M_repack);
00212   if (_current_field == NULL) {
00213     _pack_error = true;
00214   } else {
00215     _current_field->pack_uint(_pack_data, value, _pack_error, _range_error);
00216     advance();
00217   }
00218 }
00219 
00220 ////////////////////////////////////////////////////////////////////
00221 //     Function: DCPacker::pack_int64
00222 //       Access: Published
00223 //  Description: Packs the indicated numeric or string value into the
00224 //               stream.
00225 ////////////////////////////////////////////////////////////////////
00226 INLINE void DCPacker::
00227 pack_int64(PN_int64 value) {
00228   nassertv(_mode == M_pack || _mode == M_repack);
00229   if (_current_field == NULL) {
00230     _pack_error = true;
00231   } else {
00232     _current_field->pack_int64(_pack_data, value, _pack_error, _range_error);
00233     advance();
00234   }
00235 }
00236 
00237 ////////////////////////////////////////////////////////////////////
00238 //     Function: DCPacker::pack_uint64
00239 //       Access: Published
00240 //  Description: Packs the indicated numeric or string value into the
00241 //               stream.
00242 ////////////////////////////////////////////////////////////////////
00243 INLINE void DCPacker::
00244 pack_uint64(PN_uint64 value) {
00245   nassertv(_mode == M_pack || _mode == M_repack);
00246   if (_current_field == NULL) {
00247     _pack_error = true;
00248   } else {
00249     _current_field->pack_uint64(_pack_data, value, _pack_error, _range_error);
00250     advance();
00251   }
00252 }
00253 
00254 ////////////////////////////////////////////////////////////////////
00255 //     Function: DCPacker::pack_string
00256 //       Access: Published
00257 //  Description: Packs the indicated numeric or string value into the
00258 //               stream.
00259 ////////////////////////////////////////////////////////////////////
00260 INLINE void DCPacker::
00261 pack_string(const string &value) {
00262   nassertv(_mode == M_pack || _mode == M_repack);
00263   if (_current_field == NULL) {
00264     _pack_error = true;
00265   } else {
00266     _current_field->pack_string(_pack_data, value, _pack_error, _range_error);
00267     advance();
00268   }
00269 }
00270 
00271 ////////////////////////////////////////////////////////////////////
00272 //     Function: DCPacker::pack_literal_value
00273 //       Access: Published
00274 //  Description: Adds the indicated string value into the stream,
00275 //               representing a single pre-packed field element, or a
00276 //               whole group of field elements at once.
00277 ////////////////////////////////////////////////////////////////////
00278 INLINE void DCPacker::
00279 pack_literal_value(const string &value) {
00280   nassertv(_mode == M_pack || _mode == M_repack);
00281   if (_current_field == NULL) {
00282     _pack_error = true;
00283   } else {
00284     _pack_data.append_data(value.data(), value.length());
00285     advance();
00286   }
00287 }
00288 
00289 ////////////////////////////////////////////////////////////////////
00290 //     Function: DCPacker::unpack_double
00291 //       Access: Published
00292 //  Description: Unpacks the current numeric or string value from the
00293 //               stream.
00294 ////////////////////////////////////////////////////////////////////
00295 INLINE double DCPacker::
00296 unpack_double() {
00297   double value = 0.0;
00298   nassertr(_mode == M_unpack, value);
00299   if (_current_field == NULL) {
00300     _pack_error = true;
00301 
00302   } else {
00303     _current_field->unpack_double(_unpack_data, _unpack_length, _unpack_p, 
00304                                   value, _pack_error, _range_error);
00305     advance();
00306   }
00307 
00308   return value;
00309 }
00310 
00311 ////////////////////////////////////////////////////////////////////
00312 //     Function: DCPacker::unpack_int
00313 //       Access: Published
00314 //  Description: Unpacks the current numeric or string value from the
00315 //               stream.
00316 ////////////////////////////////////////////////////////////////////
00317 INLINE int DCPacker::
00318 unpack_int() {
00319   int value = 0;
00320   nassertr(_mode == M_unpack, value);
00321   if (_current_field == NULL) {
00322     _pack_error = true;
00323 
00324   } else {
00325     _current_field->unpack_int(_unpack_data, _unpack_length, _unpack_p,
00326                                value, _pack_error, _range_error);
00327     advance();
00328   }
00329 
00330   return value;
00331 }
00332 
00333 ////////////////////////////////////////////////////////////////////
00334 //     Function: DCPacker::unpack_uint
00335 //       Access: Published
00336 //  Description: Unpacks the current numeric or string value from the
00337 //               stream.
00338 ////////////////////////////////////////////////////////////////////
00339 INLINE unsigned int DCPacker::
00340 unpack_uint() {
00341   unsigned int value = 0;
00342   nassertr(_mode == M_unpack, value);
00343   if (_current_field == NULL) {
00344     _pack_error = true;
00345 
00346   } else {
00347     _current_field->unpack_uint(_unpack_data, _unpack_length, _unpack_p,
00348                                 value, _pack_error, _range_error);
00349     advance();
00350   }
00351 
00352   return value;
00353 }
00354 
00355 ////////////////////////////////////////////////////////////////////
00356 //     Function: DCPacker::unpack_int64
00357 //       Access: Published
00358 //  Description: Unpacks the current numeric or string value from the
00359 //               stream.
00360 ////////////////////////////////////////////////////////////////////
00361 INLINE PN_int64 DCPacker::
00362 unpack_int64() {
00363   PN_int64 value = 0;
00364   nassertr(_mode == M_unpack, value);
00365   if (_current_field == NULL) {
00366     _pack_error = true;
00367 
00368   } else {
00369     _current_field->unpack_int64(_unpack_data, _unpack_length, _unpack_p,
00370                                  value, _pack_error, _range_error);
00371     advance();
00372   }
00373 
00374   return value;
00375 }
00376 
00377 ////////////////////////////////////////////////////////////////////
00378 //     Function: DCPacker::unpack_uint64
00379 //       Access: Published
00380 //  Description: Unpacks the current numeric or string value from the
00381 //               stream.
00382 ////////////////////////////////////////////////////////////////////
00383 INLINE PN_uint64 DCPacker::
00384 unpack_uint64() {
00385   PN_uint64 value = 0;
00386   nassertr(_mode == M_unpack, value);
00387   if (_current_field == NULL) {
00388     _pack_error = true;
00389 
00390   } else {
00391     _current_field->unpack_uint64(_unpack_data, _unpack_length, _unpack_p,
00392                                   value, _pack_error, _range_error);
00393     advance();
00394   }
00395 
00396   return value;
00397 }
00398 
00399 ////////////////////////////////////////////////////////////////////
00400 //     Function: DCPacker::unpack_string
00401 //       Access: Published
00402 //  Description: Unpacks the current numeric or string value from the
00403 //               stream.
00404 ////////////////////////////////////////////////////////////////////
00405 INLINE string DCPacker::
00406 unpack_string() {
00407   string value;
00408   nassertr(_mode == M_unpack, value);
00409   if (_current_field == NULL) {
00410     _pack_error = true;
00411 
00412   } else {
00413     _current_field->unpack_string(_unpack_data, _unpack_length, _unpack_p,
00414                                   value, _pack_error, _range_error);
00415     advance();
00416   }
00417 
00418   return value;
00419 }
00420 
00421 ////////////////////////////////////////////////////////////////////
00422 //     Function: DCPacker::unpack_literal_value
00423 //       Access: Published
00424 //  Description: Returns the literal string that represents the packed
00425 //               value of the current field, and advances the field
00426 //               pointer.
00427 ////////////////////////////////////////////////////////////////////
00428 INLINE string DCPacker::
00429 unpack_literal_value() {
00430   size_t start = _unpack_p;
00431   unpack_skip();
00432   nassertr(_unpack_p >= start, string());
00433   return string(_unpack_data + start, _unpack_p - start);
00434 }
00435 
00436 ////////////////////////////////////////////////////////////////////
00437 //     Function: DCPacker::unpack_double
00438 //       Access: Public
00439 //  Description: Unpacks the current numeric or string value from the
00440 //               stream.
00441 ////////////////////////////////////////////////////////////////////
00442 INLINE void DCPacker::
00443 unpack_double(double &value) {
00444   nassertv(_mode == M_unpack);
00445   if (_current_field == NULL) {
00446     _pack_error = true;
00447 
00448   } else {
00449     _current_field->unpack_double(_unpack_data, _unpack_length, _unpack_p, 
00450                                   value, _pack_error, _range_error);
00451     advance();
00452   }
00453 }
00454 
00455 ////////////////////////////////////////////////////////////////////
00456 //     Function: DCPacker::unpack_int
00457 //       Access: Public
00458 //  Description: Unpacks the current numeric or string value from the
00459 //               stream.
00460 ////////////////////////////////////////////////////////////////////
00461 INLINE void DCPacker::
00462 unpack_int(int &value) {
00463   nassertv(_mode == M_unpack);
00464   if (_current_field == NULL) {
00465     _pack_error = true;
00466 
00467   } else {
00468     _current_field->unpack_int(_unpack_data, _unpack_length, _unpack_p,
00469                                value, _pack_error, _range_error);
00470     advance();
00471   }
00472 }
00473 
00474 ////////////////////////////////////////////////////////////////////
00475 //     Function: DCPacker::unpack_uint
00476 //       Access: Public
00477 //  Description: Unpacks the current numeric or string value from the
00478 //               stream.
00479 ////////////////////////////////////////////////////////////////////
00480 INLINE void DCPacker::
00481 unpack_uint(unsigned int &value) {
00482   nassertv(_mode == M_unpack);
00483   if (_current_field == NULL) {
00484     _pack_error = true;
00485 
00486   } else {
00487     _current_field->unpack_uint(_unpack_data, _unpack_length, _unpack_p,
00488                                 value, _pack_error, _range_error);
00489     advance();
00490   }
00491 }
00492 
00493 ////////////////////////////////////////////////////////////////////
00494 //     Function: DCPacker::unpack_int64
00495 //       Access: Public
00496 //  Description: Unpacks the current numeric or string value from the
00497 //               stream.
00498 ////////////////////////////////////////////////////////////////////
00499 INLINE void DCPacker::
00500 unpack_int64(PN_int64 &value) {
00501   nassertv(_mode == M_unpack);
00502   if (_current_field == NULL) {
00503     _pack_error = true;
00504 
00505   } else {
00506     _current_field->unpack_int64(_unpack_data, _unpack_length, _unpack_p,
00507                                  value, _pack_error, _range_error);
00508     advance();
00509   }
00510 }
00511 
00512 ////////////////////////////////////////////////////////////////////
00513 //     Function: DCPacker::unpack_uint64
00514 //       Access: Public
00515 //  Description: Unpacks the current numeric or string value from the
00516 //               stream.
00517 ////////////////////////////////////////////////////////////////////
00518 INLINE void DCPacker::
00519 unpack_uint64(PN_uint64 &value) {
00520   nassertv(_mode == M_unpack);
00521   if (_current_field == NULL) {
00522     _pack_error = true;
00523 
00524   } else {
00525     _current_field->unpack_uint64(_unpack_data, _unpack_length, _unpack_p,
00526                                   value, _pack_error, _range_error);
00527     advance();
00528   }
00529 }
00530 
00531 ////////////////////////////////////////////////////////////////////
00532 //     Function: DCPacker::unpack_string
00533 //       Access: Public
00534 //  Description: Unpacks the current numeric or string value from the
00535 //               stream.
00536 ////////////////////////////////////////////////////////////////////
00537 INLINE void DCPacker::
00538 unpack_string(string &value) {
00539   nassertv(_mode == M_unpack);
00540   if (_current_field == NULL) {
00541     _pack_error = true;
00542 
00543   } else {
00544     _current_field->unpack_string(_unpack_data, _unpack_length, _unpack_p,
00545                                   value, _pack_error, _range_error);
00546     advance();
00547   }
00548 }
00549 
00550 ////////////////////////////////////////////////////////////////////
00551 //     Function: DCPacker::unpack_literal_value
00552 //       Access: Public
00553 //  Description: Returns the literal string that represents the packed
00554 //               value of the current field, and advances the field
00555 //               pointer.
00556 ////////////////////////////////////////////////////////////////////
00557 INLINE void DCPacker::
00558 unpack_literal_value(string &value) {
00559   size_t start = _unpack_p;
00560   unpack_skip();
00561   nassertv(_unpack_p >= start);
00562   value.assign(_unpack_data + start, _unpack_p - start);
00563 }
00564 
00565 ////////////////////////////////////////////////////////////////////
00566 //     Function: DCPacker::had_parse_error
00567 //       Access: Published
00568 //  Description: Returns true if there has been an parse error
00569 //               since the most recent call to begin(); this can only
00570 //               happen if you call parse_and_pack().
00571 ////////////////////////////////////////////////////////////////////
00572 INLINE bool DCPacker::
00573 had_parse_error() const {
00574   return _parse_error;
00575 }
00576 
00577 ////////////////////////////////////////////////////////////////////
00578 //     Function: DCPacker::had_pack_error
00579 //       Access: Published
00580 //  Description: Returns true if there has been an packing error
00581 //               since the most recent call to begin(); in particular,
00582 //               this may be called after end() has returned false to
00583 //               determine the nature of the failure.
00584 //
00585 //               A return value of true indicates there was a push/pop
00586 //               mismatch, or the push/pop structure did not match the
00587 //               data structure, or there were the wrong number of
00588 //               elements in a nested push/pop structure, or on unpack
00589 //               that the data stream was truncated.
00590 ////////////////////////////////////////////////////////////////////
00591 INLINE bool DCPacker::
00592 had_pack_error() const {
00593   return _pack_error;
00594 }
00595 
00596 ////////////////////////////////////////////////////////////////////
00597 //     Function: DCPacker::had_range_error
00598 //       Access: Published
00599 //  Description: Returns true if there has been an range validation
00600 //               error since the most recent call to begin(); in
00601 //               particular, this may be called after end() has
00602 //               returned false to determine the nature of the
00603 //               failure.
00604 //
00605 //               A return value of true indicates a value that was
00606 //               packed or unpacked did not fit within the specified
00607 //               legal range for a parameter, or within the limits of
00608 //               the field size.
00609 ////////////////////////////////////////////////////////////////////
00610 INLINE bool DCPacker::
00611 had_range_error() const {
00612   return _range_error;
00613 }
00614 
00615 ////////////////////////////////////////////////////////////////////
00616 //     Function: DCPacker::had_error
00617 //       Access: Published
00618 //  Description: Returns true if there has been any error (either a
00619 //               pack error or a range error) since the most recent
00620 //               call to begin().  If this returns true, then the
00621 //               matching call to end() will indicate an error
00622 //               (false).
00623 ////////////////////////////////////////////////////////////////////
00624 INLINE bool DCPacker::
00625 had_error() const {
00626   return _range_error || _pack_error || _parse_error;
00627 }
00628 
00629 ////////////////////////////////////////////////////////////////////
00630 //     Function: DCPacker::get_num_unpacked_bytes
00631 //       Access: Published
00632 //  Description: Returns the number of bytes that have been unpacked
00633 //               so far, or after unpack_end(), the total number of
00634 //               bytes that were unpacked at all.  This can be used to
00635 //               validate that all of the bytes in the buffer were
00636 //               actually unpacked (which is not otherwise considered
00637 //               an error).
00638 ////////////////////////////////////////////////////////////////////
00639 INLINE size_t DCPacker::
00640 get_num_unpacked_bytes() const {
00641   return _unpack_p;
00642 }
00643 
00644 ////////////////////////////////////////////////////////////////////
00645 //     Function: DCPacker::get_length
00646 //       Access: Published
00647 //  Description: Returns the current length of the buffer.  This is
00648 //               the number of useful bytes stored in the buffer, not
00649 //               the amount of memory it takes up.
00650 ////////////////////////////////////////////////////////////////////
00651 INLINE size_t DCPacker::
00652 get_length() const {
00653   return _pack_data.get_length();
00654 }
00655 
00656 ////////////////////////////////////////////////////////////////////
00657 //     Function: DCPacker::get_string
00658 //       Access: Published
00659 //  Description: Returns the packed data buffer as a string.  Also see
00660 //               get_data().
00661 ////////////////////////////////////////////////////////////////////
00662 INLINE string DCPacker::
00663 get_string() const {
00664   return _pack_data.get_string();
00665 }
00666 
00667 ////////////////////////////////////////////////////////////////////
00668 //     Function: DCPacker::get_unpack_length
00669 //       Access: Published
00670 //  Description: Returns the total number of bytes in the unpack data
00671 //               buffer.  This is the buffer used when unpacking; it
00672 //               is separate from the pack data returned by
00673 //               get_length(), which is filled during packing.
00674 ////////////////////////////////////////////////////////////////////
00675 INLINE size_t DCPacker::
00676 get_unpack_length() const {
00677   return _unpack_length;
00678 }
00679 
00680 ////////////////////////////////////////////////////////////////////
00681 //     Function: DCPacker::get_unpack_string
00682 //       Access: Published
00683 //  Description: Returns the unpack data buffer, as a string.
00684 //               This is the buffer used when unpacking; it is
00685 //               separate from the pack data returned by get_string(),
00686 //               which is filled during packing.  Also see
00687 //               get_unpack_data().
00688 ////////////////////////////////////////////////////////////////////
00689 INLINE string DCPacker::
00690 get_unpack_string() const {
00691   return string(_unpack_data, _unpack_length);
00692 }
00693 
00694 ////////////////////////////////////////////////////////////////////
00695 //     Function: DCPacker::get_string
00696 //       Access: Published
00697 //  Description: Copies the packed data into the indicated string.
00698 //               Also see get_data().
00699 ////////////////////////////////////////////////////////////////////
00700 INLINE void DCPacker::
00701 get_string(string &data) const {
00702   data.assign(_pack_data.get_data(), _pack_data.get_length());
00703 }
00704 
00705 ////////////////////////////////////////////////////////////////////
00706 //     Function: DCPacker::get_data
00707 //       Access: Public
00708 //  Description: Returns the beginning of the data buffer.  The buffer
00709 //               is not null-terminated, but see also get_string().
00710 //
00711 //               This may be used in conjunction with get_length() to
00712 //               copy all of the bytes out of the buffer.  Also see
00713 //               take_data() to get the packed data without a copy
00714 //               operation.
00715 ////////////////////////////////////////////////////////////////////
00716 INLINE const char *DCPacker::
00717 get_data() const {
00718   return _pack_data.get_data();
00719 }
00720 
00721 ////////////////////////////////////////////////////////////////////
00722 //     Function: DCPacker::take_data
00723 //       Access: Public
00724 //  Description: Returns the pointer to the beginning of the data
00725 //               buffer, and transfers ownership of the buffer to the
00726 //               caller.  The caller is now responsible for ultimately
00727 //               freeing the returned pointer with delete[], if it is
00728 //               non-NULL.  This may (or may not) return NULL if the
00729 //               buffer is empty.
00730 //
00731 //               This also empties the DCPackData structure, and sets
00732 //               its length to zero (so you should call get_length()
00733 //               before calling this method).
00734 ////////////////////////////////////////////////////////////////////
00735 INLINE char *DCPacker::
00736 take_data() {
00737   return _pack_data.take_data();
00738 }
00739 
00740 ////////////////////////////////////////////////////////////////////
00741 //     Function: DCPacker::append_data
00742 //       Access: Public
00743 //  Description: Adds the indicated bytes to the end of the data.
00744 //               This may only be called between packing sessions.
00745 ////////////////////////////////////////////////////////////////////
00746 INLINE void DCPacker::
00747 append_data(const char *buffer, size_t size) {
00748   nassertv(_mode == M_idle);
00749   _pack_data.append_data(buffer, size);
00750 }
00751 
00752 ////////////////////////////////////////////////////////////////////
00753 //     Function: DCPacker::get_write_pointer
00754 //       Access: Public
00755 //  Description: Adds the indicated number of bytes to the end of the
00756 //               data without initializing them, and returns a pointer
00757 //               to the beginning of the new data.  This may only be
00758 //               called between packing sessions.
00759 ////////////////////////////////////////////////////////////////////
00760 INLINE char *DCPacker::
00761 get_write_pointer(size_t size) {
00762   nassertr(_mode == M_idle, NULL);
00763   return _pack_data.get_write_pointer(size);
00764 }
00765 
00766 ////////////////////////////////////////////////////////////////////
00767 //     Function: DCPacker::get_unpack_data
00768 //       Access: Public
00769 //  Description: Returns a read pointer to the unpack data buffer.
00770 //               This is the buffer used when unpacking; it is
00771 //               separate from the pack data returned by get_data(),
00772 //               which is filled during packing.
00773 ////////////////////////////////////////////////////////////////////
00774 INLINE const char *DCPacker::
00775 get_unpack_data() const {
00776   return _unpack_data;
00777 }
00778 
00779 ////////////////////////////////////////////////////////////////////
00780 //     Function: DCPacker::StackElement::get_num_stack_elements_ever_allocated
00781 //       Access: Published, Static
00782 //  Description: Returns the number of DCPacker::StackElement pointers
00783 //               ever simultaneously allocated; these are now either
00784 //               in active use or have been recycled into the deleted
00785 //               DCPacker::StackElement pool to be used again.
00786 ////////////////////////////////////////////////////////////////////
00787 INLINE int DCPacker::
00788 get_num_stack_elements_ever_allocated() {
00789   return StackElement::_num_ever_allocated;
00790 }
00791 
00792 ////////////////////////////////////////////////////////////////////
00793 //     Function: DCPacker::raw_pack_int8
00794 //       Access: Published
00795 //  Description: Packs the data into the buffer between packing
00796 //               sessions.
00797 ////////////////////////////////////////////////////////////////////
00798 INLINE void DCPacker::
00799 raw_pack_int8(int value) {
00800   nassertv(_mode == M_idle);
00801   DCPackerInterface::do_pack_int8(_pack_data.get_write_pointer(1), value);
00802 }
00803 
00804 ////////////////////////////////////////////////////////////////////
00805 //     Function: DCPacker::raw_pack_int16
00806 //       Access: Published
00807 //  Description: Packs the data into the buffer between packing
00808 //               sessions.
00809 ////////////////////////////////////////////////////////////////////
00810 INLINE void DCPacker::
00811 raw_pack_int16(int value) {
00812   nassertv(_mode == M_idle);
00813   DCPackerInterface::do_pack_int16(_pack_data.get_write_pointer(2), value);
00814 }
00815 
00816 ////////////////////////////////////////////////////////////////////
00817 //     Function: DCPacker::raw_pack_int32
00818 //       Access: Published
00819 //  Description: Packs the data into the buffer between packing
00820 //               sessions.
00821 ////////////////////////////////////////////////////////////////////
00822 INLINE void DCPacker::
00823 raw_pack_int32(int value) {
00824   nassertv(_mode == M_idle);
00825   DCPackerInterface::do_pack_int32(_pack_data.get_write_pointer(4), value);
00826 }
00827 
00828 ////////////////////////////////////////////////////////////////////
00829 //     Function: DCPacker::raw_pack_int64
00830 //       Access: Published
00831 //  Description: Packs the data into the buffer between packing
00832 //               sessions.
00833 ////////////////////////////////////////////////////////////////////
00834 INLINE void DCPacker::
00835 raw_pack_int64(PN_int64 value) {
00836   nassertv(_mode == M_idle);
00837   DCPackerInterface::do_pack_int64(_pack_data.get_write_pointer(8), value);
00838 }
00839 
00840 ////////////////////////////////////////////////////////////////////
00841 //     Function: DCPacker::raw_pack_uint8
00842 //       Access: Published
00843 //  Description: Packs the data into the buffer between packing
00844 //               sessions.
00845 ////////////////////////////////////////////////////////////////////
00846 INLINE void DCPacker::
00847 raw_pack_uint8(unsigned int value) {
00848   nassertv(_mode == M_idle);
00849   DCPackerInterface::do_pack_uint8(_pack_data.get_write_pointer(1), value);
00850 }
00851 
00852 ////////////////////////////////////////////////////////////////////
00853 //     Function: DCPacker::raw_pack_uint16
00854 //       Access: Published
00855 //  Description: Packs the data into the buffer between packing
00856 //               sessions.
00857 ////////////////////////////////////////////////////////////////////
00858 INLINE void DCPacker::
00859 raw_pack_uint16(unsigned int value) {
00860   nassertv(_mode == M_idle);
00861   DCPackerInterface::do_pack_uint16(_pack_data.get_write_pointer(2), value);
00862 }
00863 
00864 ////////////////////////////////////////////////////////////////////
00865 //     Function: DCPacker::raw_pack_uint32
00866 //       Access: Published
00867 //  Description: Packs the data into the buffer between packing
00868 //               sessions.
00869 ////////////////////////////////////////////////////////////////////
00870 INLINE void DCPacker::
00871 raw_pack_uint32(unsigned int value) {
00872   nassertv(_mode == M_idle);
00873   DCPackerInterface::do_pack_uint32(_pack_data.get_write_pointer(4), value);
00874 }
00875 
00876 ////////////////////////////////////////////////////////////////////
00877 //     Function: DCPacker::raw_pack_uint64
00878 //       Access: Published
00879 //  Description: Packs the data into the buffer between packing
00880 //               sessions.
00881 ////////////////////////////////////////////////////////////////////
00882 INLINE void DCPacker::
00883 raw_pack_uint64(PN_uint64 value) {
00884   nassertv(_mode == M_idle);
00885   DCPackerInterface::do_pack_uint64(_pack_data.get_write_pointer(8), value);
00886 }
00887 
00888 ////////////////////////////////////////////////////////////////////
00889 //     Function: DCPacker::raw_pack_float64
00890 //       Access: Published
00891 //  Description: Packs the data into the buffer between packing
00892 //               sessions.
00893 ////////////////////////////////////////////////////////////////////
00894 INLINE void DCPacker::
00895 raw_pack_float64(double value) {
00896   nassertv(_mode == M_idle);
00897   DCPackerInterface::do_pack_float64(_pack_data.get_write_pointer(8), value);
00898 }
00899 
00900 ////////////////////////////////////////////////////////////////////
00901 //     Function: DCPacker::raw_pack_string
00902 //       Access: Published
00903 //  Description: Packs the data into the buffer between packing
00904 //               sessions.
00905 ////////////////////////////////////////////////////////////////////
00906 INLINE void DCPacker::
00907 raw_pack_string(const string &value) {
00908   nassertv(_mode == M_idle);
00909   DCPackerInterface::do_pack_uint16(_pack_data.get_write_pointer(2), value.length());
00910   _pack_data.append_data(value.data(), value.length());
00911 }
00912 
00913 ////////////////////////////////////////////////////////////////////
00914 //     Function: DCPacker::raw_unpack_int8
00915 //       Access: Published
00916 //  Description: Unpacks the data from the buffer between unpacking
00917 //               sessions.
00918 ////////////////////////////////////////////////////////////////////
00919 INLINE int DCPacker::
00920 raw_unpack_int8() {
00921   int value = 0;
00922   raw_unpack_int8(value);
00923   return value;
00924 }
00925 
00926 ////////////////////////////////////////////////////////////////////
00927 //     Function: DCPacker::raw_unpack_int16
00928 //       Access: Published
00929 //  Description: Unpacks the data from the buffer between unpacking
00930 //               sessions.
00931 ////////////////////////////////////////////////////////////////////
00932 INLINE int DCPacker::
00933 raw_unpack_int16() {
00934   int value = 0;
00935   raw_unpack_int16(value);
00936   return value;
00937 }
00938 
00939 ////////////////////////////////////////////////////////////////////
00940 //     Function: DCPacker::raw_unpack_int32
00941 //       Access: Published
00942 //  Description: Unpacks the data from the buffer between unpacking
00943 //               sessions.
00944 ////////////////////////////////////////////////////////////////////
00945 INLINE int DCPacker::
00946 raw_unpack_int32() {
00947   int value = 0;
00948   raw_unpack_int32(value);
00949   return value;
00950 }
00951 
00952 ////////////////////////////////////////////////////////////////////
00953 //     Function: DCPacker::raw_unpack_int64
00954 //       Access: Published
00955 //  Description: Unpacks the data from the buffer between unpacking
00956 //               sessions.
00957 ////////////////////////////////////////////////////////////////////
00958 INLINE PN_int64 DCPacker::
00959 raw_unpack_int64() {
00960   PN_int64 value = 0;
00961   raw_unpack_int64(value);
00962   return value;
00963 }
00964 
00965 ////////////////////////////////////////////////////////////////////
00966 //     Function: DCPacker::raw_unpack_int8
00967 //       Access: Public
00968 //  Description: Unpacks the data from the buffer between unpacking
00969 //               sessions.
00970 ////////////////////////////////////////////////////////////////////
00971 INLINE void DCPacker::
00972 raw_unpack_int8(int &value) {
00973   nassertv(_mode == M_idle && _unpack_data != NULL);
00974   if (_unpack_p + 1 > _unpack_length) {
00975     _pack_error = true;
00976     return;
00977   }
00978   value = DCPackerInterface::do_unpack_int8(_unpack_data + _unpack_p);
00979   _unpack_p++;
00980 }
00981 
00982 ////////////////////////////////////////////////////////////////////
00983 //     Function: DCPacker::raw_unpack_int16
00984 //       Access: Public
00985 //  Description: Unpacks the data from the buffer between unpacking
00986 //               sessions.
00987 ////////////////////////////////////////////////////////////////////
00988 INLINE void DCPacker::
00989 raw_unpack_int16(int &value) {
00990   nassertv(_mode == M_idle && _unpack_data != NULL);
00991   if (_unpack_p + 2 > _unpack_length) {
00992     _pack_error = true;
00993     return;
00994   }
00995   value = DCPackerInterface::do_unpack_int16(_unpack_data + _unpack_p);
00996   _unpack_p += 2;
00997 }
00998 
00999 ////////////////////////////////////////////////////////////////////
01000 //     Function: DCPacker::raw_unpack_int32
01001 //       Access: Public
01002 //  Description: Unpacks the data from the buffer between unpacking
01003 //               sessions.
01004 ////////////////////////////////////////////////////////////////////
01005 INLINE void DCPacker::
01006 raw_unpack_int32(int &value) {
01007   nassertv(_mode == M_idle && _unpack_data != NULL);
01008   if (_unpack_p + 4 > _unpack_length) {
01009     _pack_error = true;
01010     return;
01011   }
01012   value = DCPackerInterface::do_unpack_int32(_unpack_data + _unpack_p);
01013   _unpack_p += 4;
01014 }
01015 
01016 ////////////////////////////////////////////////////////////////////
01017 //     Function: DCPacker::raw_unpack_uint8
01018 //       Access: Published
01019 //  Description: Unpacks the data from the buffer between unpacking
01020 //               sessions.
01021 ////////////////////////////////////////////////////////////////////
01022 INLINE unsigned int DCPacker::
01023 raw_unpack_uint8() {
01024   unsigned int value = 0;
01025   raw_unpack_uint8(value);
01026   return value;
01027 }
01028 
01029 ////////////////////////////////////////////////////////////////////
01030 //     Function: DCPacker::raw_unpack_uint16
01031 //       Access: Published
01032 //  Description: Unpacks the data from the buffer between unpacking
01033 //               sessions.
01034 ////////////////////////////////////////////////////////////////////
01035 INLINE unsigned int DCPacker::
01036 raw_unpack_uint16() {
01037   unsigned int value = 0;
01038   raw_unpack_uint16(value);
01039   return value;
01040 }
01041 
01042 ////////////////////////////////////////////////////////////////////
01043 //     Function: DCPacker::raw_unpack_uint32
01044 //       Access: Published
01045 //  Description: Unpacks the data from the buffer between unpacking
01046 //               sessions.
01047 ////////////////////////////////////////////////////////////////////
01048 INLINE unsigned int DCPacker::
01049 raw_unpack_uint32() {
01050   unsigned int value = 0;
01051   raw_unpack_uint32(value);
01052   return value;
01053 }
01054 
01055 ////////////////////////////////////////////////////////////////////
01056 //     Function: DCPacker::raw_unpack_uint64
01057 //       Access: Published
01058 //  Description: Unpacks the data from the buffer between unpacking
01059 //               sessions.
01060 ////////////////////////////////////////////////////////////////////
01061 INLINE PN_uint64 DCPacker::
01062 raw_unpack_uint64() {
01063   PN_uint64 value = 0;
01064   raw_unpack_uint64(value);
01065   return value;
01066 }
01067 
01068 ////////////////////////////////////////////////////////////////////
01069 //     Function: DCPacker::raw_unpack_float64
01070 //       Access: Published
01071 //  Description: Unpacks the data from the buffer between unpacking
01072 //               sessions.
01073 ////////////////////////////////////////////////////////////////////
01074 INLINE double DCPacker::
01075 raw_unpack_float64() {
01076   double value = 0;
01077   raw_unpack_float64(value);
01078   return value;
01079 }
01080 
01081 ////////////////////////////////////////////////////////////////////
01082 //     Function: DCPacker::raw_unpack_string
01083 //       Access: Published
01084 //  Description: Unpacks the data from the buffer between unpacking
01085 //               sessions.
01086 ////////////////////////////////////////////////////////////////////
01087 INLINE string DCPacker::
01088 raw_unpack_string() {
01089   string value;
01090   raw_unpack_string(value);
01091   return value;
01092 }
01093 
01094 ////////////////////////////////////////////////////////////////////
01095 //     Function: DCPacker::raw_unpack_int64
01096 //       Access: Public
01097 //  Description: Unpacks the data from the buffer between unpacking
01098 //               sessions.
01099 ////////////////////////////////////////////////////////////////////
01100 INLINE void DCPacker::
01101 raw_unpack_int64(PN_int64 &value) {
01102   nassertv(_mode == M_idle && _unpack_data != NULL);
01103   if (_unpack_p + 8 > _unpack_length) {
01104     _pack_error = true;
01105     return;
01106   }
01107   value = DCPackerInterface::do_unpack_int64(_unpack_data + _unpack_p);
01108   _unpack_p += 8;
01109 }
01110 
01111 ////////////////////////////////////////////////////////////////////
01112 //     Function: DCPacker::raw_unpack_uint8
01113 //       Access: Public
01114 //  Description: Unpacks the data from the buffer between unpacking
01115 //               sessions.
01116 ////////////////////////////////////////////////////////////////////
01117 INLINE void DCPacker::
01118 raw_unpack_uint8(unsigned int &value) {
01119   nassertv(_mode == M_idle && _unpack_data != NULL);
01120   if (_unpack_p + 1 > _unpack_length) {
01121     _pack_error = true;
01122     return;
01123   }
01124   value = DCPackerInterface::do_unpack_uint8(_unpack_data + _unpack_p);
01125   _unpack_p++;
01126 }
01127 
01128 ////////////////////////////////////////////////////////////////////
01129 //     Function: DCPacker::raw_unpack_uint16
01130 //       Access: Public
01131 //  Description: Unpacks the data from the buffer between unpacking
01132 //               sessions.
01133 ////////////////////////////////////////////////////////////////////
01134 INLINE void DCPacker::
01135 raw_unpack_uint16(unsigned int &value) {
01136   nassertv(_mode == M_idle && _unpack_data != NULL);
01137   if (_unpack_p + 2 > _unpack_length) {
01138     _pack_error = true;
01139     return;
01140   }
01141   value = DCPackerInterface::do_unpack_uint16(_unpack_data + _unpack_p);
01142   _unpack_p += 2;
01143 }
01144 
01145 ////////////////////////////////////////////////////////////////////
01146 //     Function: DCPacker::raw_unpack_uint32
01147 //       Access: Public
01148 //  Description: Unpacks the data from the buffer between unpacking
01149 //               sessions.
01150 ////////////////////////////////////////////////////////////////////
01151 INLINE void DCPacker::
01152 raw_unpack_uint32(unsigned int &value) {
01153   nassertv(_mode == M_idle && _unpack_data != NULL);
01154   if (_unpack_p + 4 > _unpack_length) {
01155     _pack_error = true;
01156     return;
01157   }
01158   value = DCPackerInterface::do_unpack_uint32(_unpack_data + _unpack_p);
01159   _unpack_p += 4;
01160 }
01161 
01162 ////////////////////////////////////////////////////////////////////
01163 //     Function: DCPacker::raw_unpack_uint64
01164 //       Access: Public
01165 //  Description: Unpacks the data from the buffer between unpacking
01166 //               sessions.
01167 ////////////////////////////////////////////////////////////////////
01168 INLINE void DCPacker::
01169 raw_unpack_uint64(PN_uint64 &value) {
01170   nassertv(_mode == M_idle && _unpack_data != NULL);
01171   if (_unpack_p + 8 > _unpack_length) {
01172     _pack_error = true;
01173     return;
01174   }
01175   value = DCPackerInterface::do_unpack_uint64(_unpack_data + _unpack_p);
01176   _unpack_p += 8;
01177 }
01178 
01179 ////////////////////////////////////////////////////////////////////
01180 //     Function: DCPacker::raw_unpack_float64
01181 //       Access: Public
01182 //  Description: Unpacks the data from the buffer between unpacking
01183 //               sessions.
01184 ////////////////////////////////////////////////////////////////////
01185 INLINE void DCPacker::
01186 raw_unpack_float64(double &value) {
01187   nassertv(_mode == M_idle && _unpack_data != NULL);
01188   if (_unpack_p + 8 > _unpack_length) {
01189     _pack_error = true;
01190     return;
01191   }
01192   value = DCPackerInterface::do_unpack_float64(_unpack_data + _unpack_p);
01193   _unpack_p += 8;
01194 }
01195 
01196 ////////////////////////////////////////////////////////////////////
01197 //     Function: DCPacker::raw_unpack_string
01198 //       Access: Public
01199 //  Description: Unpacks the data from the buffer between unpacking
01200 //               sessions.
01201 ////////////////////////////////////////////////////////////////////
01202 INLINE void DCPacker::
01203 raw_unpack_string(string &value) {
01204   nassertv(_mode == M_idle && _unpack_data != NULL);
01205   unsigned int string_length = raw_unpack_uint16();
01206 
01207   if (_unpack_p + string_length > _unpack_length) {
01208     _pack_error = true;
01209     return;
01210   }
01211 
01212   value.assign(_unpack_data + _unpack_p, string_length);
01213   _unpack_p += string_length;
01214 }
01215 
01216 ////////////////////////////////////////////////////////////////////
01217 //     Function: DCPacker::advance
01218 //       Access: Private
01219 //  Description: Advances to the next field after a call to
01220 //               pack_value() or pop().
01221 ////////////////////////////////////////////////////////////////////
01222 INLINE void DCPacker::
01223 advance() {
01224   _current_field_index++;
01225   if (_num_nested_fields >= 0 &&
01226       _current_field_index >= _num_nested_fields) {
01227     // Done with all the fields on this parent.  The caller must now
01228     // call pop().
01229     _current_field = NULL;
01230 
01231     // But if the parent is a switch record, we make a special case so
01232     // we can get the alternate fields.
01233     if (_current_parent != (DCPackerInterface *)NULL) {
01234       const DCSwitchParameter *switch_parameter = ((DCPackerInterface *)_current_parent)->as_switch_parameter();
01235       if (switch_parameter != (DCSwitchParameter *)NULL) {
01236         handle_switch(switch_parameter);
01237       }
01238     }
01239 
01240   } else if (_pop_marker != 0 && _unpack_p >= _pop_marker) {
01241     // Done with all the fields on this parent.  The caller must now
01242     // call pop().
01243     _current_field = NULL;
01244 
01245   } else {
01246     // We have another field to advance to.
01247     _current_field = _current_parent->get_nested_field(_current_field_index);
01248   }
01249 }
01250 
01251 ////////////////////////////////////////////////////////////////////
01252 //     Function: DCPacker::StackElement::operator new
01253 //       Access: Public
01254 //  Description: Allocates the memory for a new DCPacker::StackElement.
01255 //               This is specialized here to provide for fast
01256 //               allocation of these things.
01257 ////////////////////////////////////////////////////////////////////
01258 INLINE void *DCPacker::StackElement::
01259 operator new(size_t size) {
01260   if (_deleted_chain != (DCPacker::StackElement *)NULL) {
01261     StackElement *obj = _deleted_chain;
01262     _deleted_chain = _deleted_chain->_next;
01263     return obj;
01264   }
01265 #ifndef NDEBUG
01266   _num_ever_allocated++;
01267 #endif  // NDEBUG
01268   return ::operator new(size);
01269 }
01270 
01271 ////////////////////////////////////////////////////////////////////
01272 //     Function: DCPacker::StackElement::operator delete
01273 //       Access: Public
01274 //  Description: Frees the memory for a deleted DCPacker::StackElement.
01275 //               This is specialized here to provide for fast
01276 //               allocation of these things.
01277 ////////////////////////////////////////////////////////////////////
01278 INLINE void DCPacker::StackElement::
01279 operator delete(void *ptr) {
01280   StackElement *obj = (StackElement *)ptr;
01281   obj->_next = _deleted_chain;
01282   _deleted_chain = obj;
01283 }
 All Classes Functions Variables Enumerations