ofstd/include/dcmtk/ofstd/ofconfig.h

00001 /*
00002  *
00003  *  Copyright (C) 1997-2010, OFFIS e.V.
00004  *  All rights reserved.  See COPYRIGHT file for details.
00005  *
00006  *  This software and supporting documentation were developed by
00007  *
00008  *    OFFIS e.V.
00009  *    R&D Division Health
00010  *    Escherweg 2
00011  *    D-26121 Oldenburg, Germany
00012  *
00013  *
00014  *  Module:  ofstd
00015  *
00016  *  Author: Marco Eichelberg
00017  *
00018  *  Purpose:
00019  *    classes: OFConfigFile
00020  *
00021  *  Last Update:      $Author: joergr $
00022  *  Update Date:      $Date: 2010-10-14 13:15:50 $
00023  *  CVS/RCS Revision: $Revision: 1.8 $
00024  *  Status:           $State: Exp $
00025  *
00026  *  CVS/RCS Log at end of file
00027  *
00028  */
00029 
00030 #ifndef OFCONFIG_H
00031 #define OFCONFIG_H
00032 
00033 #include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
00034 #include "dcmtk/ofstd/ofstring.h"
00035 #include "dcmtk/ofstd/ofstack.h"
00036 #include "dcmtk/ofstd/ofstream.h"
00037 
00038 #define INCLUDE_CSTDIO
00039 #include "dcmtk/ofstd/ofstdinc.h"
00040 
00041 /*
00042  *  Short description of configuration file structure:
00043  *    - The data in a configuration file have a tree structure.
00044  *      The tree has a depth defined at instantiation time (by default, OFConfigFile_MaxLevel), 
00045  *      not including the (imaginary) root node.
00046  *    - A level 0 entry (a leaf) has the form: KEYWORD = VALUE,
00047  *      where the keyword starts on row one of a line.
00048  *    - A level 1 entry has the form [KEYWORD]
00049  *    - A level 2 entry has the form [[KEYWORD]] (and so on).
00050  *    - Keywords may consist of:
00051  *        A..Z, a..z (which are converted to uppercase),
00052  *        0..9,
00053  *        '-'
00054  *    - Values can be any kind of ASCII text. Values may span multiple lines.
00055  *      To continue a value in the next line, the next line MUST start with
00056  *      (any amount of) whitespace, which is discarded when reading the value.
00057  *      linefeeds (converted to ASCII 10 if necessary) are kept in the
00058  *      value string. Empty lines are discarded (and also their linefeed).
00059  *    - The data must have a "clean" tree structure. This means that there
00060  *      MUST be a level 2 keyword before any level 1 keyword etc.
00061  *    - lines starting with the comment char (default  is "#") are interpreted 
00062  *      as comment lines.
00063  *
00064  */
00065 
00066 #define OFConfigFile_MaxLevel 2
00067 #define OFConfigFile_CommentChar '#'
00068 
00069 class OFConfigFile;
00070 class OFConfigFileNode;
00071 
00072 typedef OFConfigFileNode *OFPConfigFileNode;
00073 
00074 
00079 class OFConfigFileNode
00080 {
00081 public:
00085   OFConfigFileNode(const char *keyword);
00086 
00088   ~OFConfigFileNode();
00089 
00092   const char *getKeyword() const
00093   {
00094     return keyword_.c_str();
00095   }
00096 
00099   const char *getValue() const
00100   {
00101     return value_.c_str();
00102   }
00103 
00107   void setValue(const char *c)
00108   {
00109     value_ = c;
00110   }
00111 
00116   OFBool match(const char *c) const
00117   {
00118     return (keyword_ == c);
00119   }
00120 
00125   OFBool less(const char *c) const
00126   {
00127     return (keyword_ < c);
00128   }
00129 
00133   OFConfigFileNode *getBrother() const
00134   {
00135     return brother_;
00136   }
00137 
00141   OFConfigFileNode *getSon() const
00142   {
00143     return son_;
00144   }
00145 
00149   void setBrother(OFConfigFileNode *brother)
00150   {
00151     brother_ = brother;
00152   }
00153 
00157   void setSon(OFConfigFileNode *son)
00158   {
00159     son_ = son;
00160   }
00161 
00166   void print(STD_NAMESPACE ostream& out, unsigned int level);
00167 
00168 private:
00170   OFConfigFileNode(const OFConfigFileNode& arg);
00171 
00173   OFConfigFileNode &operator=(const OFConfigFileNode& arg);
00174 
00176   OFConfigFileNode *brother_;
00177 
00179   OFConfigFileNode *son_;
00180 
00182   OFString keyword_;
00183 
00185   OFString value_;
00186 };
00187 
00189 typedef OFConfigFileNode *OFConfigFileNodePtr;
00190 
00194 class OFConfigFileCursor
00195 {
00196 public:
00199   OFConfigFileCursor(unsigned int maxLevel) 
00200   : array_(NULL)
00201   , maxLevel_(maxLevel)
00202   { 
00203     clear(); 
00204   }
00205 
00208   OFConfigFileCursor(const OFConfigFileCursor& source);
00209 
00212   ~OFConfigFileCursor() 
00213   {
00214     delete[] array_;
00215   }
00216 
00219   OFConfigFileCursor& operator=(const OFConfigFileCursor& source);
00220 
00222   void clear();
00223 
00228   const char *getKeyword(unsigned int level) const
00229   {
00230     if ((level <= maxLevel_) && array_ && array_[level]) return array_[level]->getKeyword(); else return NULL;
00231   }
00232 
00237   const char *getValue(unsigned int level) const
00238   {
00239     if ((level <= maxLevel_) && array_ && array_[level]) return array_[level]->getValue(); else return NULL;
00240   }
00241 
00247   OFBool section_valid(unsigned int level) const;
00248 
00259   void set_section(
00260     unsigned int level, 
00261     const char *key,
00262     OFConfigFileNode *anchor);
00263    
00273   void first_section(
00274     unsigned int level,
00275     OFConfigFileNode *anchor);
00276 
00285   void next_section(unsigned int level);
00286 
00294   void insert(
00295     unsigned int level,
00296     OFConfigFileNode *& newnode,
00297     OFConfigFileNode *& anchor,
00298     OFBool orderedMode);
00299 
00303   OFBool operator<(const OFConfigFileCursor& /* arg */) const
00304   {
00305     return OFFalse;
00306   }
00307 
00311   OFBool operator==(const OFConfigFileCursor& /* arg */) const
00312   {
00313     return OFTrue;
00314   }
00315 
00316 private:
00317 
00325   void orderedInsert(
00326     OFConfigFileNode *parent,
00327     OFConfigFileNode *&newnode);
00328 
00330   OFConfigFileNodePtr *array_;
00331 
00333   unsigned int maxLevel_;  
00334 };
00335 
00336 
00342 class OFConfigFile
00343 {
00344 public:
00345 
00353   OFConfigFile(
00354     FILE *infile, 
00355     unsigned int maxLevel = OFConfigFile_MaxLevel,
00356     char commentChar = OFConfigFile_CommentChar,
00357     OFBool orderedMode = OFFalse);
00358 
00361   virtual ~OFConfigFile();
00362 
00366   void loadFile(FILE *infile);
00367   
00373   const char *get_keyword(unsigned int level);
00374   
00379   const char *get_value();
00380   
00391   OFBool get_bool_value(OFBool defaultvalue);
00392   
00398   OFBool section_valid(unsigned int level) const
00399   {
00400     return cursor_.section_valid(level);
00401   }
00402   
00412   void set_section(unsigned int level, const char *key)
00413   {
00414     cursor_.set_section(level, key, anchor_);
00415   }
00416    
00425   void first_section(unsigned int level)
00426   {
00427     cursor_.first_section(level, anchor_);
00428   }
00429 
00438   void next_section(unsigned int level)
00439   {
00440     cursor_.next_section(level);
00441   }
00442   
00445   void save_cursor();
00446   
00449   void restore_cursor();
00450   
00459   void select_section(
00460     const char *key1,
00461     const char *key2=NULL,
00462     const char *key3=NULL);
00463   
00469   const char *get_entry(const char *key0);
00470 
00474   void print(STD_NAMESPACE ostream& out);
00475 
00476 private:  
00477 
00484   char read_char(FILE *infile);
00485 
00491   char read_keywordchar(FILE *infile);
00492   
00499   void read_entry(FILE *infile);
00500   
00505   void store_char(char c);
00506 
00509   OFConfigFile(const OFConfigFile&);
00510   
00513   OFConfigFile& operator=(const OFConfigFile&);
00514 
00515 
00517   OFStack<OFConfigFileCursor> stack_;
00518 
00520   OFConfigFileCursor cursor_;
00521 
00523   OFConfigFileNode *anchor_;
00524 
00526   int isnewline_;
00527 
00529   int crfound_;
00530 
00532   char *buffer_;
00533 
00535   size_t bufptr_;
00536 
00538   long bufsize_;
00539 
00541   unsigned int maxLevel_;  
00542 
00544   char commentChar_;
00545   
00555   OFBool orderedMode_;
00556 };
00557 
00558 #endif
00559 
00560 /*
00561  *  $Log: ofconfig.h,v $
00562  *  Revision 1.8  2010-10-14 13:15:50  joergr
00563  *  Updated copyright header. Added reference to COPYRIGHT file.
00564  *
00565  *  Revision 1.7  2010-04-26 12:22:30  uli
00566  *  Fixed a some minor doxygen warnings.
00567  *
00568  *  Revision 1.6  2008-04-16 09:37:27  meichel
00569  *  class OFConfigFile now supports an ordered mode where multiple
00570  *    configuration files can be loaded and can replace entries of other.
00571  *    Also added function to print content of configuration in reloadable format.
00572  *
00573  *  Revision 1.5  2008-04-15 15:46:30  meichel
00574  *  class OFConfigFile now supports flexible tree depths and configurable
00575  *    comment characters and can, therefore, fully replace the equivalent
00576  *    code in module dcmprint.
00577  *
00578  *  Revision 1.4  2005/12/08 16:05:51  meichel
00579  *  Changed include path schema for all DCMTK header files
00580  *
00581  *  Revision 1.3  2003/06/12 13:15:59  joergr
00582  *  Fixed inconsistent API documentation reported by Doxygen.
00583  *
00584  *  Revision 1.2  2003/06/04 12:31:44  meichel
00585  *  Added dummy comparison operators, needed by MSVC5 with STL
00586  *
00587  *  Revision 1.1  2003/04/29 10:14:16  meichel
00588  *  Moved configuration file parser from module dcmpstat to ofstd and renamed
00589  *    class to OFConfigFile. Cleaned up implementation (no more friend declarations).
00590  *
00591  *
00592  */
00593 


Generated on 6 Jan 2011 for OFFIS DCMTK Version 3.6.0 by Doxygen 1.5.1