Go to the documentation of this file.
26 using std::istringstream;
31 PT(
XFile) XFile::_standard_templates;
37 XFile(
bool keep_names) :
XFileNode(this) {
40 _format_type = FT_text;
42 _keep_names = keep_names;
61 _nodes_by_guid.clear();
79 <<
"Cannot open " << filename <<
" for reading.\n";
82 bool okflag =
read(*in, filename);
98 read(istream &in,
const string &filename) {
99 if (!read_header(in)) {
103 if (_format_type != FT_text) {
107 <<
"Cannot read binary .x files at this time.\n";
114 get_standard_templates();
116 x_init_parser(in, filename, *
this);
120 return (x_error_count() == 0);
140 <<
"Can't open " << filename <<
" for output.\n";
148 OCompressStream compressor(&out,
false);
149 return write(compressor);
163 write(ostream &out)
const {
164 if (!write_header(out)) {
180 const XFile *standard_templates = get_standard_templates();
181 if (standard_templates !=
this) {
186 if (child !=
nullptr &&
187 child->
is_of_type(XFileTemplate::get_class_type())) {
189 if (standard !=
nullptr && xtemplate->
matches(standard)) {
209 const XFile *standard_templates = get_standard_templates();
210 if (standard_templates !=
this) {
214 NodesByGuid::const_iterator gi;
215 gi = _nodes_by_guid.find(guid);
216 if (gi != _nodes_by_guid.end() &&
217 (*gi).second->is_of_type(XFileTemplate::get_class_type())) {
219 if (standard !=
nullptr && xtemplate->
matches(standard)) {
238 const XFile *standard_templates = get_standard_templates();
248 const XFile *standard_templates = get_standard_templates();
259 if (child !=
nullptr &&
260 child->
is_of_type(XFileDataNodeTemplate::get_class_type())) {
273 NodesByGuid::const_iterator gi;
274 gi = _nodes_by_guid.find(guid);
275 if (gi != _nodes_by_guid.end() &&
276 (*gi).second->is_of_type(XFileDataNodeTemplate::get_class_type())) {
287 write_text(ostream &out,
int indent_level)
const {
288 Children::const_iterator ci;
289 for (ci = _children.begin(); ci != _children.end(); ++ci) {
290 (*ci)->write_text(out, indent_level);
300 read_header(istream &in) {
302 if (!in.read(magic, 4)) {
308 if (memcmp(magic,
"xof ", 4) != 0) {
310 <<
"Not a DirectX file.\n";
315 if (!in.read(version, 4)) {
317 <<
"Truncated file.\n";
320 _major_version = (version[0] -
'0') * 10 + (version[1] -
'0');
321 _minor_version = (version[2] -
'0') * 10 + (version[3] -
'0');
324 if (!in.read(format, 4)) {
326 <<
"Truncated file.\n";
330 if (memcmp(format,
"txt ", 4) == 0) {
331 _format_type = FT_text;
333 }
else if (memcmp(format,
"bin ", 4) == 0) {
334 _format_type = FT_binary;
336 }
else if (memcmp(format,
"com ", 4) == 0) {
337 _format_type = FT_compressed;
341 <<
"Unknown format type: " << string(format, 4) <<
"\n";
345 if (_format_type == FT_compressed) {
348 char compression_type[4];
349 in.read(compression_type, 4);
353 if (!in.read(float_size, 4)) {
355 <<
"Truncated file.\n";
359 if (memcmp(float_size,
"0032", 4) == 0) {
362 }
else if (memcmp(float_size,
"0064", 4) == 0) {
367 <<
"Unknown float size: " << string(float_size, 4) <<
"\n";
379 write_header(ostream &out)
const {
380 out.write(
"xof ", 4);
383 sprintf(buffer,
"%02d%02d", _major_version, _minor_version);
384 if (strlen(buffer) != 4) {
386 <<
"Invalid version: " << _major_version <<
"." << _minor_version
391 out.write(buffer, 4);
393 switch (_format_type) {
395 out.write(
"txt ", 4);
399 out.write(
"bin ", 4);
403 out.write(
"cmp ", 4);
408 <<
"Invalid format type: " << _format_type <<
"\n";
412 if (_format_type == FT_compressed) {
414 out.write(
"xxx ", 4);
417 switch (_float_size) {
419 out.write(
"0032", 4);
423 out.write(
"0064", 4);
428 <<
"Invalid float size: " << _float_size <<
"\n";
432 if (_format_type == FT_text) {
445 get_standard_templates() {
446 if (_standard_templates ==
nullptr) {
450 string data((
const char *)standard_templates_data, standard_templates_data_len);
454 istringstream inz(data);
455 IDecompressStream in(&inz,
false);
459 istringstream in(data);
462 _standard_templates =
new XFile;
463 if (!_standard_templates->read(in,
"standardTemplates.x")) {
465 <<
"Internal error: Unable to parse built-in standardTemplates.x!\n";
469 for (
int i = 0; i < _standard_templates->get_num_children(); i++) {
471 if (child->
is_of_type(XFileTemplate::get_class_type())) {
473 xtemplate->_is_standard =
true;
478 return _standard_templates;
void set_text()
Indicates that the filename represents a text file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileNode * find_child(const std::string &name) const
Returns the child with the indicated name, if any, or NULL if none.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
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.
This represents the complete contents of an X file (file.x) in memory.
XFileNode * get_child(int n) const
Returns the nth child of this node.
A single node of an X file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileTemplate * find_template(const std::string &name) const
Returns the template associated with the indicated name, if any, or NULL if none.
virtual void clear()
Removes all children from the node, and otherwise resets it to its initial state.
TypeHandle is the identifier used to differentiate C++ class types.
A template definition in the X file.
A hierarchy of directories and files that appears to be one continuous file system,...
bool write(Filename filename) const
Opens the indicated filename for output and writes a parseable description of all the known distribut...
This is a node which contains all of the data elements defined by a template.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileDataNodeTemplate * find_data_object(const std::string &name) const
Returns the data object associated with the indicated name, if any, or NULL if none.
static XFileTemplate * find_standard_template(const std::string &name)
Returns the standard template associated with the indicated name, if any, or NULL if none.
bool read(Filename filename)
Opens and reads the indicated .x file by name.
XFileNode * find_descendent(const std::string &name) const
Returns the first child or descendent found with the indicated name after a depth-first search,...
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual bool matches(const XFileNode *other) const
Returns true if the node, particularly a template node, is structurally equivalent to the other node ...
std::istream * open_read_file(const Filename &filename, bool auto_unwrap) const
Convenience function; returns a newly allocated istream if the file exists and can be read,...
std::string get_extension() const
Returns the file extension.
This is an implementation of the Windows GUID object, used everywhere as a world-unique identifier fo...
The name of a file, such as a texture file or an Egg file.
virtual void write_text(std::ostream &out, int indent_level) const
Writes a suitable representation of this node to an .x file in text mode.
void set_binary()
Indicates that the filename represents a binary file.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
virtual void clear()
Removes all of the classes defined within the XFile and prepares it for reading a new file.