Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

direct/src/dcparser/dcFile.cxx

Go to the documentation of this file.
00001 // Filename: dcFile.cxx
00002 // Created by:  drose (05Oct00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "dcFile.h"
00020 #include "dcParserDefs.h"
00021 #include "dcLexerDefs.h"
00022 #include "hashGenerator.h"
00023 
00024 #ifdef WITHIN_PANDA
00025 #include "filename.h"
00026 #include "config_express.h"
00027 #include "virtualFileSystem.h"
00028 #endif
00029 
00030 
00031 ////////////////////////////////////////////////////////////////////
00032 //     Function: DCFile::Constructor
00033 //       Access: Published
00034 //  Description:
00035 ////////////////////////////////////////////////////////////////////
00036 DCFile::
00037 DCFile() {
00038 }
00039 
00040 ////////////////////////////////////////////////////////////////////
00041 //     Function: DCFile::Destructor
00042 //       Access: Published
00043 //  Description:
00044 ////////////////////////////////////////////////////////////////////
00045 DCFile::
00046 ~DCFile() {
00047   Classes::iterator ci;
00048   for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
00049     delete (*ci);
00050   }
00051 }
00052 
00053 ////////////////////////////////////////////////////////////////////
00054 //     Function: DCFile::read
00055 //       Access: Published
00056 //  Description: Opens and reads the indicated .dc file by name.  The
00057 //               distributed classes defined in the file will be
00058 //               appended to the set of distributed classes already
00059 //               recorded, if any.
00060 //
00061 //               Returns true if the file is successfully read, false
00062 //               if there was an error (in which case the file might
00063 //               have been partially read).
00064 ////////////////////////////////////////////////////////////////////
00065 bool DCFile::
00066 read(Filename filename) {
00067   ifstream in;
00068 
00069 #ifdef WITHIN_PANDA
00070   filename.set_text();
00071   if (use_vfs) {
00072     VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00073     istream *in = vfs->open_read_file(filename);
00074     if (in == (istream *)NULL) {
00075       cerr << "Cannot open " << filename << " for reading.\n";
00076       return false;
00077     }
00078     bool okflag = read(*in, filename);
00079     delete in;
00080     return okflag;
00081   }
00082   filename.open_read(in);
00083 #else
00084   in.open(filename.c_str());
00085 #endif
00086 
00087   if (!in) {
00088     cerr << "Cannot open " << filename << " for reading.\n";
00089     return false;
00090   }
00091 
00092   return read(in, filename);
00093 }
00094 
00095 ////////////////////////////////////////////////////////////////////
00096 //     Function: DCFile::read
00097 //       Access: Published
00098 //  Description: Parses the already-opened input stream for
00099 //               distributed class descriptions.  The filename
00100 //               parameter is optional and is only used when reporting
00101 //               errors.
00102 //
00103 //               The distributed classes defined in the file will be
00104 //               appended to the set of distributed classes already
00105 //               recorded, if any.
00106 //
00107 //               Returns true if the file is successfully read, false
00108 //               if there was an error (in which case the file might
00109 //               have been partially read).
00110 ////////////////////////////////////////////////////////////////////
00111 bool DCFile::
00112 read(istream &in, const string &filename) {
00113   dc_init_parser(in, filename, *this);
00114   dcyyparse();
00115   dc_cleanup_parser();
00116 
00117   return (dc_error_count() == 0);
00118 }
00119 
00120 ////////////////////////////////////////////////////////////////////
00121 //     Function: DCFile::write
00122 //       Access: Published
00123 //  Description: Opens the indicated filename for output and writes a
00124 //               parseable description of all the known distributed
00125 //               classes to the file.
00126 //
00127 //               Returns true if the description is successfully
00128 //               written, false otherwise.
00129 ////////////////////////////////////////////////////////////////////
00130 bool DCFile::
00131 write(Filename filename) const {
00132   ofstream out;
00133 
00134 #ifdef WITHIN_PANDA
00135   filename.set_text();
00136   filename.open_write(out);
00137 #else
00138   out.open(filename.c_str());
00139 #endif
00140 
00141   if (!out) {
00142     cerr << "Can't open " << filename << " for output.\n";
00143     return false;
00144   }
00145   return write(out, filename);
00146 }
00147 
00148 ////////////////////////////////////////////////////////////////////
00149 //     Function: DCFile::write
00150 //       Access: Published
00151 //  Description: Writes a parseable description of all the known
00152 //               distributed classes to the file.  The filename
00153 //               parameter is optional and is only used when reporting
00154 //               errors.
00155 //
00156 //               Returns true if the description is successfully
00157 //               written, false otherwise.
00158 ////////////////////////////////////////////////////////////////////
00159 bool DCFile::
00160 write(ostream &out, const string &filename) const {
00161   Classes::const_iterator ci;
00162   for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
00163     (*ci)->write(out);
00164     out << "\n";
00165   }
00166 
00167   if (out.fail()) {
00168     cerr << "I/O error writing " << filename << ".\n";
00169     return false;
00170   }
00171 
00172   return true;
00173 }
00174 
00175 ////////////////////////////////////////////////////////////////////
00176 //     Function: DCFile::get_num_classes
00177 //       Access: Published
00178 //  Description: Returns the number of classes read from the .dc
00179 //               file(s).
00180 ////////////////////////////////////////////////////////////////////
00181 int DCFile::
00182 get_num_classes() {
00183   return _classes.size();
00184 }
00185 
00186 ////////////////////////////////////////////////////////////////////
00187 //     Function: DCFile::get_class
00188 //       Access: Published
00189 //  Description: Returns the nth class read from the .dc file(s).
00190 ////////////////////////////////////////////////////////////////////
00191 DCClass *DCFile::
00192 get_class(int n) {
00193   nassertr(n >= 0 && n < (int)_classes.size(), NULL);
00194   return _classes[n];
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: DCFile::get_class_by_name
00199 //       Access: Published
00200 //  Description: Returns the class that has the indicated name, or
00201 //               NULL if there is no such class.
00202 ////////////////////////////////////////////////////////////////////
00203 DCClass *DCFile::
00204 get_class_by_name(const string &name) {
00205   ClassesByName::const_iterator ni;
00206   ni = _classes_by_name.find(name);
00207   if (ni != _classes_by_name.end()) {
00208     return (*ni).second;
00209   }
00210 
00211   return (DCClass *)NULL;
00212 }
00213 
00214 ////////////////////////////////////////////////////////////////////
00215 //     Function: DCFile::get_hash
00216 //       Access: Published
00217 //  Description: Returns a 32-bit hash index associated with this
00218 //               file.  This number is guaranteed to be consistent if
00219 //               the contents of the file have not changed, and it is
00220 //               very likely to be different if the contents of the
00221 //               file do change.
00222 ////////////////////////////////////////////////////////////////////
00223 unsigned long DCFile::
00224 get_hash() const {
00225   HashGenerator hashgen;
00226   generate_hash(hashgen);
00227   return hashgen.get_hash();
00228 }
00229 
00230 ////////////////////////////////////////////////////////////////////
00231 //     Function: DCFile::generate_hash
00232 //       Access: Public, Virtual
00233 //  Description: Accumulates the properties of this file into the
00234 //               hash.
00235 ////////////////////////////////////////////////////////////////////
00236 void DCFile::
00237 generate_hash(HashGenerator &hashgen) const {
00238   hashgen.add_int(_classes.size());
00239   Classes::const_iterator ci;
00240   for (ci = _classes.begin(); ci != _classes.end(); ++ci) {
00241     (*ci)->generate_hash(hashgen);
00242   }
00243 }
00244 
00245 ////////////////////////////////////////////////////////////////////
00246 //     Function: DCFile::add_class
00247 //       Access: Public
00248 //  Description: Adds the newly-allocated distributed class definition
00249 //               to the file.  The DCFile becomes the owner of the
00250 //               pointer and will delete it when it destructs.
00251 //               Returns true if the class is successfully added, or
00252 //               false if there was a name conflict.
00253 ////////////////////////////////////////////////////////////////////
00254 bool DCFile::
00255 add_class(DCClass *dclass) {
00256   bool inserted = _classes_by_name.insert
00257     (ClassesByName::value_type(dclass->_name, dclass)).second;
00258 
00259   if (!inserted) {
00260     return false;
00261   }
00262 
00263   dclass->_number = get_num_classes();
00264   _classes.push_back(dclass);
00265   return true;
00266 }

Generated on Fri May 2 01:37:07 2003 for Direct by doxygen1.3