OpenWalnut  1.4.0
WProjectFileIO.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WPROJECTFILEIO_H
00026 #define WPROJECTFILEIO_H
00027 
00028 #include <ostream>
00029 #include <string>
00030 #include <vector>
00031 
00032 #include <boost/shared_ptr.hpp>
00033 
00034 #include "WProperties.h"
00035 
00036 class WProjectFile;
00037 
00038 /**
00039  * A base class for all parts of OpenWalnut which can be serialized to a project file. It is used by WProjectFile to actually parse the file line
00040  * by line. Derive from this class if you write your own parser and use it to fill your internal data structures. But write it in a very
00041  * error-tolerant way. We want to avoid that small problems in the project file cause the whole file to be useless.
00042  *
00043  * In general, each IO implementation has the chance to parse each line. After parsing all lines, the done method gets called. This method should
00044  * contain code to actually apply the settings loaded. You should avoid doing this in the parse method itself.
00045  */
00046 class WProjectFileIO // NOLINT
00047 {
00048 public:
00049     /**
00050      * Abbreviation for a shared pointer.
00051      */
00052     typedef boost::shared_ptr< WProjectFileIO > SPtr;
00053 
00054     /**
00055      * Abbreviation for const shared pointer.
00056      */
00057     typedef boost::shared_ptr< const WProjectFileIO > ConstSPtr;
00058 
00059     /**
00060      * Default constructor.
00061      */
00062     WProjectFileIO();
00063 
00064     /**
00065      * Destructor.
00066      */
00067     virtual ~WProjectFileIO();
00068 
00069     /**
00070      * This method parses the specified line and interprets it. It gets called line by line by WProjectFile. You should avoid applying anything
00071      * of the loaded information here. You should use \ref done for this.
00072      *
00073      * \param line the current line as string
00074      * \param lineNumber the current line number. Useful for error/warning/debugging output.
00075      *
00076      * \return true if the line could be parsed.
00077      */
00078     virtual bool parse( std::string line, unsigned int lineNumber ) = 0;
00079 
00080     /**
00081      * Called whenever the end of the project file has been reached. Use this to actually apply your loaded settings. Do this in a error-tolerant
00082      * way and apply as most settings as possible even if some other settings are erroneous. Add errors with \ref addError. Try avoiding
00083      * exceptions if possible.
00084      */
00085     virtual void done();
00086 
00087     /**
00088      * Saves the state to the specified stream.
00089      *
00090      * \param output the stream to print the state to.
00091      */
00092     virtual void save( std::ostream& output ) = 0;   // NOLINT
00093 
00094     /**
00095      * Checks whether there where errors during load or save.
00096      *
00097      * \return true if there where.
00098      */
00099     bool hadErrors() const;
00100 
00101     /**
00102      * Get error list.
00103      *
00104      * \return the list
00105      */
00106     const std::vector< std::string >& getErrors() const;
00107 
00108     /**
00109      * Checks whether there where warnings during load or save.
00110      *
00111      * \return true if there where.
00112      */
00113     bool hadWarnings() const;
00114 
00115     /**
00116      * Get warnings list.
00117      *
00118      * \return the list
00119      */
00120     const std::vector< std::string >& getWarnings() const;
00121 
00122     /**
00123      * Create a clone of the IO. This is especially useful for custom parsers registered at \ref WProjectFile::registerParser. Implement this
00124      * function.
00125      *
00126      * \param project the project file using this parser instance.
00127      *
00128      * \return Cloned instance.
00129      */
00130     virtual SPtr clone( WProjectFile* project ) const = 0;
00131 
00132     /**
00133      * Set the project using this parser
00134      *
00135      * \param project the project
00136      */
00137     void setProject( WProjectFile* project );
00138 
00139     /**
00140      * When to apply this parser. This might be important in some cases. Note that you can only decide
00141      * whether you want to apply your changes before or after the modules have been added.
00142      */
00143     enum ApplyOrder
00144     {
00145         PRE_MODULES = 0,
00146         POST_MODULES
00147     };
00148 
00149     /**
00150      * Return the apply order of this IO.
00151      *
00152      * \return the order
00153      */
00154     ApplyOrder getApplyOrder() const;
00155 
00156 protected:
00157     /**
00158      * Add an error. Use this when you encounter some difficulties during parsing or applying settings. Provide useful errors. They will be
00159      * presented to the user.
00160      *
00161      * \param description the error description
00162      */
00163     void addError( std::string description );
00164 
00165     /**
00166      * Add an warning. Use this when you encounter some difficulties during parsing or applying settings. Provide useful warnings. They will be
00167      * presented to the user.
00168      *
00169      * \param description the error description
00170      */
00171     void addWarning( std::string description );
00172 
00173     /**
00174      * Recursively prints the properties and nested properties.
00175      *
00176      * \param output    the output stream to print to
00177      * \param props     the properties to recursively print
00178      * \param indent    the indentation level
00179      * \param prefix    the prefix (name prefix of property)
00180      * \param index     the ID to use
00181      * \param indexPrefix use this to add a prefix to the index
00182      */
00183     void printProperties( std::ostream& output, boost::shared_ptr< WProperties > props, std::string indent, //NOLINT ( non-const ref )
00184                           std::string prefix, unsigned int index, std::string indexPrefix = "" );
00185 
00186 
00187     /**
00188      * Set the order of calls to "done".
00189      *
00190      * \param order the order.
00191      */
00192     void setApplyOrder( ApplyOrder order );
00193 
00194     /**
00195      * The project using this parser.
00196      *
00197      * \return the project
00198      */
00199     WProjectFile* getProject() const;
00200 
00201 private:
00202     /**
00203      * List of errors if any.
00204      */
00205     std::vector< std::string > m_errors;
00206 
00207     /**
00208      * List of warnings if any.
00209      */
00210     std::vector< std::string > m_warnings;
00211 
00212     /**
00213      * The project using this parser
00214      */
00215     WProjectFile* m_project;
00216 
00217     /**
00218      * The order in which the "done" functions are called.
00219      */
00220     ApplyOrder m_applyOrder;
00221 };
00222 
00223 #endif  // WPROJECTFILEIO_H
00224