15 #include "pandabase.h" 19 #include "bamReader.h" 20 #include "datagramIterator.h" 21 #include "config_util.h" 22 #include "pipelineCyclerBase.h" 30 BamReader::NewTypes BamReader::_new_types;
32 const int BamReader::_cur_major = _bam_major_ver;
33 const int BamReader::_cur_minor = _bam_minor_ver;
46 _num_extra_objects = 0;
48 _now_creating = _created_objs.end();
51 _long_object_id =
false;
63 nassertv(_num_extra_objects == 0);
64 nassertv(_nesting_level == 0);
77 if (_needs_init && _source != NULL) {
78 bool success =
init();
95 nassertr(_source != NULL,
false);
96 nassertr(_needs_init,
false);
100 if (_source->is_error()) {
104 if (!get_datagram(header)) {
106 <<
"Unable to read Bam header.\n";
117 if (_file_major != _bam_major_ver ||
118 _file_minor < _bam_first_minor_ver ||
119 _file_minor > _bam_minor_ver) {
121 <<
"Bam file is version " << _file_major <<
"." << _file_minor
124 if (_bam_minor_ver == _bam_first_minor_ver) {
126 <<
"This program can only load version " 127 << _bam_major_ver <<
"." << _bam_first_minor_ver <<
" bams.\n";
130 <<
"This program can only load version " 131 << _bam_major_ver <<
"." << _bam_first_minor_ver <<
" through " 132 << _bam_major_ver <<
"." << _bam_minor_ver <<
" bams.\n";
138 _file_endian = (BamEndian)scan.
get_uint8();
140 _file_stdfloat_double =
false;
141 if (_file_minor >= 27) {
142 _file_stdfloat_double = scan.
get_bool();
147 <<
"Bam header is too short.\n";
183 if (data == (
void *)NULL) {
184 AuxDataTable::iterator ti = _aux_data.find(obj);
185 if (ti != _aux_data.end()) {
194 _aux_data[obj][name] = data;
207 AuxDataTable::const_iterator ti = _aux_data.find(obj);
208 if (ti != _aux_data.end()) {
210 AuxDataNames::const_iterator ni = names.find(name);
211 if (ni != names.end()) {
276 nassertr(_num_extra_objects == 0,
false);
278 int start_level = _nesting_level;
281 int object_id = p_read_object();
290 while (_num_extra_objects > 0) {
292 _num_extra_objects--;
297 while (_nesting_level > start_level) {
303 if (object_id == 0) {
304 if (bam_cat.is_spam()) {
306 <<
"Returning false\n";
311 CreatedObjs::iterator oi = _created_objs.find(object_id);
313 if (oi == _created_objs.end()) {
315 <<
"Undefined object encountered!\n";
319 CreatedObj &created_obj = (*oi).second;
320 ptr = created_obj._ptr;
321 ref_ptr = created_obj._ref_ptr;
323 if (bam_cat.is_spam()) {
326 <<
"Returning object of type " << ptr->get_type() <<
"\n";
329 if (created_obj._change_this != NULL ||
330 created_obj._change_this_ref != NULL) {
332 <<
"Returning pointer to " << ptr->get_type()
333 <<
" that might change.\n";
361 bool any_completed_this_pass;
364 if (bam_cat.is_spam()) {
366 <<
"resolve pass begin\n";
368 all_completed =
true;
369 any_completed_this_pass =
false;
371 ObjectPointers::iterator oi;
372 oi = _object_pointers.begin();
373 while (oi != _object_pointers.end()) {
374 int object_id = (*oi).first;
375 PointerReference &pref = (*oi).second;
377 CreatedObjs::iterator ci = _created_objs.find(object_id);
378 nassertr(ci != _created_objs.end(),
false);
380 CreatedObj &created_obj = (*ci).second;
386 CreatedObjs::iterator was_creating = _now_creating;
389 if (resolve_object_pointers(object_ptr, pref)) {
393 ObjectPointers::iterator old = oi;
395 _object_pointers.erase(old);
396 any_completed_this_pass =
true;
399 if (created_obj._change_this_ref != NULL) {
402 nassertr(created_obj._ref_ptr == NULL || created_obj._ref_ptr == object_ref_ptr,
false);
404 if (new_ptr != object_ref_ptr) {
406 vector_int &old_refs = _created_objs_by_pointer[object_ptr];
407 vector_int &new_refs = _created_objs_by_pointer[new_ptr];
408 for (vector_int::const_iterator oi = old_refs.begin();
409 oi != old_refs.end();
411 new_refs.push_back(*oi);
413 _created_objs_by_pointer.erase(object_ptr);
417 _finalize_list.erase(object_ptr);
419 created_obj.set_ptr(new_ptr, new_ptr);
420 created_obj._change_this = NULL;
421 created_obj._change_this_ref = NULL;
423 }
else if (created_obj._change_this != NULL) {
425 TypedWritable *new_ptr = created_obj._change_this(object_ptr,
this);
426 if (new_ptr != object_ptr) {
428 vector_int &old_refs = _created_objs_by_pointer[object_ptr];
429 vector_int &new_refs = _created_objs_by_pointer[new_ptr];
430 for (vector_int::const_iterator oi = old_refs.begin();
431 oi != old_refs.end();
433 new_refs.push_back(*oi);
435 _created_objs_by_pointer.erase(object_ptr);
439 _finalize_list.erase(object_ptr);
442 created_obj._change_this = NULL;
443 created_obj._change_this_ref = NULL;
449 all_completed =
false;
452 _now_creating = was_creating;
455 if (bam_cat.is_spam()) {
457 <<
"resolve pass end: all_completed = " << all_completed
458 <<
" any_completed_this_pass = " << any_completed_this_pass
461 }
while (!all_completed && any_completed_this_pass);
471 ObjectPointers::const_iterator oi;
472 for (oi = _object_pointers.begin();
473 oi != _object_pointers.end();
475 int object_id = (*oi).first;
476 CreatedObjs::iterator ci = _created_objs.find(object_id);
477 nassertr(ci != _created_objs.end(),
false);
478 CreatedObj &created_obj = (*ci).second;
482 <<
"Unable to complete " << object_ptr->get_type() <<
"\n";
486 return all_completed;
504 if (orig_pointer == new_pointer) {
507 CreatedObjsByPointer::iterator ci = _created_objs_by_pointer.find(orig_pointer);
508 if (ci == _created_objs_by_pointer.end()) {
513 if (bam_cat.is_spam()) {
515 <<
"change_pointer(" << (
void *)orig_pointer <<
", " 516 << (
void *)new_pointer <<
") (" << new_pointer->get_type() <<
")\n";
519 const vector_int &old_refs = (*ci).second;
520 vector_int &new_refs = _created_objs_by_pointer[new_pointer];
522 for (vector_int::const_iterator oi = old_refs.begin();
523 oi != old_refs.end();
525 int object_id = (*oi);
527 CreatedObjs::iterator ci = _created_objs.find(object_id);
528 nassertr(ci != _created_objs.end(),
false);
529 nassertr((*ci).second._ptr == orig_pointer,
false);
533 new_refs.push_back(object_id);
536 _created_objs_by_pointer.erase(ci);
539 Finalize::iterator fi = _finalize_list.find((
TypedWritable *)orig_pointer);
540 if (fi != _finalize_list.end()) {
542 _finalize_list.erase(fi);
575 IndexMap::const_iterator mi = _index_map.find(
id);
576 if (mi != _index_map.end()) {
590 bool new_type =
false;
600 <<
"Bam file '" <<
get_filename() <<
"' contains objects of unknown type: " 603 _new_types.insert(type);
607 int num_parent_classes = scan.
get_uint8();
608 for (
int i = 0; i < num_parent_classes; i++) {
614 if (bam_cat.is_debug()) {
616 <<
"Bam file indicates a derivation of " << type
617 <<
" from " << parent_type <<
" which is no longer true.\n";
623 bool inserted = _index_map.insert(IndexMap::value_type(
id, type)).second;
624 nassertr(inserted, type);
626 if (bam_cat.is_spam()) {
628 <<
"Read TypeHandle for " << type <<
".\n";
661 nassertv(_now_creating != _created_objs.end());
662 int requestor_id = (*_now_creating).first;
665 int object_id = read_object_id(scan);
667 PointerReference &pref = _object_pointers[requestor_id];
670 pref._objects.push_back(object_id);
673 pref._cycler_pointers[_reading_cycler].push_back(object_id);
678 if (object_id != 0) {
687 _num_extra_objects++;
701 for (
int i = 0; i < count; i++) {
716 read_object_id(scan);
738 nassertv(!_file_data_records.empty());
739 info = _file_data_records.front();
740 _file_data_records.pop_front();
755 _reading_cycler = &cycler;
757 cdata->
fillin(scan,
this);
759 _reading_cycler = old_cycler;
772 _reading_cycler = &cycler;
774 cdata->
fillin(scan,
this, extra_data);
776 _reading_cycler = old_cycler;
796 nassertv(_now_creating != _created_objs.end());
797 int requestor_id = (*_now_creating).first;
799 PointerReference &pref = _object_pointers[requestor_id];
800 pref._int_tags[tag] = value;
811 nassertr(_now_creating != _created_objs.end(), 0);
812 int requestor_id = (*_now_creating).first;
814 ObjectPointers::const_iterator opi = _object_pointers.find(requestor_id);
815 nassertr(opi != _object_pointers.end(), 0);
816 const PointerReference &pref = (*opi).second;
818 IntTags::const_iterator iti = pref._int_tags.find(tag);
819 nassertr(iti != pref._int_tags.end(), 0);
820 return (*iti).second;
845 nassertv(_now_creating != _created_objs.end());
846 int requestor_id = (*_now_creating).first;
848 PointerReference &pref = _object_pointers[requestor_id];
849 pref._aux_tags[tag] = value;
860 nassertr(_now_creating != _created_objs.end(), NULL);
861 int requestor_id = (*_now_creating).first;
863 ObjectPointers::const_iterator opi = _object_pointers.find(requestor_id);
864 nassertr(opi != _object_pointers.end(), NULL);
865 const PointerReference &pref = (*opi).second;
867 AuxTags::const_iterator ati = pref._aux_tags.find(tag);
868 nassertr(ati != pref._aux_tags.end(), NULL);
869 return (*ati).second;
889 if (bam_cat.is_spam()) {
891 <<
"register_finalize(" << (
void *)whom <<
") (" << whom->get_type()
895 _finalize_list.insert(whom);
918 nassertv(_now_creating != _created_objs.end());
919 CreatedObj &created_obj = (*_now_creating).second;
929 nassertv(created_obj._ptr ==
object);
933 created_obj._change_this = func;
934 created_obj._change_this_ref = NULL;
957 nassertv(_now_creating != _created_objs.end());
958 CreatedObj &created_obj = (*_now_creating).second;
964 created_obj.set_ptr(
object,
object);
968 nassertv(created_obj._ptr ==
object);
969 nassertv(created_obj._ref_ptr ==
object);
973 created_obj._change_this = NULL;
974 created_obj._change_this_ref = func;
991 Finalize::iterator fi = _finalize_list.find(whom);
992 if (fi != _finalize_list.end()) {
993 _finalize_list.erase(fi);
994 if (bam_cat.is_spam()) {
996 <<
"finalizing " << (
void *)whom <<
" (" << whom->get_type()
1026 nassertr(_pta_id == -1, (
void *)NULL);
1027 int id = read_pta_id(scan);
1035 return (
void *)NULL;
1038 PTAMap::iterator pi = _pta_map.find(
id);
1039 if (pi == _pta_map.end()) {
1043 return (
void *)NULL;
1046 return (*pi).second;
1064 if (_pta_id != -1) {
1065 bool inserted = _pta_map.insert(PTAMap::value_type(_pta_id, ptr)).second;
1086 int object_id = read_object_id(scan);
1088 CreatedObjs::iterator ci = _created_objs.find(object_id);
1089 if (ci == _created_objs.end()) {
1091 <<
"Bam file suggests eliminating object_id " << object_id
1092 <<
", already gone.\n";
1096 ObjectPointers::iterator oi = _object_pointers.find(object_id);
1097 if (oi != _object_pointers.end()) {
1099 <<
"Unable to resolve object " << object_id
1100 <<
" before removing from table.\n";
1103 _created_objs_by_pointer.erase((*ci).second._ptr);
1104 _created_objs.erase(ci);
1119 if (_long_object_id) {
1124 if (object_id == 0xffff) {
1125 _long_object_id =
true;
1146 if (pta_id == 0xffff) {
1147 _long_pta_id =
true;
1166 if (!get_datagram(dg)) {
1168 if (bam_cat.is_debug()) {
1170 <<
"Reached end of bam source.\n";
1180 BamObjectCode boc = BOC_adjunct;
1200 free_object_ids(scan);
1205 return p_read_object();
1216 <<
"Failed to read file data.\n";
1219 _file_data_records.push_back(info);
1222 return p_read_object();
1226 <<
"Encountered invalid BamObjectCode 0x" << hex << (int)boc << dec <<
".\n";
1237 int object_id = read_object_id(scan);
1241 <<
"Found truncated datagram in bam stream\n";
1267 CreatedObj new_created_obj;
1268 CreatedObjs::iterator oi =
1269 _created_objs.insert(CreatedObjs::value_type(object_id, new_created_obj)).first;
1270 CreatedObj &created_obj = (*oi).second;
1272 if (created_obj._ptr != NULL) {
1281 CreatedObjs::iterator was_creating = _now_creating;
1283 created_obj._ptr->fillin(scan,
this);
1284 _now_creating = was_creating;
1289 <<
"in datagram containing type " << type <<
"\n";
1302 CreatedObjs::iterator was_creating = _now_creating;
1306 _now_creating = was_creating;
1309 nassertr(created_obj._ptr ==
object || created_obj._ptr == NULL, object_id);
1310 if (
object == NULL) {
1311 created_obj.set_ptr(NULL, NULL);
1315 created_obj._created =
true;
1317 if (created_obj._change_this_ref != NULL) {
1323 ObjectPointers::const_iterator ri = _object_pointers.find(object_id);
1324 if (ri == _object_pointers.end()) {
1327 created_obj.set_ptr(object_ref, object_ref);
1328 created_obj._change_this = NULL;
1329 created_obj._change_this_ref = NULL;
1333 if (new_ptr !=
object) {
1334 _finalize_list.erase(
object);
1339 }
else if (created_obj._change_this != NULL) {
1341 ObjectPointers::const_iterator ri = _object_pointers.find(object_id);
1342 if (ri == _object_pointers.end()) {
1343 TypedWritable *new_ptr = (*created_obj._change_this)(
object,
this);
1345 created_obj._change_this = NULL;
1346 created_obj._change_this_ref = NULL;
1348 if (new_ptr !=
object) {
1349 _finalize_list.erase(
object);
1355 _created_objs_by_pointer[created_obj._ptr].push_back(object_id);
1359 if (bam_cat.is_debug()) {
1361 <<
"Unable to create an object of type " << type << endl;
1364 }
else if (object->get_type() != type) {
1365 if (_new_types.find(type) != _new_types.end()) {
1369 if (bam_cat.is_debug()) {
1371 <<
"Attempted to create a " << type.
get_name() \
1372 <<
" but a " <<
object->get_type() \
1373 <<
" was created instead." << endl;
1380 <<
"Attempted to create a " << type.
get_name() \
1381 <<
" but a " <<
object->get_type() \
1382 <<
" was created instead." << endl;
1386 if (bam_cat.is_spam()) {
1388 <<
"Read a " <<
object->get_type() <<
": " << (
void *)
object <<
"\n";
1396 <<
"End of datagram reached while reading bam object " 1397 << type <<
": " << (
void *)created_obj._ptr <<
"\n";
1414 BamReader::PointerReference &pref) {
1418 bool require_fully_complete =
object->require_fully_complete();
1421 CyclerPointers::iterator ci;
1422 ci = pref._cycler_pointers.begin();
1423 while (ci != pref._cycler_pointers.end()) {
1425 const vector_int &pointer_ids = (*ci).second;
1427 if (resolve_cycler_pointers(cycler, pointer_ids, require_fully_complete)) {
1431 CyclerPointers::iterator old = ci;
1433 pref._cycler_pointers.erase(old);
1441 if (!pref._cycler_pointers.empty()) {
1443 if (bam_cat.is_spam()) {
1445 <<
"some cyclers pending: complete_pointers for " << (
void *)
object 1446 <<
" (" << object->get_type() <<
")\n";
1456 bool is_complete =
true;
1458 vector_typedWritable references;
1459 references.reserve(pref._objects.size());
1461 vector_int::const_iterator pi;
1462 for (pi = pref._objects.begin();
1463 pi != pref._objects.end() && is_complete;
1465 int child_id = (*pi);
1466 if (child_id == 0) {
1472 CreatedObjs::const_iterator oi = _created_objs.find(child_id);
1473 if (oi == _created_objs.end()) {
1475 is_complete =
false;
1478 const CreatedObj &child_obj = (*oi).second;
1479 if (!child_obj._created) {
1481 is_complete =
false;
1482 }
else if (child_obj._change_this != NULL || child_obj._change_this_ref != NULL) {
1484 is_complete =
false;
1486 if (require_fully_complete &&
1487 _object_pointers.find(child_id) != _object_pointers.end()) {
1489 is_complete =
false;
1493 references.push_back(child_obj._ptr);
1502 nassertr(references.size() == pref._objects.size(),
false);
1504 if (bam_cat.is_spam()) {
1506 <<
"complete_pointers for " << (
void *)
object 1507 <<
" (" << object->get_type() <<
"), " << references.size()
1510 int num_completed = 0;
1511 if (!references.empty()) {
1512 num_completed =
object->complete_pointers(&references[0],
this);
1514 if (num_completed != (
int)references.size()) {
1516 <<
object->get_type() <<
" completed " << num_completed
1517 <<
" of " << references.size() <<
" pointers.\n";
1518 nassertr(num_completed < (
int)references.size(),
true);
1523 if (bam_cat.is_spam()) {
1525 <<
"not ready: complete_pointers for " << (
void *)
object 1526 <<
" (" << object->get_type() <<
")\n";
1543 const vector_int &pointer_ids,
1544 bool require_fully_complete) {
1551 bool is_complete =
true;
1552 vector_typedWritable references;
1554 vector_int::const_iterator pi;
1555 for (pi = pointer_ids.begin(); pi != pointer_ids.end() && is_complete; ++pi) {
1556 int child_id = (*pi);
1558 if (child_id == 0) {
1564 CreatedObjs::const_iterator oi = _created_objs.find(child_id);
1565 if (oi == _created_objs.end()) {
1567 is_complete =
false;
1570 const CreatedObj &child_obj = (*oi).second;
1571 if (child_obj._change_this != NULL || child_obj._change_this_ref != NULL) {
1573 is_complete =
false;
1576 if (require_fully_complete &&
1577 _object_pointers.find(child_id) != _object_pointers.end()) {
1579 is_complete =
false;
1583 references.push_back(child_obj._ptr);
1593 if (bam_cat.is_spam()) {
1595 <<
"complete_pointers for CycleData object " << (
void *)cdata
1600 if (num_completed != (
int)references.size()) {
1602 <<
"CycleData object completed " << num_completed
1603 <<
" of " << references.size() <<
" pointers.\n";
1604 nassertr(num_completed < (
int)references.size(),
true);
1621 if (bam_cat.is_debug()) {
1623 <<
"Finalizing bam source\n";
1626 Finalize::iterator fi = _finalize_list.begin();
1627 while (fi != _finalize_list.end()) {
1630 _finalize_list.erase(fi);
1631 if (bam_cat.is_spam()) {
1633 <<
"finalizing " << (
void *)
object <<
" (" << object->get_type()
1636 object->finalize(
this);
1637 _aux_data.erase(
object);
1638 fi = _finalize_list.begin();
1642 if (!_aux_data.empty()) {
1643 AuxDataTable::iterator ti = _aux_data.find((
TypedWritable *)NULL);
1645 if (ti != _aux_data.end()) {
1646 if (_aux_data.size() > 1) {
1648 AuxDataTable new_aux_data;
1649 AuxDataTable::iterator nti =
1651 (*nti).second.swap((*ti).second);
1652 _aux_data.swap(new_aux_data);
1666 BamReader::AuxData::
This is our own Panda specialization on the default STL map.
void read_file_data(SubfileInfo &info)
Reads a block of auxiliary file data from the Bam file.
void set_source(DatagramGenerator *source)
Changes the source of future datagrams for this BamReader.
bool get_bool()
Extracts a boolean value.
virtual void finalize(BamReader *manager)
Called by the BamReader to perform any final actions needed for setting up the object after all objec...
Stores auxiliary data that may be piggybacked on the BamReader during each object's read pass...
static TypeHandle none()
Returns a special zero-valued TypeHandle that is used to indicate no type.
A Factory can be used to create an instance of a particular subclass of some general base class...
virtual ReferenceCount * as_reference_count()
Returns the pointer cast to a ReferenceCount pointer, if it is in fact of that type.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
TypeHandle find_type(const string &name) const
Looks for a previously-registered type of the given name.
bool resolve()
This may be called at any time during processing of the Bam file to resolve all the known pointers so...
void read_cdata(DatagramIterator &scan, PipelineCyclerBase &cycler)
Reads in the indicated CycleData object.
Type * make_instance_more_general(TypeHandle handle, const FactoryParams ¶ms=FactoryParams())
Attempts to create an instance of the type requested, or some base type of the type requested...
TypedWritable * read_object()
Reads a single object from the Bam file.
void * get_pta(DatagramIterator &scan)
This function works in conjection with register_pta(), below, to read a PointerToArray (PTA) from the...
A single page of data maintained by a PipelineCycler.
Base class for objects that can be written to and read from Bam files.
void skip_pointer(DatagramIterator &scan)
Reads and discards a pointer value from the Bam file.
This is the trivial, non-threaded implementation of PipelineCyclerBase.
string get_name(TypedObject *object=(TypedObject *) NULL) const
Returns the name of the type.
PN_uint8 get_uint8()
Extracts an unsigned 8-bit integer.
PN_uint32 get_uint32()
Extracts an unsigned 32-bit integer.
static void consider_yield()
Possibly suspends the current thread for the rest of the current epoch, if it has run for enough this...
int get_int_tag(const string &tag) const
Returns the value previously set via set_int_tag().
CycleData * write(Thread *current_thread)
Returns a non-const CycleData pointer, filled with a unique copy of the data for the current stage of...
string get_string()
Extracts a variable-length string.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
PN_uint16 get_uint16()
Extracts an unsigned 16-bit integer.
void register_change_this(ChangeThisFunc func, TypedWritable *whom)
Called by an object reading itself from the bam file to indicate that the object pointer that will be...
static Thread * get_current_thread()
Returns a pointer to the currently-executing Thread object.
TypeHandle register_dynamic_type(const string &name)
Registers a new type on-the-fly, presumably at runtime.
TypeHandle get_parent_towards(TypeHandle ancestor, TypedObject *object=(TypedObject *) NULL) const
Returns the parent class that is in a direct line of inheritance to the indicated ancestor class...
bool init()
Initializes the BamReader prior to reading any objects from its source.
size_t get_current_index() const
Returns the current position within the datagram of the next piece of data to extract.
virtual bool save_datagram(SubfileInfo &info)
Skips over the next datagram without extracting it, but saves the relevant file information in the Su...
int get_remaining_size() const
Return the bytes left in the datagram.
void read_pointers(DatagramIterator &scan, int count)
A convenience function to read a contiguous list of pointers.
bool change_pointer(const TypedWritable *orig_pointer, const TypedWritable *new_pointer)
Indicates that an object recently read from the bam stream should be replaced with a new object...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
void register_finalize(TypedWritable *whom)
Should be called by an object reading itself from the Bam file to indicate that this particular objec...
A base class for things which need to inherit from both TypedWritable and from ReferenceCount.
void finalize_now(TypedWritable *whom)
Forces the finalization of a particular object.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class's make_from_bam() method to read in all...
static TypeRegistry * ptr()
Returns the pointer to the global TypeRegistry object.
A base class for all things that want to be reference-counted.
void release_write(CycleData *pointer)
Releases a pointer previously obtained via a call to write().
BamReaderAuxData * get_aux_tag(const string &tag) const
Returns the value previously set via set_aux_tag().
AuxData * get_aux_data(TypedWritable *obj, const string &name) const
Returns the pointer previously associated with the bam reader by a previous call to set_aux_data()...
void set_aux_tag(const string &tag, BamReaderAuxData *value)
Allows the creating object to store a temporary data value on the BamReader.
This class records a particular byte sub-range within an existing file on disk.
void set_int_tag(const string &tag, int value)
Allows the creating object to store a temporary data value on the BamReader.
A class to retrieve the individual data elements previously stored in a Datagram. ...
TypeHandle is the identifier used to differentiate C++ class types.
The parameters that are passed through the Factory to any object constructing itself from a Bam file...
This class defines the abstract interace to any source of datagrams, whether it be from a file or fro...
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
void record_derivation(TypeHandle child, TypeHandle parent)
Records that the type referenced by child inherits directly from the type referenced by parent...
void set_aux_data(TypedWritable *obj, const string &name, AuxData *data)
Associates an arbitrary block of data with the indicated object (or NULL), and the indicated name...
const Filename & get_filename() const
If a BAM is a file, then the BamReader should contain the name of the file.
TypeHandle read_handle(DatagramIterator &scan)
Reads a TypeHandle out of the Datagram.
size_t get_length() const
Returns the number of bytes in the datagram.
void register_pta(void *ptr)
The second part of read_pta(), this should be called with the pointer to the array that was read in a...
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.