00001 #ifndef Impala_Persistency_File_h
00002 #define Impala_Persistency_File_h
00003
00004 #include "Persistency/FileSystem.h"
00005 #include "Basis/Endian.h"
00006
00007 namespace Impala
00008 {
00009 namespace Persistency
00010 {
00011
00012
00015 class File
00016 {
00017 public:
00018
00019 typedef Util::IOBuffer IOBuffer;
00020
00021 File()
00022 {
00023 mPath = "";
00024 mFileSystem = 0;
00025 mIsWritable = false;
00026 }
00027
00028 File(CString path)
00029 {
00030 mPath = path;
00031 mFileSystem = 0;
00032 mIsWritable = false;
00033 }
00034
00035 File(CString path, FileSystem* fs, bool isWritable)
00036 {
00037 mPath = path;
00038 mFileSystem = fs;
00039 mIsWritable = isWritable;
00040 }
00041
00042 bool
00043 Valid() const
00044 {
00045 return (!mPath.empty() && (mFileSystem != 0));
00046 }
00047
00048 String
00049 GetPath() const
00050 {
00051 return mPath;
00052 }
00053
00054 FileSystem*
00055 GetFileSystem() const
00056 {
00057 return mFileSystem;
00058 }
00059
00060 bool
00061 IsWritable() const
00062 {
00063 return mIsWritable;
00064 }
00065
00066 void
00067 CopyFrom(File srcFile)
00068 {
00069 IOBuffer* srcBuf = srcFile.GetReadBuffer();
00070 if (!srcBuf)
00071 return;
00072 IOBuffer* dstBuf = GetWriteBuffer();
00073 if (!dstBuf)
00074 {
00075 delete srcBuf;
00076 return;
00077 }
00078 int bufSize = Util::Channel::DATA_BUFFER_SIZE;
00079 char* buf = new char[bufSize];
00080 while (srcBuf->Available() > 0)
00081 {
00082 int nrRead = srcBuf->Read(buf, bufSize);
00083 dstBuf->Write(buf, nrRead);
00084 }
00085 delete buf;
00086 delete dstBuf;
00087 delete srcBuf;
00088 }
00089
00090 void
00091 Delete()
00092 {
00093 if (! (Valid() && IsWritable()))
00094 return;
00095 mFileSystem->DeleteFile(mPath);
00096 mPath = "";
00097 }
00098
00099
00100
00101 template<class BackInsertIterator>
00102 void
00103 ReadStrings(BackInsertIterator bi, bool skipEmptyAndComment = true)
00104 {
00105 IOBuffer* buf = GetReadBuffer();
00106 if (! (buf && buf->Valid()))
00107 {
00108 return;
00109 }
00110
00111 while (buf->Available())
00112 {
00113 String line = buf->ReadLine();
00114 if (line[0] || !skipEmptyAndComment)
00115 {
00116 if ((line[0] != '#') || !skipEmptyAndComment)
00117 *bi++ = line;
00118 }
00119 }
00120 delete buf;
00121 }
00122
00123 void
00124 ReadStrings(std::vector<String>& stringList)
00125 {
00126 ReadStrings(std::back_inserter(stringList));
00127 }
00128
00129 template <class Iterator>
00130 bool
00131 WriteStrings(Iterator begin, Iterator end)
00132 {
00133 IOBuffer* buf = GetWriteBuffer();
00134 if (! (buf && buf->Valid()))
00135 {
00136 return false;
00137 }
00138 for (Iterator it=begin ; it!=end ; it++)
00139 {
00140 String s = *it;
00141 buf->Puts(s);
00142 }
00143 delete buf;
00144 return true;
00145 }
00146
00147 void
00148 WriteStrings(const std::vector<String>& stringList)
00149 {
00150 WriteStrings(stringList.begin(), stringList.end());
00151 }
00152
00153
00154
00155 template<class BackInsertIterator>
00156 void
00157 ReadNative(BackInsertIterator bi, bool useMemoryBuffer = false)
00158 {
00159 typedef typename BackInsertIterator::container_type::value_type elem_type;
00160
00161 IOBuffer* buf = (useMemoryBuffer) ? GetReadBuffer(true, "")
00162 : GetReadBuffer();
00163 if (! (buf && buf->Valid()))
00164 return;
00165
00166 while (buf->Available() > 0)
00167 {
00168 elem_type d;
00169 buf->Read(&d, sizeof(d));
00170 EndianSwap(&d);
00171 *bi++ = d;
00172 }
00173 delete buf;
00174 }
00175
00176 template <class Iterator>
00177 void
00178 WriteNative(Iterator begin, Iterator end)
00179 {
00180 typedef typename Iterator::value_type elem_type;
00181
00182 IOBuffer* buf = GetWriteBuffer();
00183 for (Iterator it=begin ; it!=end ; it++)
00184 {
00185 elem_type d = *it;
00186 EndianSwap(&d);
00187 buf->Write(&d, sizeof(d));
00188 }
00189 delete buf;
00190 }
00191
00192
00193
00194
00195 IOBuffer*
00196 GetReadBuffer()
00197 {
00198 if (!Valid())
00199 {
00200 ILOG_ERROR("Can't get read buffer for invalid file");
00201 return 0;
00202 }
00203 return mFileSystem->GetIOBuffer(GetPath(), true, false, "", 0, true);
00204 }
00205
00206
00207 IOBuffer*
00208 GetReadBuffer(bool useMemoryIfLocal, String useLocalFileIfRemote,
00209 Int64 useLocalSizeIfRemote = 0,
00210 bool useIOBufferChannel = false)
00211 {
00212 if (!Valid())
00213 {
00214 ILOG_ERROR("Can't get read buffer for invalid file");
00215 return 0;
00216 }
00217 return mFileSystem->GetIOBuffer(GetPath(), true, useMemoryIfLocal,
00218 useLocalFileIfRemote,
00219 useLocalSizeIfRemote,
00220 useIOBufferChannel);
00221 }
00222
00223
00224 IOBuffer*
00225 GetWriteBuffer()
00226 {
00227 if (!Valid())
00228 {
00229 ILOG_ERROR("Can't get write buffer for invalid file");
00230 return 0;
00231 }
00232 if (!IsWritable())
00233 {
00234 ILOG_ERROR("Can't get write buffer for non-writable file");
00235 return 0;
00236 }
00237 return mFileSystem->GetIOBuffer(GetPath(), false, false, "tmp", 0, true);
00238 }
00239
00240
00241 IOBuffer*
00242 GetWriteBuffer(bool useMemoryIfLocal, String useLocalFileIfRemote,
00243 Int64 useLocalSizeIfRemote = 0,
00244 bool useIOBufferChannel = false)
00245 {
00246 if (!Valid())
00247 {
00248 ILOG_ERROR("Can't get write buffer for invalid file");
00249 return 0;
00250 }
00251 if (!IsWritable())
00252 {
00253 ILOG_ERROR("Can't get write buffer for non-writable file");
00254 return 0;
00255 }
00256 return mFileSystem->GetIOBuffer(GetPath(), false, useMemoryIfLocal,
00257 useLocalFileIfRemote,
00258 useLocalSizeIfRemote,
00259 useIOBufferChannel);
00260 }
00261
00262 private:
00263
00264 String mPath;
00265 FileSystem* mFileSystem;
00266 bool mIsWritable;
00267
00268 ILOG_VAR_DEC;
00269 };
00270
00271 ILOG_VAR_INIT(File, Impala.Persistency);
00272
00273 }
00274 }
00275
00276 #endif