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);
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())) {
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;
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
bool open_write(std::ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
virtual bool matches(const XFileNode *other) const
Returns true if the node, particularly a template node, is structurally equivalent to the other node ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
virtual void clear()
Removes all of the classes defined within the XFile and prepares it for reading a new file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A hierarchy of directories and files that appears to be one continuous file system,...
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,...
XFileTemplate * find_template(const std::string &name) const
Returns the template associated with the indicated name, if any, or NULL if none.
void set_binary()
Indicates that the filename represents a binary file.
void set_text()
Indicates that the filename represents a text file.
This is an implementation of the Windows GUID object, used everywhere as a world-unique identifier fo...
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 is a node which contains all of the data elements defined by a template.
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
A single node of an X file.
bool write(Filename filename) const
Opens the indicated filename for output and writes a parseable description of all the known distribut...
static XFileTemplate * find_standard_template(const std::string &name)
Returns the standard template associated with the indicated name, if any, or NULL if none.
The name of a file, such as a texture file or an Egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
bool read(Filename filename)
Opens and reads the indicated .x file by name.
std::string get_extension() const
Returns the file extension.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
XFileNode * find_descendent(const std::string &name) const
Returns the first child or descendent found with the indicated name after a depth-first search,...
XFileNode * find_child(const std::string &name) const
Returns the child 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.
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.
This represents the complete contents of an X file (file.x) in memory.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
A template definition in the X file.
TypeHandle is the identifier used to differentiate C++ class types.
XFileNode * get_child(int n) const
Returns the nth child of this node.