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

filecontainer.h

00001 #ifndef EDG_WORKLOAD_COMMON_UTILITIES_FILECONTAINER_H
00002 #define EDG_WORKLOAD_COMMON_UTILITIES_FILECONTAINER_H
00003 
00004 #include <unistd.h>
00005 
00006 #include <exception>
00007 #include <iostream>
00008 #include <fstream>
00009 #include <vector>
00010 #include <string>
00011 
00012 #include "edg/workload/common/common_namespace.h"
00013 
00014 /*
00015   Hack to activate wrong filelist dumping...
00016   Remove when no more needed...
00017 */
00018 #define FILELIST_HAS_DEBUG_CODE
00019 
00020 COMMON_NAMESPACE_BEGIN {
00021 
00022 namespace utilities {
00023 
00024 class FileIterator {
00025   inline friend std::ostream &operator<<( std::ostream &os, const FileIterator &fi ) { return fi.write( os ); }
00026   inline friend std::istream &operator>>( std::istream &is, FileIterator &fi ) { return fi.read( is ); }
00027 
00028 public:
00029   FileIterator( std::streamoff prev = 0, std::streamoff next = 0, std::streamoff current = 0 );
00030 
00031   ~FileIterator( void );
00032 
00033   std::ostream &write( std::ostream &os ) const;
00034   std::istream &read( std::istream &is );
00035 
00036   inline std::streamoff position( void ) const { return this->fi_current; }
00037   inline std::streamoff get_prev( void ) const { return this->fi_prev; }
00038   inline std::streamoff get_next( void ) const { return this->fi_next; }
00039   inline FileIterator &set_prev( std::streamoff prev ) { this->fi_prev = prev; return *this; }
00040   inline FileIterator &set_next( std::streamoff next ) { this->fi_next = next; return *this; }
00041   inline FileIterator &set_current( std::streamoff current ) { this->fi_current = current; return *this; }
00042   inline FileIterator &reset( std::streamoff prev = 0, std::streamoff next = 0, std::streamoff current = 0 )
00043   { this->fi_prev = prev; this->fi_next = next; this->fi_current = current; return *this; }
00044 
00045   inline operator bool( void ) const { return this->fi_good; }
00046   inline bool operator!( void ) const { return !this->fi_good; }
00047 
00048   inline static int size( void ) { return fi_s_width; }
00049 
00050 private:
00051   void initialize( void );
00052 
00053   bool             fi_good;
00054   std::streamoff   fi_prev, fi_next, fi_current;
00055 
00056   static int           fi_s_width;
00057   static FileIterator  fi_s_iterator;
00058 };
00059 
00060 class FileContainerError : public std::exception {
00061 public:
00062   enum iostatus_t { unknown = -1, 
00063                     all_good, 
00064                     cannot_open,
00065                     file_closed,
00066                     syntax_error,
00067                     io_error,
00068                     data_error,
00069                     unavailable_position,
00070                     container_modified,
00071                     try_recover,
00072                     unrecoverable_data,
00073                     decrementing_from_zero,
00074                     not_removing_last,
00075                     _last_error
00076   };
00077 
00078   FileContainerError( iostatus_t code = all_good );
00079   FileContainerError( iostatus_t code, const std::string &func, const char *file = NULL, int line = -1 );
00080 
00081   ~FileContainerError( void ) throw();
00082 
00083   std::string string_error( void ) const;
00084   virtual const char *what( void ) const throw();
00085 
00086   inline iostatus_t code( void ) { return this->fce_code; }
00087   inline FileContainerError &set_code( iostatus_t code ) { this->fce_code = code; return *this; }
00088 
00089   static const char *code_to_string( iostatus_t status );
00090 
00091 private:
00092   int                   fce_line;
00093   iostatus_t            fce_code;
00094   std::string           fce_func, fce_file;
00095   mutable std::string   fce_what;
00096 
00097   static const char    *fce_s_errors[];
00098 };
00099 
00100 class FileContainer {
00101 public:
00102   enum filestatus_t { empty        = ' ',
00103                       opened       = '1',
00104                       closed       = '0',
00105                       ae_iterator  = 'a',
00106                       ae_limits,
00107                       ae_writing,
00108                       ae_written,
00109                       ab_iterator,
00110                       ab_writing,
00111                       ab_written,
00112                       ab_last,
00113                       ab_limits,
00114                       am_iterator1,
00115                       am_iterator2,
00116                       am_writing,
00117                       am_written,
00118                       am_last,
00119                       rd_limits,
00120                       rd_iterator,
00121                       rd_iterator2,
00122                       rd_iterator3,
00123                       rd_mark1,
00124                       rd_mark2,
00125                       ft_begin,
00126                       ft_end,        /* 'v' */
00127                       ad_empty,
00128                       rd_empty       /* 'x' */
00129   };
00130 
00131   typedef FileContainerError::iostatus_t iostatus_t;
00132 
00133   FileContainer( void );
00134   FileContainer( const char *filename );
00135 
00136   ~FileContainer( void );
00137 
00138   iostatus_t open( const char *filename );
00139   FileContainer &close( void );
00140 
00141   iostatus_t add_data( const std::string &data, std::streamoff where, FileIterator &it );
00142   iostatus_t read_data( std::string &data, std::streamoff where, FileIterator &it, bool fileorder = false );
00143   iostatus_t remove_data( std::streamoff where );
00144   iostatus_t recover_data( filestatus_t status = closed, bool check = true );
00145   iostatus_t increment_iterator( FileIterator &it );
00146   iostatus_t decrement_iterator( FileIterator &it );
00147   iostatus_t increment_fileorder_iterator( FileIterator &it );
00148   iostatus_t decrement_fileorder_iterator( FileIterator &it );
00149   iostatus_t truncate( void );
00150   iostatus_t read_size( size_t &size );
00151   iostatus_t compact_data( void );
00152   iostatus_t sync( void );
00153   iostatus_t get_iterator( std::streamoff where, FileIterator &it );
00154   iostatus_t get_fileorder_iterator( std::streamoff where, FileIterator &it );
00155   iostatus_t modified( bool &mod );
00156   iostatus_t read_begin( std::streamoff &begin );
00157   iostatus_t read_end( std::streamoff &end );
00158   iostatus_t read_last( std::streamoff &last );
00159   iostatus_t read_file_end( std::streamoff &fileend );
00160 #ifdef FILELIST_HAS_DEBUG_CODE
00161   iostatus_t dump_status( const char *filename, iostatus_t status, const std::string &caller, int line );
00162 #endif
00163 
00164   inline iostatus_t read_data( std::string &data, FileIterator &it ) { return this->read_data( data, it.position(), it ); }
00165   inline iostatus_t read_fileorder_data( std::string &data, FileIterator &it )
00166   { return this->read_data( data, it.position(), it, true ); }
00167   inline iostatus_t add_data( const std::string &data, FileIterator &it ) { return this->add_data( data, it.position(), it ); }
00168   inline iostatus_t remove_data( const FileIterator &it ) { return this->remove_data( it.position() ); }
00169   inline iostatus_t initialize( void ) { return this->initContainer(); }
00170   inline iostatus_t force_backup( const char *backupfile = NULL ) { return this->backupFile( backupfile ); }
00171   inline std::streamoff file_begin( void ) { return fc_s_headerSize; }
00172   inline std::streamoff start( void ) { return 0; }
00173   inline std::fstream &get_stream( void ) { return *this->fc_stream; }
00174 
00175   inline const std::string &filename( void ) const { return this->fc_filename; }
00176 
00177 private:
00178   const FileContainer &operator=( const FileContainer & ); // Not implemented
00179   FileContainer( const FileContainer & ); // Not implemented
00180 
00181   class TimeStamp;
00182 
00183   iostatus_t openFile( void );
00184   iostatus_t createFile( void );
00185   iostatus_t syncData( bool stamp = true );
00186   iostatus_t createEmptyFile( void );
00187   iostatus_t eraseFile( off_t size = 0 );
00188   iostatus_t truncateFile( off_t size );
00189   iostatus_t readStamp( void );
00190   iostatus_t writeStamp( void );
00191   iostatus_t writeFileStatus( filestatus_t fs );
00192   iostatus_t readFileStatus( filestatus_t &fs );
00193   iostatus_t readSize( void );
00194   iostatus_t writeAndSetSize( size_t num );
00195   iostatus_t createEmptyBackup( filestatus_t status );
00196   iostatus_t writeIteratorBackup( int what, const FileIterator &it, filestatus_t status );
00197   iostatus_t readIteratorBackup( int what, FileIterator &it );
00198   iostatus_t writeLimitsBackup( filestatus_t status, const FileIterator &it, bool isList = false );
00199   iostatus_t readLimitsBackup( FileIterator &it, bool isList = false );
00200   iostatus_t writeInitialPosition( const FileIterator &limits, bool isList = false );
00201   iostatus_t readInitialPosition( FileIterator &limits, bool isList = false );
00202   iostatus_t updateTimeStamp( void );
00203   iostatus_t checkStream( bool recover = true );
00204   iostatus_t checkStreamAndStamp( bool recover = true );
00205   iostatus_t checkStamp( bool &modified );
00206   iostatus_t readIteratorHere( FileIterator &it );
00207   iostatus_t readIterator( std::streamoff where, FileIterator &it, bool fileorder = false );
00208   iostatus_t writeIterator( std::streamoff where, const FileIterator &it );
00209   iostatus_t resetNextOfLast( filestatus_t status );
00210   iostatus_t writeDataHeader( const FileIterator &it, std::string::size_type size, char state );
00211   iostatus_t writeDataHere( const FileIterator &it, const FileIterator &lit, const std::string &data, filestatus_t status );
00212   iostatus_t addDataAtBegin( const std::string &data, FileIterator &it, std::streamoff end );
00213   iostatus_t addDataAtEnd( const std::string &data, FileIterator &it, std::streamoff end );
00214   iostatus_t addDataInMiddle( const std::string &data, FileIterator &it, std::streamoff where, std::streamoff end );
00215   iostatus_t readDataHere( FileIterator &it, FileIterator &itList, std::string &data, bool force = false );
00216   iostatus_t readSizeAndState( std::string::size_type &size, char &state );
00217   iostatus_t removeDataPointer( const FileIterator &it, std::string::size_type size );
00218   iostatus_t markDataAsErased( const FileIterator &it, std::string::size_type size, filestatus_t status );
00219   iostatus_t markDataAsUnerased( const FileIterator &it );
00220   iostatus_t backupFile( const char *backupfile = NULL );
00221   iostatus_t fillVector( std::vector<std::string> &vec );
00222   iostatus_t initContainer( void );
00223   iostatus_t checkConsistency( int allowable_size_offset );
00224 
00225   inline std::streamoff getEnd( void ) { this->fc_stream->seekp( 0, std::ios::end ); return this->fc_stream->tellp(); }
00226   inline std::streamoff getBegin( void ) { return this->fc_limits.get_prev(); }
00227 
00228   static void staticInitialize( void );
00229 
00230   bool               fc_initialized;
00231   size_t             fc_size;
00232   std::fstream      *fc_stream;
00233   TimeStamp         *fc_stamp;
00234   std::string        fc_filename;
00235   FileIterator       fc_limits, fc_removed;
00236 #ifdef FILELIST_HAS_DEBUG_CODE
00237   std::vector<std::string>   fc_callStack;
00238 
00239   class StackPusher {
00240   public:
00241     StackPusher( std::vector<std::string> &callstack, const char *format, ... );
00242     ~StackPusher( void );
00243 
00244   private:
00245     std::vector<std::string>     &sp_callstack;
00246   };
00247 #endif
00248 
00249   static int         fc_s_stampSize, fc_s_sizeSize, fc_s_headerSize, fc_s_backupSize;
00250   static int         fc_s_iteratorBackupSize, fc_s_limitsBackupSize, fc_s_numberSize;
00251   static int         fc_s_statusPosition, fc_s_positionPosition;
00252   static int         fc_s_listBackupSize, fc_s_listPosition;
00253   static const int   fc_s_iteratorBackupNumber;
00254 };
00255 
00256 #ifdef FILELIST_HAS_DEBUG_CODE
00257 void throwErrorAndDumpFile( FileContainer &cont, FileContainerError::iostatus_t status,
00258                             const std::string &func, const std::string &filename, int line, bool doThrow = true );
00259 #else
00260 #define throwErrorAndDumpFile( container, status, func, filename, line )  \
00261            throw FileContainerError( (status), (func), (filename).c_str(), (line) )
00262 #endif
00263 
00264 }; // Namespace utilities
00265 
00266 } COMMON_NAMESPACE_END;
00267 
00268 #endif /* EDG_WORKLOAD_COMMON_UTILITIES_FILECONTAINER_H */
00269 
00270 // Local Variables:
00271 // mode: c++
00272 // End:

Generated on Fri May 14 14:18:25 2004 for COMMON API - configuration, jobid, ldif2classadi, logger, process, requestad, socket++i, task, utilities by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002