16 #include "xParserDefs.h" 17 #include "xLexerDefs.h" 18 #include "xFileTemplate.h" 19 #include "xFileDataNodeTemplate.h" 20 #include "config_xfile.h" 21 #include "standard_templates.h" 23 #include "virtualFileSystem.h" 27 PT(
XFile) XFile::_standard_templates;
35 XFile(
bool keep_names) :
XFileNode(this,
"") {
38 _format_type = FT_text;
40 _keep_names = keep_names;
63 _nodes_by_guid.clear();
83 if (in == (istream *)NULL) {
85 <<
"Cannot open " << filename <<
" for reading.\n";
88 bool okflag =
read(*in, filename);
110 read(istream &in,
const string &filename) {
111 if (!read_header(in)) {
115 if (_format_type != FT_text) {
119 <<
"Cannot read binary .x files at this time.\n";
126 get_standard_templates();
128 x_init_parser(in, filename, *
this);
132 return (x_error_count() == 0);
156 <<
"Can't open " << filename <<
" for output.\n";
164 OCompressStream compressor(&out,
false);
165 return write(compressor);
183 if (!write_header(out)) {
201 const XFile *standard_templates = get_standard_templates();
202 if (standard_templates !=
this) {
208 child->
is_of_type(XFileTemplate::get_class_type())) {
232 const XFile *standard_templates = get_standard_templates();
233 if (standard_templates !=
this) {
237 NodesByGuid::const_iterator gi;
238 gi = _nodes_by_guid.find(guid);
239 if (gi != _nodes_by_guid.end() &&
240 (*gi).second->is_of_type(XFileTemplate::get_class_type())) {
263 const XFile *standard_templates = get_standard_templates();
275 const XFile *standard_templates = get_standard_templates();
289 child->
is_of_type(XFileDataNodeTemplate::get_class_type())) {
304 NodesByGuid::const_iterator gi;
305 gi = _nodes_by_guid.find(guid);
306 if (gi != _nodes_by_guid.end() &&
307 (*gi).second->is_of_type(XFileDataNodeTemplate::get_class_type())) {
322 Children::const_iterator ci;
323 for (ci = _children.begin(); ci != _children.end(); ++ci) {
324 (*ci)->write_text(out, indent_level);
336 read_header(istream &in) {
338 if (!in.read(magic, 4)) {
344 if (memcmp(magic,
"xof ", 4) != 0) {
346 <<
"Not a DirectX file.\n";
351 if (!in.read(version, 4)) {
353 <<
"Truncated file.\n";
356 _major_version = (version[0] -
'0') * 10 + (version[1] -
'0');
357 _minor_version = (version[2] -
'0') * 10 + (version[3] -
'0');
360 if (!in.read(format, 4)) {
362 <<
"Truncated file.\n";
366 if (memcmp(format,
"txt ", 4) == 0) {
367 _format_type = FT_text;
369 }
else if (memcmp(format,
"bin ", 4) == 0) {
370 _format_type = FT_binary;
372 }
else if (memcmp(format,
"com ", 4) == 0) {
373 _format_type = FT_compressed;
377 <<
"Unknown format type: " << string(format, 4) <<
"\n";
381 if (_format_type == FT_compressed) {
384 char compression_type[4];
385 in.read(compression_type, 4);
389 if (!in.read(float_size, 4)) {
391 <<
"Truncated file.\n";
395 if (memcmp(float_size,
"0032", 4) == 0) {
398 }
else if (memcmp(float_size,
"0064", 4) == 0) {
403 <<
"Unknown float size: " << string(float_size, 4) <<
"\n";
417 write_header(ostream &out)
const {
418 out.write(
"xof ", 4);
421 sprintf(buffer,
"%02d%02d", _major_version, _minor_version);
422 if (strlen(buffer) != 4) {
424 <<
"Invalid version: " << _major_version <<
"." << _minor_version
429 out.write(buffer, 4);
431 switch (_format_type) {
433 out.write(
"txt ", 4);
437 out.write(
"bin ", 4);
441 out.write(
"cmp ", 4);
446 <<
"Invalid format type: " << _format_type <<
"\n";
450 if (_format_type == FT_compressed) {
452 out.write(
"xxx ", 4);
455 switch (_float_size) {
457 out.write(
"0032", 4);
461 out.write(
"0064", 4);
466 <<
"Invalid float size: " << _float_size <<
"\n";
470 if (_format_type == FT_text) {
486 get_standard_templates() {
487 if (_standard_templates == (
XFile *)NULL) {
491 string data((
const char *)standard_templates_data, standard_templates_data_len);
496 IDecompressStream in(&inz,
false);
503 _standard_templates =
new XFile;
504 if (!_standard_templates->read(in,
"standardTemplates.x")) {
506 <<
"Internal error: Unable to parse built-in standardTemplates.x!\n";
510 for (
int i = 0; i < _standard_templates->get_num_children(); i++) {
512 if (child->
is_of_type(XFileTemplate::get_class_type())) {
514 xtemplate->_is_standard =
true;
519 return _standard_templates;
bool open_write(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 ...
virtual void clear()
Removes all of the classes defined within the XFile and prepares it for reading a new file...
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS's file system.
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...
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...
string get_extension() const
Returns the file extension.
static XFileTemplate * find_standard_template(const string &name)
Returns the standard template associated with the indicated name, if any, or NULL if none...
static void close_read_file(istream *stream)
Closes a file opened by a previous call to open_read_file().
This is a node which contains all of the data elements defined by a template.
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...
The name of a file, such as a texture file or an Egg file.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
bool read(Filename filename)
Opens and reads the indicated .x file by name.
XFileDataNodeTemplate * find_data_object(const string &name) const
Returns the data object associated with the indicated name, if any, or NULL if none.
XFileNode * find_child(const 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. ...
virtual void write_text(ostream &out, int indent_level) const
Writes a suitable representation of this node to an .x file in text mode.
This represents the complete contents of an X file (file.x) in memory.
XFileTemplate * find_template(const string &name) const
Returns the template associated with the indicated name, if any, or NULL if none. ...
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
XFileNode * find_descendent(const string &name) const
Returns the first child or descendent found with the indicated name after a depth-first search...
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.