00001
00002
00003
00004
00005 #ifndef BALL_SYSTEM_FILE_H
00006 #define BALL_SYSTEM_FILE_H
00007
00008 #ifndef BALL_DATATYPE_REGULAREXPRESSION_H
00009 # include <BALL/DATATYPE/regularExpression.h>
00010 #endif
00011
00012 #ifndef BALL_DATATYPE_STRING_H
00013 # include <BALL/DATATYPE/string.h>
00014 #endif
00015
00016 #ifndef BALL_SYSTEM_FILESYSTEM_H
00017 # include <BALL/SYSTEM/fileSystem.h>
00018 #endif
00019
00020 #include <stdlib.h>
00021 #include <sys/stat.h>
00022 #include <stdio.h>
00023 #include <algorithm>
00024
00025 #ifdef BALL_COMPILER_MSVC
00026 #ifndef S_ISREG
00027 # define S_ISREG _S_ISREG
00028 #endif
00029 #ifndef S_ISDIR
00030 # define S_ISDIR _S_ISDIR
00031 #endif
00032 # define S_ISCHR _S_ISCHR
00033 # define S_ISBLK _S_ISBLK
00034 # define S_ISFIFO _S_ISFIFO
00035 # define access _access
00036 #endif
00037
00038 #include <iostream>
00039 #include <fstream>
00040 #include <sys/types.h>
00041 #include <map>
00042 #include <algorithm>
00043
00044 #ifdef BALL_HAS_UNISTD_H
00045 # include <unistd.h>
00046 #endif
00047
00048 #ifdef BALL_COMPILER_MSVC
00049 # include <fcntl.h>
00050 # include <io.h>
00051
00052
00053 # define F_OK 0
00054 # define W_OK 2
00055 # define R_OK 4
00056 #endif
00057
00058
00059 namespace BALL
00060 {
00078 class BALL_EXPORT TransformationManager
00079 {
00080 public:
00081
00085
00087 TransformationManager();
00088
00090 ~TransformationManager();
00091
00093
00096
00098 void registerTransformation(const String& pattern, const String& command);
00099
00101 void unregisterTransformation(const String& pattern);
00102
00104 String findTransformation(const String& name) const;
00105
00123 String transform(const String& name);
00125
00126 protected:
00127
00129 std::map<String, String> transformation_methods_;
00130 };
00131
00135 class BALL_EXPORT File
00136 : public std::fstream
00137 {
00138 public:
00139
00143 class BALL_EXPORT CannotWrite
00144 : public Exception::GeneralException
00145 {
00146 public:
00147 CannotWrite(const char* file, int line, const String& filename);
00148
00149 ~CannotWrite()
00150 throw();
00151
00152 String getFilename() const;
00153
00154 protected:
00155 std::string filename_;
00156 };
00157
00161
00166 typedef std::ios::openmode OpenMode;
00167
00169
00173
00174 static const OpenMode MODE_IN;
00175
00177 static const OpenMode MODE_OUT;
00178
00180 static const OpenMode MODE_APP;
00181
00183 static const OpenMode MODE_BINARY;
00184
00186 static const OpenMode MODE_ATE;
00187
00189 static const OpenMode MODE_TRUNC;
00191
00195
00199 enum Transformation
00200 {
00202 TRANSFORMATION__EXEC = 1,
00204 TRANSFORMATION__FILTER = 2,
00206 TRANSFORMATION__URL = 3
00207 };
00208
00211 enum Type
00212 {
00214 TYPE__UNKNOWN = 0,
00216 TYPE__DIRECTORY = 1,
00218 TYPE__CHAR_SPECIAL_FILE = 2,
00220 TYPE__BLOCK_SPECIAL_FILE = 3,
00222 TYPE__REGULAR_FILE = 4,
00224 TYPE__SYMBOLIC_LINK = 5,
00226 TYPE__SOCKET = 6,
00228 TYPE__FIFO_SPECIAL_FILE = 7
00229 };
00230
00232 static const String TRANSFORMATION_EXEC_PREFIX;
00233
00235 static const String TRANSFORMATION_FILE_PREFIX;
00236
00238 static const String TRANSFORMATION_FTP_PREFIX;
00239
00241 static const String TRANSFORMATION_HTTP_PREFIX;
00242
00244
00247
00250 File();
00251
00257 File(const String& name, OpenMode open_mode = std::ios::in)
00258 throw(Exception::FileNotFound);
00259
00263 virtual ~File();
00264
00267 virtual void clear();
00269
00273
00278
00279
00281
00285
00292 bool open(const String& name, File::OpenMode open_mode = std::ios::in)
00293 throw (Exception::FileNotFound);
00294
00299 bool reopen()
00300 throw (Exception::FileNotFound);
00301
00307 bool reopen(File::OpenMode open_mode)
00308 throw (Exception::FileNotFound);
00309
00312 void close();
00313
00317 const String& getName() const;
00318
00322 void setName(const String& name);
00323
00326 const String& getOriginalName() const;
00327
00332 Size getSize()
00333 throw(Exception::FileNotFound);
00334
00338 static Size getSize(String name)
00339 throw (Exception::FileNotFound);
00340
00345 File::OpenMode getOpenMode() const;
00346
00352 static Type getType(String name, bool trace_link)
00353 throw(Exception::FileNotFound);
00354
00359 Type getType(bool trace_link)
00360 const throw(Exception::FileNotFound);
00361
00369 static bool copy(String source_name, String destination_name, Size buffer_size = 4096)
00370 throw(Exception::FileNotFound);
00371
00378 bool copyTo(const String& destination_name, Size buffer_size = 4096)
00379 throw(Exception::FileNotFound);
00380
00387 static bool move(const String& source_name, const String& destination_name)
00388 throw(Exception::FileNotFound);
00389
00395 bool moveTo(const String& destination_name)
00396 throw(Exception::FileNotFound);
00397
00402 static bool remove(String name);
00403
00407 bool remove();
00408
00414 static bool rename(String old_path, String new_path)
00415 throw (Exception::FileNotFound);
00416
00422 bool renameTo(const String& new_path)
00423 throw (Exception::FileNotFound);
00424
00430 static bool truncate(String path, Size size = 0)
00431 throw (Exception::FileNotFound);
00432
00437 bool truncate(Size size = 0)
00438 throw (Exception::FileNotFound);
00439
00448 static bool createTemporaryFilename(String& temporary, const String& suffix = ".TMP");
00449
00454 std::fstream& getFileStream();
00455
00457
00461
00467 TransformationManager& getTransformationManager();
00468
00474 const TransformationManager& getTransformationManager() const;
00475
00478 static void enableTransformation(Transformation transformation);
00479
00482 static void disableTransformation(Transformation transformation);
00483
00486 static bool isTransformationEnabled(Transformation transformation);
00487
00490 static void registerTransformation(const String& pattern, const String& exec);
00491
00494 static void unregisterTransformation(const String& pattern);
00495
00497
00500
00504 bool operator == (const File& file) const;
00505
00509 bool operator != (const File& file) const;
00510
00515 bool isOpen() const;
00516
00521 bool isClosed() const;
00522
00527 static bool isAccessible(String name);
00528
00532 bool isAccessible()
00533 const throw (Exception::FileNotFound);
00534
00541 bool isCanonized()
00542 const throw (Exception::FileNotFound);
00543
00548 static bool isReadable(String name)
00549 throw (Exception::FileNotFound);
00550
00554 bool isReadable()
00555 const throw (Exception::FileNotFound);
00556
00561 static bool isWritable(String name)
00562 throw (Exception::FileNotFound);
00563
00567 bool isWritable()
00568 const throw (Exception::FileNotFound);
00569
00574 static bool isExecutable(String name)
00575 throw (Exception::FileNotFound);
00576
00580 bool isExecutable()
00581 const throw (Exception::FileNotFound);
00582
00584
00587
00593 bool isValid() const;
00594
00596
00597 private:
00598 const File& operator = (const File& file);
00599
00600 protected:
00601
00602 String name_;
00603 String original_name_;
00604 OpenMode open_mode_;
00605 bool is_open_;
00606 bool is_temporary_;
00607
00608 static TransformationManager transformation_manager_;
00609 static Size transformation_methods_;
00610 };
00611
00612
00624 template <typename T>
00625 class BinaryFileAdaptor
00626 {
00627
00628 public:
00629
00631
00632
00634 BinaryFileAdaptor();
00635
00637 BinaryFileAdaptor(const T& data, bool swap_endian = false);
00638
00640
00641
00642
00644 void setSwapEndian(bool swap_endian);
00645
00647 bool getSwapEndian() const;
00648
00652 void setData(const T& data);
00653
00656 const T& getData() const;
00657
00660 T& getData();
00661
00663
00664 protected:
00665
00666
00667 T data_;
00668
00669
00670 bool swap_endian_;
00671 };
00672
00673 template <typename T>
00674 BALL_INLINE
00675 BinaryFileAdaptor<T>::BinaryFileAdaptor()
00676 : data_(),
00677 swap_endian_(false)
00678 {
00679 }
00680
00681 template <typename T>
00682 BALL_INLINE
00683 BinaryFileAdaptor<T>::BinaryFileAdaptor(const T& data, bool swap_endian)
00684 : data_(data),
00685 swap_endian_(swap_endian)
00686 {
00687 }
00688
00689 template <typename T>
00690 BALL_INLINE
00691 void BinaryFileAdaptor<T>::setSwapEndian(bool swap_endian)
00692 {
00693 swap_endian_ = swap_endian;
00694 }
00695
00696 template <typename T>
00697 BALL_INLINE
00698 bool BinaryFileAdaptor<T>::getSwapEndian() const
00699 {
00700 return swap_endian_;
00701 }
00702
00703 template <typename T>
00704 BALL_INLINE
00705 void BinaryFileAdaptor<T>::setData(const T& data)
00706 {
00707 data_ = data;
00708 }
00709
00710 template <typename T>
00711 BALL_INLINE
00712 const T& BinaryFileAdaptor<T>::getData() const
00713 {
00714 return data_;
00715 }
00716
00717 template <typename T>
00718 BALL_INLINE
00719 T& BinaryFileAdaptor<T>::getData()
00720 {
00721 return data_;
00722 }
00723
00725 template <typename T>
00726 std::ostream& operator << (std::ostream& os, const BinaryFileAdaptor<T>& data)
00727 {
00728
00729 if (!data.getSwapEndian())
00730 {
00731 os.write(reinterpret_cast<const char*>(&data.getData()), sizeof(T));
00732 }
00733 else
00734 {
00735 T swapped_data = data.getData();
00736 swapBytes(swapped_data);
00737 os.write(reinterpret_cast<const char*>(&swapped_data), sizeof(T));
00738 }
00739 return os;
00740 }
00741
00743 template <typename T>
00744 std::istream& operator >> (std::istream& is, BinaryFileAdaptor<T>& data)
00745 {
00746
00747 if (!data.getSwapEndian())
00748 {
00749 is.read(reinterpret_cast<char*>(&data.getData()), sizeof(T));
00750 }
00751 else
00752 {
00753 T swapped_data;
00754 is.read(reinterpret_cast<char*>(&swapped_data), sizeof(T));
00755 swapBytes(swapped_data);
00756 data.setData(swapped_data);
00757 }
00758 return is;
00759 }
00760
00761
00765 template <typename T>
00766 BALL_INLINE
00767 void swapBytes(T& t)
00768 {
00769 if (sizeof(T) % 2 != 0)
00770 {
00771 Log.error() << "Cannot swap types of uneven size." << std::endl;
00772 return;
00773 }
00774
00775 char* tmp = reinterpret_cast<char*>(&t);
00776 std::reverse(tmp, tmp + sizeof(T));
00777 }
00778
00779
00780 # ifndef BALL_NO_INLINE_FUNCTIONS
00781 # include <BALL/SYSTEM/file.iC>
00782 # endif
00783
00784 }
00785
00786 #endif // BALL_SYSTEM_FILE_H