Panda3D
 All Classes Functions Variables Enumerations
dcPackerInterface.cxx
00001 // Filename: dcPackerInterface.cxx
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 #include "dcPackerInterface.h"
00016 #include "dcPackerCatalog.h"
00017 #include "dcField.h"
00018 #include "dcParserDefs.h"
00019 #include "dcLexerDefs.h"
00020 
00021 ////////////////////////////////////////////////////////////////////
00022 //     Function: DCPackerInterface::Constructor
00023 //       Access: Public
00024 //  Description: 
00025 ////////////////////////////////////////////////////////////////////
00026 DCPackerInterface::
00027 DCPackerInterface(const string &name) :
00028   _name(name)
00029 {
00030   _has_fixed_byte_size = false;
00031   _fixed_byte_size = 0;
00032   _has_fixed_structure = false;
00033   _has_range_limits = false;
00034   _num_length_bytes = 0;
00035   _has_nested_fields = false;
00036   _num_nested_fields = -1;
00037   _pack_type = PT_invalid;
00038   _catalog = NULL;
00039 }
00040 
00041 ////////////////////////////////////////////////////////////////////
00042 //     Function: DCPackerInterface::Copy Constructor
00043 //       Access: Public
00044 //  Description: 
00045 ////////////////////////////////////////////////////////////////////
00046 DCPackerInterface::
00047 DCPackerInterface(const DCPackerInterface &copy) :
00048   _name(copy._name),
00049   _has_fixed_byte_size(copy._has_fixed_byte_size),
00050   _fixed_byte_size(copy._fixed_byte_size),
00051   _has_fixed_structure(copy._has_fixed_structure),
00052   _has_range_limits(copy._has_range_limits),
00053   _num_length_bytes(copy._num_length_bytes),
00054   _has_nested_fields(copy._has_nested_fields),
00055   _num_nested_fields(copy._num_nested_fields),
00056   _pack_type(copy._pack_type)
00057 {
00058   _catalog = NULL;
00059 }
00060 
00061 ////////////////////////////////////////////////////////////////////
00062 //     Function: DCPackerInterface::Destructor
00063 //       Access: Public, Virtual
00064 //  Description: 
00065 ////////////////////////////////////////////////////////////////////
00066 DCPackerInterface::
00067 ~DCPackerInterface() {
00068   if (_catalog != (DCPackerCatalog *)NULL) {
00069     delete _catalog;
00070   }
00071 }
00072 
00073 ////////////////////////////////////////////////////////////////////
00074 //     Function: DCPackerInterface::find_seek_index
00075 //       Access: Published
00076 //  Description: Returns the index number to be passed to a future
00077 //               call to DCPacker::seek() to seek directly to the
00078 //               named field without having to look up the field name
00079 //               in a table later, or -1 if the named field cannot be
00080 //               found.
00081 //
00082 //               If the named field is nested within a switch or some
00083 //               similar dynamic structure that reveals different
00084 //               fields based on the contents of the data, this
00085 //               mechanism cannot be used to pre-fetch the field index
00086 //               number--you must seek for the field by name.
00087 ////////////////////////////////////////////////////////////////////
00088 int DCPackerInterface::
00089 find_seek_index(const string &name) const {
00090   return get_catalog()->find_entry_by_name(name);
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //     Function: DCPackerInterface::as_field
00095 //       Access: Published, Virtual
00096 //  Description: 
00097 ////////////////////////////////////////////////////////////////////
00098 DCField *DCPackerInterface::
00099 as_field() {
00100   return (DCField *)NULL;
00101 }
00102 
00103 ////////////////////////////////////////////////////////////////////
00104 //     Function: DCPackerInterface::as_field
00105 //       Access: Published, Virtual
00106 //  Description: 
00107 ////////////////////////////////////////////////////////////////////
00108 const DCField *DCPackerInterface::
00109 as_field() const {
00110   return (DCField *)NULL;
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////
00114 //     Function: DCPackerInterface::as_switch_parameter
00115 //       Access: Published, Virtual
00116 //  Description: 
00117 ////////////////////////////////////////////////////////////////////
00118 DCSwitchParameter *DCPackerInterface::
00119 as_switch_parameter() {
00120   return (DCSwitchParameter *)NULL;
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: DCPackerInterface::as_switch_parameter
00125 //       Access: Published, Virtual
00126 //  Description: 
00127 ////////////////////////////////////////////////////////////////////
00128 const DCSwitchParameter *DCPackerInterface::
00129 as_switch_parameter() const {
00130   return (DCSwitchParameter *)NULL;
00131 }
00132 
00133 ////////////////////////////////////////////////////////////////////
00134 //     Function: DCPackerInterface::as_class_parameter
00135 //       Access: Published, Virtual
00136 //  Description: 
00137 ////////////////////////////////////////////////////////////////////
00138 DCClassParameter *DCPackerInterface::
00139 as_class_parameter() {
00140   return (DCClassParameter *)NULL;
00141 }
00142 
00143 ////////////////////////////////////////////////////////////////////
00144 //     Function: DCPackerInterface::as_class_parameter
00145 //       Access: Published, Virtual
00146 //  Description: 
00147 ////////////////////////////////////////////////////////////////////
00148 const DCClassParameter *DCPackerInterface::
00149 as_class_parameter() const {
00150   return (DCClassParameter *)NULL;
00151 }
00152 
00153 ////////////////////////////////////////////////////////////////////
00154 //     Function: DCPackerInterface::check_match
00155 //       Access: Published
00156 //  Description: Returns true if this interface is bitwise the same as
00157 //               the interface described with the indicated formatted
00158 //               string, e.g. "(uint8, uint8, int16)", or false
00159 //               otherwise.
00160 //
00161 //               If DCFile is not NULL, it specifies the DCFile that
00162 //               was previously loaded, from which some predefined
00163 //               structs and typedefs may be referenced in the
00164 //               description string.
00165 ////////////////////////////////////////////////////////////////////
00166 bool DCPackerInterface::
00167 check_match(const string &description, DCFile *dcfile) const {
00168   bool match = false;
00169 
00170   istringstream strm(description);
00171   dc_init_parser_parameter_description(strm, "check_match", dcfile);
00172   dcyyparse();
00173   dc_cleanup_parser();
00174 
00175   DCField *field = dc_get_parameter_description();
00176   if (field != NULL) {
00177     match = check_match(field);
00178     delete field;
00179   }
00180 
00181   if (dc_error_count() == 0) {
00182     return match;
00183   }
00184 
00185   // Parse error: no match is allowed.
00186   return false;
00187 }
00188 
00189 ////////////////////////////////////////////////////////////////////
00190 //     Function: DCPackerInterface::set_name
00191 //       Access: Public, Virtual
00192 //  Description: Sets the name of this field.
00193 ////////////////////////////////////////////////////////////////////
00194 void DCPackerInterface::
00195 set_name(const string &name) {
00196   _name = name;
00197 }
00198 
00199 ////////////////////////////////////////////////////////////////////
00200 //     Function: DCPackerInterface::calc_num_nested_fields
00201 //       Access: Public, Virtual
00202 //  Description: This flavor of get_num_nested_fields is used during
00203 //               unpacking.  It returns the number of nested fields to
00204 //               expect, given a certain length in bytes (as read from
00205 //               the _num_length_bytes stored in the stream on the
00206 //               push).  This will only be called if _num_length_bytes
00207 //               is nonzero.
00208 ////////////////////////////////////////////////////////////////////
00209 int DCPackerInterface::
00210 calc_num_nested_fields(size_t) const {
00211   return 0;
00212 }
00213 
00214 ////////////////////////////////////////////////////////////////////
00215 //     Function: DCPackerInterface::get_nested_field
00216 //       Access: Public, Virtual
00217 //  Description: Returns the DCPackerInterface object that represents
00218 //               the nth nested field.  This may return NULL if there
00219 //               is no such field (but it shouldn't do this if n is in
00220 //               the range 0 <= n < get_num_nested_fields()).
00221 ////////////////////////////////////////////////////////////////////
00222 DCPackerInterface *DCPackerInterface::
00223 get_nested_field(int) const {
00224   return NULL;
00225 }
00226 
00227 ////////////////////////////////////////////////////////////////////
00228 //     Function: DCPackerInterface::validate_num_nested_fields
00229 //       Access: Public, Virtual
00230 //  Description: After a number of fields have been packed via push()
00231 //               .. pack_*() .. pop(), this is called to confirm that
00232 //               the number of nested fields that were added is valid
00233 //               for this type.  This is primarily useful for array
00234 //               types with dynamic ranges that can't validate the
00235 //               number of fields any other way.
00236 ////////////////////////////////////////////////////////////////////
00237 bool DCPackerInterface::
00238 validate_num_nested_fields(int) const {
00239   return true;
00240 }
00241 
00242 ////////////////////////////////////////////////////////////////////
00243 //     Function: DCPackerInterface::pack_double
00244 //       Access: Public, Virtual
00245 //  Description: Packs the indicated numeric or string value into the
00246 //               stream.
00247 ////////////////////////////////////////////////////////////////////
00248 void DCPackerInterface::
00249 pack_double(DCPackData &, double, bool &pack_error, bool &) const {
00250   pack_error = true;
00251 }
00252 
00253 ////////////////////////////////////////////////////////////////////
00254 //     Function: DCPackerInterface::pack_int
00255 //       Access: Public, Virtual
00256 //  Description: Packs the indicated numeric or string value into the
00257 //               stream.
00258 ////////////////////////////////////////////////////////////////////
00259 void DCPackerInterface::
00260 pack_int(DCPackData &, int, bool &pack_error, bool &) const {
00261   pack_error = true;
00262 }
00263 
00264 ////////////////////////////////////////////////////////////////////
00265 //     Function: DCPackerInterface::pack_uint
00266 //       Access: Public, Virtual
00267 //  Description: Packs the indicated numeric or string value into the
00268 //               stream.
00269 ////////////////////////////////////////////////////////////////////
00270 void DCPackerInterface::
00271 pack_uint(DCPackData &, unsigned int, bool &pack_error, bool &) const {
00272   pack_error = true;
00273 }
00274 
00275 ////////////////////////////////////////////////////////////////////
00276 //     Function: DCPackerInterface::pack_int64
00277 //       Access: Public, Virtual
00278 //  Description: Packs the indicated numeric or string value into the
00279 //               stream.
00280 ////////////////////////////////////////////////////////////////////
00281 void DCPackerInterface::
00282 pack_int64(DCPackData &, PN_int64, bool &pack_error, bool &) const {
00283   pack_error = true;
00284 }
00285 
00286 ////////////////////////////////////////////////////////////////////
00287 //     Function: DCPackerInterface::pack_uint64
00288 //       Access: Public, Virtual
00289 //  Description: Packs the indicated numeric or string value into the
00290 //               stream.
00291 ////////////////////////////////////////////////////////////////////
00292 void DCPackerInterface::
00293 pack_uint64(DCPackData &, PN_uint64, bool &pack_error, bool &) const {
00294   pack_error = true;
00295 }
00296 
00297 ////////////////////////////////////////////////////////////////////
00298 //     Function: DCPackerInterface::pack_string
00299 //       Access: Public, Virtual
00300 //  Description: Packs the indicated numeric or string value into the
00301 //               stream.
00302 ////////////////////////////////////////////////////////////////////
00303 void DCPackerInterface::
00304 pack_string(DCPackData &, const string &, bool &pack_error, bool &) const {
00305   pack_error = true;
00306 }
00307 
00308 ////////////////////////////////////////////////////////////////////
00309 //     Function: DCPackerInterface::pack_default_value
00310 //       Access: Public, Virtual
00311 //  Description: Packs the field's specified default value (or a
00312 //               sensible default if no value is specified) into the
00313 //               stream.  Returns true if the default value is packed,
00314 //               false if the field doesn't know how to pack its
00315 //               default value.
00316 ////////////////////////////////////////////////////////////////////
00317 bool DCPackerInterface::
00318 pack_default_value(DCPackData &, bool &) const {
00319   return false;
00320 }
00321 
00322 ////////////////////////////////////////////////////////////////////
00323 //     Function: DCPackerInterface::unpack_double
00324 //       Access: Public, Virtual
00325 //  Description: Unpacks the current numeric or string value from the
00326 //               stream.
00327 ////////////////////////////////////////////////////////////////////
00328 void DCPackerInterface::
00329 unpack_double(const char *, size_t, size_t &, double &, bool &pack_error, bool &) const {
00330   pack_error = true;
00331 }
00332 
00333 ////////////////////////////////////////////////////////////////////
00334 //     Function: DCPackerInterface::unpack_int
00335 //       Access: Public, Virtual
00336 //  Description: Unpacks the current numeric or string value from the
00337 //               stream.
00338 ////////////////////////////////////////////////////////////////////
00339 void DCPackerInterface::
00340 unpack_int(const char *, size_t, size_t &, int &, bool &pack_error, bool &) const {
00341   pack_error = true;
00342 }
00343 
00344 ////////////////////////////////////////////////////////////////////
00345 //     Function: DCPackerInterface::unpack_uint
00346 //       Access: Public, Virtual
00347 //  Description: Unpacks the current numeric or string value from the
00348 //               stream.
00349 ////////////////////////////////////////////////////////////////////
00350 void DCPackerInterface::
00351 unpack_uint(const char *, size_t, size_t &, unsigned int &, bool &pack_error, bool &) const {
00352   pack_error = true;
00353 }
00354 
00355 ////////////////////////////////////////////////////////////////////
00356 //     Function: DCPackerInterface::unpack_int64
00357 //       Access: Public, Virtual
00358 //  Description: Unpacks the current numeric or string value from the
00359 //               stream.
00360 ////////////////////////////////////////////////////////////////////
00361 void DCPackerInterface::
00362 unpack_int64(const char *, size_t, size_t &, PN_int64 &, bool &pack_error, bool &) const {
00363   pack_error = true;
00364 }
00365 
00366 ////////////////////////////////////////////////////////////////////
00367 //     Function: DCPackerInterface::unpack_uint64
00368 //       Access: Public, Virtual
00369 //  Description: Unpacks the current numeric or string value from the
00370 //               stream.
00371 ////////////////////////////////////////////////////////////////////
00372 void DCPackerInterface::
00373 unpack_uint64(const char *, size_t, size_t &, PN_uint64 &, bool &pack_error, bool &) const {
00374   pack_error = true;
00375 }
00376 
00377 ////////////////////////////////////////////////////////////////////
00378 //     Function: DCPackerInterface::unpack_string
00379 //       Access: Public, Virtual
00380 //  Description: Unpacks the current numeric or string value from the
00381 //               stream.
00382 ////////////////////////////////////////////////////////////////////
00383 void DCPackerInterface::
00384 unpack_string(const char *, size_t, size_t &, string &, bool &pack_error, bool &) const {
00385   pack_error = true;
00386 }
00387 
00388 ////////////////////////////////////////////////////////////////////
00389 //     Function: DCPackerInterface::unpack_validate
00390 //       Access: Public, Virtual
00391 //  Description: Internally unpacks the current numeric or string
00392 //               value and validates it against the type range limits,
00393 //               but does not return the value.  Returns true on
00394 //               success, false on failure (e.g. we don't know how to
00395 //               validate this field).
00396 ////////////////////////////////////////////////////////////////////
00397 bool DCPackerInterface::
00398 unpack_validate(const char *data, size_t length, size_t &p,
00399                 bool &pack_error, bool &) const {
00400   if (!_has_range_limits) {
00401     return unpack_skip(data, length, p, pack_error);
00402   }
00403   return false;
00404 }
00405 
00406 ////////////////////////////////////////////////////////////////////
00407 //     Function: DCPackerInterface::unpack_skip
00408 //       Access: Public, Virtual
00409 //  Description: Increments p to the end of the current field without
00410 //               actually unpacking any data or performing any range
00411 //               validation.  Returns true on success, false on
00412 //               failure (e.g. we don't know how to skip this field).
00413 ////////////////////////////////////////////////////////////////////
00414 bool DCPackerInterface::
00415 unpack_skip(const char *data, size_t length, size_t &p,
00416             bool &pack_error) const {
00417   if (_has_fixed_byte_size) {
00418     // If this field has a fixed byte size, it's easy to skip.
00419     p += _fixed_byte_size;
00420     if (p > length) {
00421       pack_error = true;
00422     }
00423     return true;
00424   }
00425 
00426   if (_has_nested_fields && _num_length_bytes != 0) {
00427     // If we have a length prefix, use that for skipping.
00428     if (p + _num_length_bytes > length) {
00429       pack_error = true;
00430       
00431     } else {
00432       if (_num_length_bytes == 4) {
00433         size_t this_length = do_unpack_uint32(data + p);
00434         p += this_length + 4;
00435       } else {
00436         size_t this_length = do_unpack_uint16(data + p);
00437         p += this_length + 2;
00438       }
00439       if (p > length) {
00440         pack_error = true;
00441       }
00442     }
00443     return true;
00444   }
00445 
00446   // Otherwise, we don't know how to skip this field (presumably it
00447   // can be skipped by skipping over its nested fields individually).
00448   return false;
00449 }
00450 
00451 ////////////////////////////////////////////////////////////////////
00452 //     Function: DCPackerInterface::get_catalog
00453 //       Access: Public
00454 //  Description: Returns the DCPackerCatalog associated with this
00455 //               field, listing all of the nested fields by name.
00456 ////////////////////////////////////////////////////////////////////
00457 const DCPackerCatalog *DCPackerInterface::
00458 get_catalog() const {
00459   if (_catalog == (DCPackerCatalog *)NULL) {
00460     ((DCPackerInterface *)this)->make_catalog();
00461   }
00462   return _catalog;
00463 }
00464 
00465 ////////////////////////////////////////////////////////////////////
00466 //     Function: DCPackerInterface::do_check_match_simple_parameter
00467 //       Access: Protected, Virtual
00468 //  Description: Returns true if this field matches the indicated
00469 //               simple parameter, false otherwise.
00470 ////////////////////////////////////////////////////////////////////
00471 bool DCPackerInterface::
00472 do_check_match_simple_parameter(const DCSimpleParameter *) const {
00473   return false;
00474 }
00475 
00476 ////////////////////////////////////////////////////////////////////
00477 //     Function: DCPackerInterface::do_check_match_class_parameter
00478 //       Access: Protected, Virtual
00479 //  Description: Returns true if this field matches the indicated
00480 //               class parameter, false otherwise.
00481 ////////////////////////////////////////////////////////////////////
00482 bool DCPackerInterface::
00483 do_check_match_class_parameter(const DCClassParameter *) const {
00484   return false;
00485 }
00486 
00487 ////////////////////////////////////////////////////////////////////
00488 //     Function: DCPackerInterface::do_check_match_switch_parameter
00489 //       Access: Protected, Virtual
00490 //  Description: Returns true if this field matches the indicated
00491 //               switch parameter, false otherwise.
00492 ////////////////////////////////////////////////////////////////////
00493 bool DCPackerInterface::
00494 do_check_match_switch_parameter(const DCSwitchParameter *) const {
00495   return false;
00496 }
00497 
00498 ////////////////////////////////////////////////////////////////////
00499 //     Function: DCPackerInterface::do_check_match_array_parameter
00500 //       Access: Protected, Virtual
00501 //  Description: Returns true if this field matches the indicated
00502 //               array parameter, false otherwise.
00503 ////////////////////////////////////////////////////////////////////
00504 bool DCPackerInterface::
00505 do_check_match_array_parameter(const DCArrayParameter *) const {
00506   return false;
00507 }
00508 
00509 ////////////////////////////////////////////////////////////////////
00510 //     Function: DCPackerInterface::do_check_match_atomic_field
00511 //       Access: Protected, Virtual
00512 //  Description: Returns true if this field matches the indicated
00513 //               atomic field, false otherwise.
00514 ////////////////////////////////////////////////////////////////////
00515 bool DCPackerInterface::
00516 do_check_match_atomic_field(const DCAtomicField *) const {
00517   return false;
00518 }
00519 
00520 ////////////////////////////////////////////////////////////////////
00521 //     Function: DCPackerInterface::do_check_match_molecular_field
00522 //       Access: Protected, Virtual
00523 //  Description: Returns true if this field matches the indicated
00524 //               molecular field, false otherwise.
00525 ////////////////////////////////////////////////////////////////////
00526 bool DCPackerInterface::
00527 do_check_match_molecular_field(const DCMolecularField *) const {
00528   return false;
00529 }
00530 
00531 ////////////////////////////////////////////////////////////////////
00532 //     Function: DCPackerInterface::make_catalog
00533 //       Access: Private
00534 //  Description: Called internally to create a new DCPackerCatalog
00535 //               object.
00536 ////////////////////////////////////////////////////////////////////
00537 void DCPackerInterface::
00538 make_catalog() {
00539   nassertv(_catalog == (DCPackerCatalog *)NULL);
00540   _catalog = new DCPackerCatalog(this);
00541 
00542   _catalog->r_fill_catalog("", this, NULL, 0);
00543 }
 All Classes Functions Variables Enumerations