Panda3D
Loading...
Searching...
No Matches
bamFile.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file bamFile.cxx
10 * @author drose
11 * @date 2000-07-02
12 */
13
14#include "bamFile.h"
15#include "config_pgraph.h"
16
17#include "bam.h"
18#include "bamCacheRecord.h"
19#include "config_putil.h"
20#include "bamReader.h"
21#include "bamWriter.h"
22#include "filename.h"
23#include "config_express.h"
24#include "virtualFileSystem.h"
25#include "dcast.h"
26
27using std::string;
28
29/**
30 *
31 */
32BamFile::
33BamFile() {
34 _reader = nullptr;
35 _writer = nullptr;
36}
37
38/**
39 *
40 */
41BamFile::
42~BamFile() {
43 close();
44}
45
46/**
47 * Attempts to open the indicated filename for reading. Returns true if
48 * successful, false on error.
49 */
51open_read(const Filename &bam_filename, bool report_errors) {
52 close();
53
54 if (!_din.open(bam_filename)) {
55 return false;
56 }
57
58 return continue_open_read(bam_filename, report_errors);
59}
60
61/**
62 * Attempts to open the indicated stream for reading. The filename is just
63 * for information purposes only. Returns true if successful, false on error.
64 */
66open_read(std::istream &in, const string &bam_filename, bool report_errors) {
67 close();
68
69 if (!_din.open(in)) {
70 return false;
71 }
72
73 return continue_open_read(bam_filename, report_errors);
74}
75
76/**
77 * Reads and returns the next object from the Bam file, or NULL if the end of
78 * the file has been reached, or if there is an error condition. Use is_eof()
79 * to differentiate these two cases.
80 *
81 * The pointers returned by this method will not be valid for use until
82 * resolve() is subsequently called.
83 */
86 if (_reader == nullptr) {
87 return nullptr;
88 }
89
90 return _reader->read_object();
91}
92
93/**
94 * Returns true if the reader has reached end-of-file, false otherwise. This
95 * call is only valid after a call to read_object().
96 */
98is_eof() const {
99 return _reader != nullptr && _reader->is_eof();
100}
101
102/**
103 * This must be called after one or more objects have been read via calls to
104 * read_object() in order to resolve all internal pointer references in the
105 * objects read and make all the pointers valid. It returns true if all
106 * objects are successfully resolved, or false if some have not been (in which
107 * case you must call resolve() again later).
108 */
110resolve() {
111 if (_reader == nullptr) {
112 return false;
113 }
114
115 return _reader->resolve();
116}
117
118/**
119 * Although the bam file format is general enough to store a list of objects
120 * of arbitrary type, bam files on disk usually contain just one object, a
121 * PandaNode that is the root of a scene graph. (Bam files that store other
122 * kinds of things are usually given the extension "boo", for "binary other
123 * objects", to differentiate them from the normal scene graph type file.)
124 *
125 * This is a convenience method for when you believe you are reading a scene
126 * graph bam file. It reads the one PandaNode and returns it. It also calls
127 * resolve() to fully resolve the object, since we expect this will be the
128 * only object in the file.
129 *
130 * If the bam file contains something other than a PandaNode, an error is
131 * printed and NULL is returned.
132 */
133PT(PandaNode) BamFile::
134read_node(bool report_errors) {
135 PT(PandaNode) result;
136
137 TypedWritable *object = read_object();
138
139 if (object != nullptr &&
140 object->is_exact_type(BamCacheRecord::get_class_type())) {
141 // Here's a special case: if the first object in the file is a
142 // BamCacheRecord, it's really a cache data file and not a true bam file;
143 // but skip over the cache data record and let the user treat it like an
144 // ordinary bam file.
145 object = read_object();
146 }
147
148 if (object == TypedWritable::Null) {
149 if (report_errors) {
150 loader_cat.error() << "Bam file " << _bam_filename << " is empty.\n";
151 }
152
153 } else if (!object->is_of_type(PandaNode::get_class_type())) {
154 if (report_errors) {
155 loader_cat.error()
156 << "Bam file " << _bam_filename
157 << " contains a " << object->get_type() << ", not a PandaNode.\n";
158 }
159
160 } else {
161 result = DCAST(PandaNode, object);
162
163 if (report_errors) {
164 read_object();
165 if (!is_eof()) {
166 loader_cat.warning()
167 << "Ignoring extra objects in " << _bam_filename << "\n";
168 }
169 }
170 }
171
172 if (!resolve()) {
173 if (report_errors) {
174 loader_cat.error()
175 << "Unable to resolve Bam file.\n";
176 }
177 result = nullptr;
178 }
179
180 return result;
181}
182
183
184/**
185 * Attempts to open the indicated file for writing. If another file by the
186 * same name already exists, it will be silently removed. Returns true if
187 * successful, false otherwise.
188 */
190open_write(const Filename &bam_filename, bool report_errors) {
191 close();
192
194 vfs->delete_file(bam_filename);
195 if (!_dout.open(bam_filename)) {
196 if (report_errors) {
197 loader_cat.error() << "Unable to open " << bam_filename << "\n";
198 }
199 return false;
200 }
201
202 return continue_open_write(bam_filename, report_errors);
203}
204
205/**
206 * Attempts to open the indicated stream for writing. The filename is just
207 * for information purposes only. Returns true if successful, false on error.
208 */
210open_write(std::ostream &out, const string &bam_filename, bool report_errors) {
211 close();
212
213 if (!_dout.open(out)) {
214 loader_cat.error() << "Could not write bam: " << bam_filename << "\n";
215 return false;
216 }
217
218 return continue_open_write(bam_filename, report_errors);
219}
220
221/**
222 * Writes the indicated object to the Bam file. Returns true if successful,
223 * false on error.
224 */
226write_object(const TypedWritable *object) {
227 if (_writer == nullptr) {
228 return false;
229 }
230
231 if (!_writer->write_object(object)) {
232 close();
233 return false;
234 }
235
236 return true;
237}
238
239/**
240 * Closes the input or output stream.
241 */
243close() {
244 if (_reader != nullptr) {
245 // resolve();
246 delete _reader;
247 _reader = nullptr;
248 }
249 if (_writer != nullptr) {
250 delete _writer;
251 _writer = nullptr;
252 }
253 _din.close();
254 _dout.close();
255}
256
257
258/**
259 * Returns the major version number of the file currently being read, or the
260 * system current major version number if no file is currently open for
261 * reading.
262 */
265 if (_reader == nullptr) {
266 return _bam_major_ver;
267 }
268 return _reader->get_file_major_ver();
269}
270
271/**
272 * Returns the minor version number of the file currently being read, or the
273 * system current minor version number if no file is currently open for
274 * reading.
275 */
278 if (_reader == nullptr) {
279 return _bam_minor_ver;
280 }
281 return _reader->get_file_minor_ver();
282}
283
284/**
285 * Returns the endian preference indicated by the Bam file currently being
286 * read or written.
287 */
289get_file_endian() const {
290 if (_writer != nullptr) {
291 return _writer->get_file_endian();
292 }
293 if (_reader != nullptr) {
294 return _reader->get_file_endian();
295 }
296
297 return bam_endian;
298}
299
300/**
301 * Returns true if the file stores all "standard" floats as 64-bit doubles, or
302 * false if they are 32-bit floats.
303 */
304bool BamFile::
306 if (_writer != nullptr) {
307 return _writer->get_file_stdfloat_double();
308 }
309 if (_reader != nullptr) {
310 return _reader->get_file_stdfloat_double();
311 }
312
313 return bam_stdfloat_double;
314}
315
316/**
317 * Returns the system current major version number. This is the version
318 * number that will be assigned to any generated Bam files.
319 */
322 return _bam_major_ver;
323}
324
325/**
326 * Returns the system current minor version number. This is the version
327 * number that will be assigned to any generated Bam files.
328 */
331 return _bam_minor_ver;
332}
333
334/**
335 * Returns the BamReader in charge of performing the read operations. This
336 * will return NULL unless open_read() was called.
337 */
339get_reader() {
340 return _reader;
341}
342
343/**
344 * Returns the BamWriter in charge of performing the write operations. This
345 * will return NULL unless open_write() was called.
346 */
348get_writer() {
349 return _writer;
350}
351
352/**
353 * Reads the header of the recently-opened bam stream and prepares to read the
354 * contents of the file. Returns true if successful, false otherwise.
355 */
356bool BamFile::
357continue_open_read(const string &bam_filename, bool report_errors) {
358 _bam_filename = bam_filename;
359
360 if (!_bam_filename.empty()) {
361 loader_cat.info()
362 << "Reading " << _bam_filename << "\n";
363 }
364
365 string head;
366 if (!_din.read_header(head, _bam_header.size())) {
367 if (report_errors) {
368 loader_cat.error() << _bam_filename << " is not a valid BAM file.\n";
369 }
370 return false;
371 }
372
373 if (head != _bam_header) {
374 if (report_errors) {
375 loader_cat.error() << _bam_filename << " is not a valid BAM file.\n";
376 }
377 return false;
378 }
379
380 _reader = new BamReader(&_din);
381 if (!_reader->init()) {
382 close();
383 return false;
384 }
385
386 return true;
387}
388
389/**
390 * Writers the header of the recently-opened bam stream and prepares to write
391 * the contents of the file. Returns true if successful, false otherwise.
392 */
393bool BamFile::
394continue_open_write(const string &bam_filename, bool report_errors) {
395 _bam_filename = bam_filename;
396
397 if (!_bam_filename.empty()) {
398 loader_cat.info() << "Writing " << _bam_filename << "\n";
399 }
400
401 if (!_dout.write_header(_bam_header)) {
402 if (report_errors) {
403 loader_cat.error() << "Unable to write to " << _bam_filename << "\n";
404 }
405 return false;
406 }
407
408 _writer = new BamWriter(&_dout);
409
410 if (!_writer->init()) {
411 close();
412 return false;
413 }
414
415 return true;
416}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BamEndian
This defines an enumerated type used to represent the endianness of certain numeric values stored in ...
Definition bamEnums.h:32
get_file_stdfloat_double
Returns true if the file stores all "standard" floats as 64-bit doubles, or false if they are 32-bit ...
Definition bamFile.h:83
int get_current_major_ver()
Returns the system current major version number.
Definition bamFile.cxx:321
void close()
Closes the input or output stream.
Definition bamFile.cxx:243
int get_current_minor_ver()
Returns the system current minor version number.
Definition bamFile.cxx:330
int get_file_minor_ver()
Returns the minor version number of the file currently being read, or the system current minor versio...
Definition bamFile.cxx:277
bool open_write(const Filename &bam_filename, bool report_errors=true)
Attempts to open the indicated file for writing.
Definition bamFile.cxx:190
TypedWritable * read_object()
Reads and returns the next object from the Bam file, or NULL if the end of the file has been reached,...
Definition bamFile.cxx:85
int get_file_major_ver()
Returns the major version number of the file currently being read, or the system current major versio...
Definition bamFile.cxx:264
get_file_endian
Returns the endian preference indicated by the Bam file currently being read or written.
Definition bamFile.h:82
bool open_read(const Filename &bam_filename, bool report_errors=true)
Attempts to open the indicated filename for reading.
Definition bamFile.cxx:51
get_writer
Returns the BamWriter in charge of performing the write operations.
Definition bamFile.h:86
get_reader
Returns the BamReader in charge of performing the read operations.
Definition bamFile.h:85
bool resolve()
This must be called after one or more objects have been read via calls to read_object() in order to r...
Definition bamFile.cxx:110
bool is_eof() const
Returns true if the reader has reached end-of-file, false otherwise.
Definition bamFile.cxx:98
bool write_object(const TypedWritable *object)
Writes the indicated object to the Bam file.
Definition bamFile.cxx:226
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition bamReader.h:110
bool is_eof() const
Returns true if the reader has reached end-of-file, false otherwise.
Definition bamReader.I:66
get_file_stdfloat_double
Returns true if the file stores all "standard" floats as 64-bit doubles, or false if they are 32-bit ...
Definition bamReader.h:160
bool resolve()
This may be called at any time during processing of the Bam file to resolve all the known pointers so...
int get_file_major_ver() const
Returns the major version number of the Bam file currently being read.
Definition bamReader.I:75
bool init()
Initializes the BamReader prior to reading any objects from its source.
Definition bamReader.cxx:85
TypedWritable * read_object()
Reads a single object from the Bam file.
int get_file_minor_ver() const
Returns the minor version number of the Bam file currently being read.
Definition bamReader.I:83
get_file_endian
Returns the endian preference indicated by the Bam file currently being read.
Definition bamReader.h:159
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition bamWriter.h:63
get_file_endian
Returns the endian preference indicated by the Bam file currently being written.
Definition bamWriter.h:97
bool write_object(const TypedWritable *obj)
Writes a single object to the Bam file, so that the BamReader::read_object() can later correctly rest...
bool init()
Initializes the BamWriter prior to writing any objects to its output stream.
get_file_stdfloat_double
Returns true if the file will store all "standard" floats as 64-bit doubles, or false if they are 32-...
Definition bamWriter.h:98
bool read_header(std::string &header, size_t num_bytes)
Reads a sequence of bytes from the beginning of the datagram file.
void close()
Closes the file.
bool open(const FileReference *file)
Opens the indicated filename for reading.
bool open(const FileReference *file)
Opens the indicated filename for writing.
bool write_header(const vector_uchar &header)
Writes a sequence of bytes to the beginning of the datagram file.
void close()
Closes the file.
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
A basic node of the scene graph or data graph.
Definition pandaNode.h:65
bool is_exact_type(TypeHandle handle) const
Returns true if the current object is the indicated type exactly.
Definition typedObject.I:38
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition typedObject.I:28
Base class for objects that can be written to and read from Bam files.
A hierarchy of directories and files that appears to be one continuous file system,...
bool delete_file(const Filename &filename)
Attempts to delete the indicated file or directory.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.