sprint 1-alpha
|
00001 /****************************************************************************** 00002 * sprint::file 00003 * 00004 * Copyright (C) 2003-2004 Paolo Medici and LostOnesLandTeam 00005 * Copyright (C) 2005-2011 Paolo Medici <www.pmx.it> 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 * 00021 *******************************************************************************/ 00022 00027 #ifndef _SPRINT_IO_FILE_H 00028 #define _SPRINT_IO_FILE_H 00029 00030 #include <sprint/platform.h> 00031 #include <sprint/io/type.h> 00032 #include <sprint/cpptraits.h> 00033 #include <cstring> 00034 00035 #ifdef WIN32 00036 00037 # include <windows.h> 00038 00039 #elif defined (LINUX) 00040 00041 #include <unistd.h> 00042 #include <sys/types.h> 00043 #include <sys/stat.h> 00044 #include <fcntl.h> 00045 00046 #endif 00047 00048 namespace sprint { 00049 namespace io { 00050 00051 namespace detail { 00052 00053 #ifdef WIN32 00054 /* Todo: creare anche la versione File64 per i file +4GB */ 00055 00058 template<bool bManaged> 00059 class file : public if_copiable<!bManaged> { 00060 HANDLE m_h; 00061 public: 00062 file(HANDLE h = INVALID_HANDLE_VALUE) : m_h(h) { 00063 } 00064 00065 file(const char *filename, flag_t mode) 00066 { 00067 if(mode == sprint::io::read) 00068 OpenForRead(filename); 00069 else if(mode == sprint::io::write) 00070 OpenForWrite(filename); 00071 else if(mode == sprint::io::readwrite) 00072 OpenForBothReadWrite(filename); 00073 00074 } 00075 00076 ~file() 00077 { 00078 if(bManaged) 00079 if(m_h!=INVALID_HANDLE_VALUE) 00080 CloseHandle(m_h); 00081 } 00083 inline bool good() 00084 { 00085 return m_h!=INVALID_HANDLE_VALUE; 00086 } 00087 00088 bool OpenForWrite(LPCWSTR lpszFileName) 00089 { 00090 m_h = CreateFileW( 00091 lpszFileName, // pointer to name of the file 00092 GENERIC_WRITE, // access (read-write) mode 00093 0, // share mode 00094 NULL, // pointer to security attributes 00095 CREATE_ALWAYS, // how to create 00096 FILE_ATTRIBUTE_NORMAL, // file attributes 00097 NULL); 00098 return m_h!=INVALID_HANDLE_VALUE; 00099 } 00100 00101 bool OpenForWrite(LPCSTR lpszFileName) 00102 { 00103 m_h = CreateFileA( 00104 lpszFileName, // pointer to name of the file 00105 GENERIC_WRITE, // access (read-write) mode 00106 0, // share mode 00107 NULL, // pointer to security attributes 00108 CREATE_ALWAYS, // how to create 00109 FILE_ATTRIBUTE_NORMAL, // file attributes 00110 NULL); 00111 return m_h!=INVALID_HANDLE_VALUE; 00112 } 00113 00114 bool OpenForRead(LPCWSTR lpszFileName) 00115 { 00116 m_h = CreateFileW( 00117 lpszFileName, // pointer to name of the file 00118 GENERIC_READ, // access (read-write) mode 00119 0, // share mode 00120 NULL, // pointer to security attributes 00121 OPEN_EXISTING, // how to create 00122 FILE_ATTRIBUTE_NORMAL, // file attributes 00123 NULL); 00124 return m_h!=INVALID_HANDLE_VALUE; 00125 } 00126 00127 bool OpenForRead(LPCSTR lpszFileName) 00128 { 00129 m_h = CreateFileA( 00130 lpszFileName, // pointer to name of the file 00131 GENERIC_READ, // access (read-write) mode 00132 0, // share mode 00133 NULL, // pointer to security attributes 00134 OPEN_EXISTING, // how to create 00135 FILE_ATTRIBUTE_NORMAL, // file attributes 00136 NULL); 00137 return m_h!=INVALID_HANDLE_VALUE; 00138 } 00139 00140 bool OpenForBothReadWrite(LPCWSTR lpszFileName) 00141 { 00142 m_h = CreateFileW( 00143 lpszFileName, // pointer to name of the file 00144 GENERIC_READ|GENERIC_WRITE, // access (read-write) mode 00145 0, // share mode 00146 NULL, // pointer to security attributes 00147 OPEN_EXISTING, // how to create 00148 FILE_ATTRIBUTE_NORMAL, // file attributes 00149 NULL); 00150 return m_h!=INVALID_HANDLE_VALUE; 00151 } 00152 00153 bool OpenForBothReadWrite(LPCSTR lpszFileName) 00154 { 00155 m_h = CreateFileA( 00156 lpszFileName, // pointer to name of the file 00157 GENERIC_READ|GENERIC_WRITE, // access (read-write) mode 00158 0, // share mode 00159 NULL, // pointer to security attributes 00160 OPEN_EXISTING, // how to create 00161 FILE_ATTRIBUTE_NORMAL, // file attributes 00162 NULL); 00163 return m_h!=INVALID_HANDLE_VALUE; 00164 } 00165 00166 bool CreateForBothReadWrite(LPCWSTR lpszFileName) 00167 { 00168 m_h = CreateFileW( 00169 lpszFileName, // pointer to name of the file 00170 GENERIC_READ|GENERIC_WRITE, // access (read-write) mode 00171 0, // share mode 00172 NULL, // pointer to security attributes 00173 CREATE_ALWAYS, // how to create 00174 FILE_ATTRIBUTE_NORMAL, // file attributes 00175 NULL); 00176 return m_h!=INVALID_HANDLE_VALUE; 00177 } 00178 00179 bool CreateForBothReadWrite(LPCSTR lpszFileName) 00180 { 00181 m_h = CreateFileA( 00182 lpszFileName, // pointer to name of the file 00183 GENERIC_READ|GENERIC_WRITE, // access (read-write) mode 00184 0, // share mode 00185 NULL, // pointer to security attributes 00186 CREATE_ALWAYS, // how to create 00187 FILE_ATTRIBUTE_NORMAL, // file attributes 00188 NULL); 00189 return m_h!=INVALID_HANDLE_VALUE; 00190 } 00191 00192 bool CreateForWrite(LPCWSTR lpszFileName) 00193 { 00194 m_h = CreateFileW( 00195 lpszFileName, // pointer to name of the file 00196 GENERIC_WRITE, // access (read-write) mode 00197 0, // share mode 00198 NULL, // pointer to security attributes 00199 CREATE_ALWAYS, // how to create 00200 FILE_ATTRIBUTE_NORMAL, // file attributes 00201 NULL); 00202 return m_h!=INVALID_HANDLE_VALUE; 00203 } 00204 00205 bool CreateForWrite(LPCSTR lpszFileName) 00206 { 00207 m_h = CreateFileA( 00208 lpszFileName, // pointer to name of the file 00209 GENERIC_WRITE, // access (read-write) mode 00210 0, // share mode 00211 NULL, // pointer to security attributes 00212 CREATE_ALWAYS, // how to create 00213 FILE_ATTRIBUTE_NORMAL, // file attributes 00214 NULL); 00215 return m_h!=INVALID_HANDLE_VALUE; 00216 } 00217 00218 bool OpenForAppend(LPCWSTR lpszFileName) 00219 { 00220 m_h = CreateFileW( 00221 lpszFileName, // pointer to name of the file 00222 GENERIC_WRITE, // access (read-write) mode 00223 0, // share mode 00224 NULL, // pointer to security attributes 00225 OPEN_ALWAYS, // how to create 00226 FILE_ATTRIBUTE_NORMAL, // file attributes 00227 NULL); 00228 if(m_h==INVALID_HANDLE_VALUE) 00229 return false; 00230 SetFilePointer(m_h, 0, NULL, FILE_END); 00231 return true; 00232 } 00233 00234 bool OpenForAppend(LPCSTR lpszFileName) 00235 { 00236 m_h = CreateFileA( 00237 lpszFileName, // pointer to name of the file 00238 GENERIC_WRITE, // access (read-write) mode 00239 0, // share mode 00240 NULL, // pointer to security attributes 00241 OPEN_ALWAYS, // how to create 00242 FILE_ATTRIBUTE_NORMAL, // file attributes 00243 NULL); 00244 if(m_h==INVALID_HANDLE_VALUE) 00245 return false; 00246 SetFilePointer(m_h, 0, NULL, FILE_END); 00247 return true; 00248 } 00249 00250 void close() 00251 { 00252 CloseHandle(m_h); 00253 m_h = INVALID_HANDLE_VALUE; 00254 } 00255 00256 sprint::io::file_size_t seek(file_size_t offset, sprint::io::seek_t type) 00257 { 00258 return -1; 00259 } 00260 00261 sprint::io::state_t state() 00262 { 00263 // TODO 00264 return sprint::io::unimplemented; 00265 } 00266 00267 // Length 00268 inline io::file_size_t length() const 00269 { 00270 return GetFileSize(m_h, NULL); 00271 } 00272 00273 int write(LPCVOID lpBuffer, UINT uBufferLen) const 00274 { 00275 DWORD dwWrite; 00276 WriteFile(m_h, lpBuffer, uBufferLen, &dwWrite, NULL); 00277 return dwWrite; 00278 } 00279 00280 int read(LPVOID lpBuffer, UINT uBufferLen) const 00281 { 00282 DWORD dwRead; 00283 ReadFile(m_h, lpBuffer, uBufferLen, &dwRead, NULL); 00284 return dwRead; 00285 } 00286 00287 void flush() 00288 { 00289 // no 00290 } 00291 00292 inline unsigned long tell() const 00293 { 00294 return SetFilePointer(m_h, 0, NULL, FILE_CURRENT); 00295 } 00296 00297 inline unsigned long SeekFromBegin(UINT uPos) const 00298 { 00299 return SetFilePointer(m_h, uPos, NULL, FILE_BEGIN); 00300 } 00301 00302 inline unsigned long Skip(UINT uPos) const 00303 { 00304 return SetFilePointer(m_h, uPos, NULL, FILE_CURRENT); 00305 } 00306 00307 inline BOOL Rewind() const 00308 { 00309 return SetFilePointer(m_h, 0, NULL, FILE_BEGIN); 00310 } 00311 00312 // The Trunc function moves the end-of-file (EOF) position for the specified file 00313 // to the current position of the file pointer. 00314 inline BOOL trunc() const 00315 { 00316 return SetEndOfFile(m_h); 00317 } 00318 00319 int get() const 00320 { 00321 int c; 00322 return (read(&c, 1)) ? c : -1; 00323 } 00324 00325 int put(char c) 00326 { 00327 return write(&c, 1); 00328 } 00329 00330 inline BOOL SetFileTime(const FILETIME* lpCreationTime, 00331 const FILETIME* lpLastAccessTime, 00332 const FILETIME* lpLastWriteTime) 00333 { 00334 return ::SetFileTime(m_h, lpCreationTime, lpLastAccessTime, lpLastWriteTime); 00335 } 00336 inline BOOL GetFileTime(FILETIME* lpCreationTime, 00337 FILETIME* lpLastAccessTime, 00338 FILETIME* lpLastWriteTime) 00339 { 00340 return ::GetFileTime(m_h, lpCreationTime, lpLastAccessTime, lpLastWriteTime); 00341 } 00342 00343 }; 00344 00345 #elif defined(__unix__) 00346 00348 template<bool bManaged> 00349 class file : public if_copiable<!bManaged> { 00350 int i; 00351 public: 00352 file(int h = -1) { 00353 i = h; 00354 } 00355 00356 ~file() 00357 { 00358 if(bManaged) 00359 ::close(i); 00360 } 00361 00362 file(const char *filename, flag_t mode) 00363 { 00364 if(mode == sprint::io::read) 00365 OpenForRead(filename); 00366 else if(mode == sprint::io::write) 00367 OpenForWrite(filename); 00368 else if(mode == sprint::io::readwrite) 00369 OpenForBothReadWrite(filename); 00370 00371 } 00372 00373 inline void close() 00374 { 00375 ::close(i); 00376 i = -1; 00377 } 00378 00379 inline bool good() 00380 { 00381 return i!=-1; 00382 } 00383 00384 inline bool OpenForWrite(const char *lpszFileName) 00385 { 00386 i = ::open(lpszFileName, O_WRONLY | O_CREAT, 0777); 00387 return i != -1; 00388 } 00389 00390 inline bool OpenForRead(const char * lpszFileName) 00391 { 00392 #if defined(__USE_LARGEFILE64) && defined(__linux__) 00393 i = ::open(lpszFileName, O_RDONLY | O_LARGEFILE); 00394 #else 00395 i = ::open(lpszFileName, O_RDONLY); 00396 #endif 00397 return i != -1; 00398 } 00399 00400 inline bool OpenForBothReadWrite(const char * lpszFileName) 00401 { 00402 i = ::open(lpszFileName, O_CREAT|O_RDWR); 00403 return i != -1; 00404 } 00405 00406 inline bool CreateForBothReadWrite(const char * lpszFileName) 00407 { 00408 /* TODO */ 00409 i = ::open(lpszFileName, O_RDWR); 00410 return i != -1; 00411 } 00412 00413 bool CreateForWrite(const char * lpszFileName) 00414 { 00415 i = ::open(lpszFileName, O_CREAT|O_WRONLY); 00416 return i != -1; 00417 } 00418 00419 bool OpenForAppend(const char * lpszFileName) 00420 { 00421 i = ::open(lpszFileName, O_APPEND); 00422 return i != -1; 00423 } 00424 00425 unsigned long length() 00426 { 00427 unsigned long here = ::lseek(i, 0, SEEK_SET); 00428 unsigned long end = ::lseek(i, 0, SEEK_END); // go to end 00429 ::lseek(i, here, SEEK_SET); 00430 return end; 00431 } 00432 00433 int flush() 00434 { 00435 } 00436 00437 int write(const void *lpBuffer, unsigned int uBufferLen) 00438 { 00439 return ::write(i, lpBuffer, uBufferLen); 00440 } 00441 00442 int read(void *lpBuffer, unsigned int uBufferLen) 00443 { 00444 return ::read(i, lpBuffer, uBufferLen); 00445 } 00446 00447 unsigned long tell() 00448 { 00449 return ::lseek(i, 0, SEEK_CUR); 00450 } 00451 00452 unsigned long seek(unsigned long uPos, seek_t mode) 00453 { 00454 return ::lseek(i, uPos, (mode == sprint::io::start) ? SEEK_SET : 00455 (mode == sprint::io::cur) ? SEEK_CUR : 00456 SEEK_END); 00457 } 00458 00459 int get() 00460 { 00461 int c; 00462 return (read(&c, 1)) ? c : -1; 00463 } 00464 00465 int put(char c) 00466 { 00467 return write(&c, 1); 00468 } 00469 00470 state_t state() const { return (i != -1) ? sprint::io::good : sprint::io::error; } 00471 00472 }; 00473 00474 #endif // WIN32 00475 00476 } // namespace detail 00477 00479 typedef detail::file<false> file_handle; 00481 typedef detail::file<true> file; 00482 00483 } // namespace io 00484 } // namespace sprint 00485 00486 #endif // FILE_H