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