file.h

Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 // $Id: file.h,v 1.68.14.1 2007/03/25 21:25:38 oliver Exp $
00005 //
00006 
00007 #ifndef BALL_SYSTEM_FILE_H
00008 #define BALL_SYSTEM_FILE_H
00009 
00010 #ifndef BALL_DATATYPE_REGULAREXPRESSION_H
00011 # include <BALL/DATATYPE/regularExpression.h>
00012 #endif
00013 
00014 #ifndef BALL_DATATYPE_STRING_H
00015 # include <BALL/DATATYPE/string.h>
00016 #endif
00017 
00018 #ifndef BALL_SYSTEM_FILESYSTEM_H
00019 # include <BALL/SYSTEM/fileSystem.h>
00020 #endif
00021 
00022 #include <stdlib.h>                   // 'getenv'
00023 #include <sys/stat.h>         // 'stat', 'lstat'
00024 #include <stdio.h>                    // 'rename'
00025 #include <algorithm>                  // 'reverse'
00026 
00027 #ifdef BALL_COMPILER_MSVC
00028 #ifndef S_ISREG
00029 # define S_ISREG _S_ISREG
00030 #endif
00031 #ifndef S_ISDIR
00032 # define S_ISDIR _S_ISDIR
00033 #endif
00034 # define S_ISCHR _S_ISCHR
00035 # define S_ISBLK _S_ISBLK
00036 # define S_ISFIFO _S_ISFIFO
00037 # define access _access
00038 #endif
00039 
00040 #include <iostream>
00041 #include <fstream>
00042 #include <sys/types.h>
00043 #include <map>
00044 #include <algorithm>
00045 
00046 #ifdef BALL_HAS_UNISTD_H
00047 # include <unistd.h>      // 'access', 'rename', 'truncate'
00048 #endif
00049 
00050 #ifdef BALL_COMPILER_MSVC
00051 # include <fcntl.h>
00052 # include <io.h>
00053   // Define the missing symbols from <unistd.h>,
00054   // which M$, in its infinite wisdom, was unable to provide.
00055 # define F_OK 0
00056 # define W_OK 2
00057 # define R_OK 4
00058 #endif
00059 
00060 
00061 namespace BALL 
00062 {
00080   class BALL_EXPORT TransformationManager
00081   { 
00082     public:
00083       
00087     
00089     TransformationManager();
00090     
00092     ~TransformationManager();
00093     
00095 
00098     
00100     void registerTransformation(const String& pattern, const String& command);
00101     
00103     void unregisterTransformation(const String& pattern);
00104     
00106     String findTransformation(const String& name) const;
00107 
00125     String transform(const String& name);
00127 
00128     protected:
00129     
00131     std::map<String, String>  transformation_methods_;
00132   };
00133     
00137   class BALL_EXPORT File
00138     : public std::fstream
00139   {
00140     public:
00141 
00145     class BALL_EXPORT CannotWrite
00146       : public Exception::GeneralException
00147     {
00148       public:
00149       CannotWrite(const char* file, int line, const String& filename)
00150         ;
00151 
00152       ~CannotWrite() 
00153         throw();
00154       String getFilename() const
00155         ;
00156 
00157       protected:
00158       std::string filename_;
00159     };
00160 
00164       
00169     typedef std::ios::openmode OpenMode;      
00170 
00172 
00176 
00177     static const OpenMode MODE_IN;
00178 
00180     static const OpenMode MODE_OUT;
00181 
00183     static const OpenMode MODE_APP;
00184 
00186     static const OpenMode MODE_BINARY;
00187 
00189     static const OpenMode MODE_ATE;
00190 
00192     static const OpenMode MODE_TRUNC;
00194 
00198 
00202     enum Transformation
00203     {
00205       TRANSFORMATION__EXEC = 1,
00207       TRANSFORMATION__FILTER = 2,
00209       TRANSFORMATION__URL = 3
00210     };
00211 
00214     enum Type
00215     {
00217       TYPE__UNKNOWN            = 0,
00219       TYPE__DIRECTORY          = 1,
00221       TYPE__CHAR_SPECIAL_FILE  = 2,
00223       TYPE__BLOCK_SPECIAL_FILE = 3,
00225       TYPE__REGULAR_FILE       = 4,
00227       TYPE__SYMBOLIC_LINK      = 5,
00229       TYPE__SOCKET             = 6,
00231       TYPE__FIFO_SPECIAL_FILE  = 7
00232     };
00233 
00235     static const String TRANSFORMATION_EXEC_PREFIX;
00236 
00238     static const String TRANSFORMATION_FILE_PREFIX;
00239 
00241     static const String TRANSFORMATION_FTP_PREFIX;
00242 
00244     static const String TRANSFORMATION_HTTP_PREFIX;
00245 
00247 
00250 
00253     File()
00254       ;
00255 
00261     File(const String& name, OpenMode open_mode = std::ios::in)
00262       throw(Exception::FileNotFound);
00263 
00269     File(const File& file)
00270       throw(Exception::FileNotFound);
00271 
00275     virtual ~File()
00276       ;
00277 
00280     virtual void clear() ;
00282 
00286 
00291     const File& operator = (const File& file)
00292       ;
00293 
00295 
00299 
00306     bool open(const String& name, File::OpenMode open_mode = std::ios::in)
00307       throw (Exception::FileNotFound);
00308 
00313     bool reopen()
00314       throw (Exception::FileNotFound);
00315 
00321     bool reopen(File::OpenMode open_mode)
00322       throw (Exception::FileNotFound);
00323 
00326     void close()
00327       ;
00328 
00332     const String& getName()
00333       const ;
00334     
00338     void setName(const String& name)
00339       ;
00340 
00343     const String& getOriginalName() const
00344       ;
00345 
00350     Size getSize()
00351       throw(Exception::FileNotFound);
00352 
00356     static Size getSize(String name)
00357       throw (Exception::FileNotFound);
00358 
00363     File::OpenMode getOpenMode()
00364       const ;
00365     
00371     static Type getType(String name, bool trace_link)
00372       throw(Exception::FileNotFound);
00373 
00378     Type getType(bool trace_link)
00379       const throw(Exception::FileNotFound);
00380 
00388     static bool copy(String source_name, String destination_name, Size buffer_size = 4096)
00389       throw(Exception::FileNotFound);
00390 
00397     bool copyTo(const String& destination_name, Size buffer_size = 4096)
00398       throw(Exception::FileNotFound);
00399 
00406     static bool move(const String& source_name, const String& destination_name)
00407       throw(Exception::FileNotFound);
00408 
00414     bool moveTo(const String& destination_name)
00415       throw(Exception::FileNotFound);
00416 
00421     static bool remove(String name)
00422       ;
00423 
00427     bool remove()
00428       ;
00429 
00435     static bool rename(String old_path, String new_path)
00436       throw (Exception::FileNotFound);
00437 
00443     bool renameTo(const String& new_path)
00444       throw (Exception::FileNotFound);
00445 
00451     static bool truncate(String path, Size size = 0)
00452       throw (Exception::FileNotFound);
00453 
00458     bool truncate(Size size = 0)
00459       throw (Exception::FileNotFound);
00460       
00468     static bool createTemporaryFilename(String& temporary)
00469       ;
00470 
00475     std::fstream& getFileStream();
00476 
00478 
00482 
00488     TransformationManager& getTransformationManager();
00489 
00495     const TransformationManager& getTransformationManager() const;
00496     
00499     static void enableTransformation(Transformation transformation);
00500 
00503     static void disableTransformation(Transformation transformation);
00504 
00507     static bool isTransformationEnabled(Transformation transformation);
00508 
00511     static void registerTransformation(const String& pattern, const String& exec);
00512 
00515     static void unregisterTransformation(const String& pattern);
00516 
00518 
00521 
00525     bool operator == (const File& file)
00526       const ;
00527     
00531     bool operator != (const File& file)
00532       const ;
00533 
00538     bool isOpen()
00539       const ;
00540 
00545     bool isClosed()
00546       const ;
00547 
00552     static bool isAccessible(String name)
00553       ;
00554 
00558     bool isAccessible()
00559       const throw (Exception::FileNotFound);
00560 
00567     bool isCanonized()
00568       const throw (Exception::FileNotFound);
00569   
00574     static bool isReadable(String name)
00575       throw (Exception::FileNotFound);
00576 
00580     bool isReadable()
00581       const throw (Exception::FileNotFound);
00582 
00587     static bool isWritable(String name)
00588       throw (Exception::FileNotFound);
00589 
00593     bool isWritable()
00594       const throw (Exception::FileNotFound);
00595 
00600     static bool isExecutable(String name)
00601       throw (Exception::FileNotFound);
00602 
00606     bool isExecutable()
00607       const throw (Exception::FileNotFound);
00608  
00610 
00613 
00619     bool isValid()
00620       const ;
00621 
00623 
00624     protected:
00625 
00626     String    name_;
00627     String    original_name_;
00628     OpenMode  open_mode_;
00629     bool      is_open_;
00630     bool      is_temporary_;
00631 
00632     static TransformationManager  transformation_manager_;
00633     static Size                   transformation_methods_;
00634   };
00635 
00636 
00648   template <typename T>
00649   class BinaryFileAdaptor
00650   {
00651 
00652     public:
00653 
00655 
00656 
00658     BinaryFileAdaptor()
00659       ;
00660 
00662     BinaryFileAdaptor(const T& data, bool swap_endian = false)
00663       ;
00664 
00666 
00667 
00668 
00670     void setSwapEndian(bool swap_endian)
00671       ;
00672 
00674     bool getSwapEndian() const
00675       ;
00676 
00680     void setData(const T& data)
00681       ;
00682 
00685     const T& getData() const
00686       ;
00687 
00690     T& getData()
00691       ;
00692 
00694 
00695     protected:
00696 
00697     //_ The member data.
00698     T data_;
00699 
00700     //_ A flag indicating whether we should swap all reads and writes
00701     bool swap_endian_;
00702   };
00703 
00704   template <typename T>
00705   BALL_INLINE
00706   BinaryFileAdaptor<T>::BinaryFileAdaptor()
00707     
00708     : data_(),
00709       swap_endian_(false)
00710   {
00711   }
00712 
00713   template <typename T>
00714   BALL_INLINE
00715   BinaryFileAdaptor<T>::BinaryFileAdaptor(const T& data, bool swap_endian)
00716     
00717     : data_(data),
00718       swap_endian_(swap_endian)
00719   {
00720   }
00721 
00722   template <typename T>
00723   BALL_INLINE
00724   void BinaryFileAdaptor<T>::setSwapEndian(bool swap_endian)
00725     
00726   {
00727     swap_endian_ = swap_endian;
00728   }
00729 
00730   template <typename T>
00731   BALL_INLINE
00732   bool BinaryFileAdaptor<T>::getSwapEndian() const
00733     
00734   {
00735     return swap_endian_;
00736   }
00737 
00738   template <typename T>
00739   BALL_INLINE
00740   void BinaryFileAdaptor<T>::setData(const T& data)
00741     
00742   {
00743     data_ = data;
00744   }
00745 
00746   template <typename T>
00747   BALL_INLINE
00748   const T& BinaryFileAdaptor<T>::getData() const 
00749     
00750   {
00751     return data_;
00752   }
00753 
00754   template <typename T>
00755   BALL_INLINE
00756   T& BinaryFileAdaptor<T>::getData()
00757     
00758   {
00759     return data_;
00760   }
00761 
00763   template <typename T>
00764   std::ostream& operator << (std::ostream& os, const BinaryFileAdaptor<T>& data)
00765   {
00766     // do we need to swap endianness?
00767     if (!data.getSwapEndian())
00768     {
00769       os.write(reinterpret_cast<const char*>(&data.getData()), sizeof(T));
00770     }
00771     else
00772     {
00773       T swapped_data = data.getData();
00774       swapBytes(swapped_data);
00775       os.write(reinterpret_cast<const char*>(&swapped_data), sizeof(T));
00776     }
00777     return os;
00778   }
00779 
00781   template <typename T>
00782   std::istream& operator >> (std::istream& is, BinaryFileAdaptor<T>& data)
00783   {
00784     // do we need to swap endianness?
00785     if (!data.getSwapEndian())
00786     {
00787       is.read(reinterpret_cast<char*>(&data.getData()), sizeof(T));
00788     }
00789     else
00790     {
00791       T swapped_data;
00792       is.read(reinterpret_cast<char*>(&swapped_data), sizeof(T));
00793       swapBytes(swapped_data);
00794       data.setData(swapped_data);
00795     }
00796     return is;
00797   }
00798 
00799 
00803   template <typename T>
00804   BALL_INLINE
00805   void swapBytes(T& t)
00806   {
00807     if (sizeof(T) % 2 != 0)
00808     {
00809       Log.error() << "Cannot swap types of uneven size." << std::endl;
00810       return;
00811     }
00812 
00813     char* tmp = reinterpret_cast<char*>(&t);
00814     std::reverse(tmp, tmp + sizeof(T));
00815   }
00816   
00817 
00818 # ifndef BALL_NO_INLINE_FUNCTIONS
00819 #   include <BALL/SYSTEM/file.iC>
00820 # endif
00821   
00822 } // namespace BALL
00823 
00824 #endif // BALL_SYSTEM_FILE_H