file_win32_wrapper.h

Go to the documentation of this file.
00001 namespace file_win32_helpers {
00002         static t_filesize get_size(HANDLE p_handle) {
00003                 union {
00004                         t_uint64 val64;
00005                         t_uint32 val32[2];
00006                 } u;
00007 
00008                 u.val64 = 0;
00009                 SetLastError(NO_ERROR);
00010                 u.val32[0] = GetFileSize(p_handle,reinterpret_cast<DWORD*>(&u.val32[1]));
00011                 if (GetLastError()!=NO_ERROR) exception_io_from_win32(GetLastError());
00012                 return u.val64;
00013         }
00014         static void seek(HANDLE p_handle,t_sfilesize p_position,file::t_seek_mode p_mode) {
00015                 union  {
00016                         t_int64 temp64;
00017                         struct {
00018                                 DWORD temp_lo;
00019                                 LONG temp_hi;
00020                         };
00021                 };
00022 
00023                 temp64 = p_position;
00024                 SetLastError(ERROR_SUCCESS);            
00025                 temp_lo = SetFilePointer(p_handle,temp_lo,&temp_hi,(DWORD)p_mode);
00026                 if (GetLastError() != ERROR_SUCCESS) exception_io_from_win32(GetLastError());
00027         }
00028 }
00029 
00030 template<bool p_seekable,bool p_writeable>
00031 class file_win32_wrapper_t : public file {
00032 public:
00033         file_win32_wrapper_t(HANDLE p_handle) : m_handle(p_handle), m_position(0)
00034         {
00035         }
00036 
00037         static service_ptr_t<file> g_CreateFile(const char * p_path,DWORD p_access,DWORD p_sharemode,LPSECURITY_ATTRIBUTES p_security_attributes,DWORD p_createmode,DWORD p_flags,HANDLE p_template) {
00038                 SetLastError(NO_ERROR);
00039                 HANDLE handle = uCreateFile(p_path,p_access,p_sharemode,p_security_attributes,p_createmode,p_flags,p_template);
00040                 if (handle == INVALID_HANDLE_VALUE) exception_io_from_win32(GetLastError());
00041                 try {
00042                         return g_create_from_handle(handle);
00043                 } catch(...) {CloseHandle(handle); throw;}
00044         }
00045 
00046         static service_ptr_t<file> g_create_from_handle(HANDLE p_handle) {
00047                 return new service_impl_t<file_win32_wrapper_t<p_seekable,p_writeable> >(p_handle);
00048         }
00049 
00050 
00051         void reopen(abort_callback & p_abort) {seek(0,p_abort);}
00052 
00053         void write(const void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
00054                 if (!p_writeable) throw exception_io_denied();
00055 
00056                 pfc::static_assert_t< (sizeof(t_size) >= sizeof(DWORD)) >();
00057 
00058                 t_size bytes_written_total = 0;
00059 
00060                 if (sizeof(t_size) == sizeof(DWORD)) {
00061                         p_abort.check_e();
00062                         DWORD bytes_written = 0;
00063                         SetLastError(ERROR_SUCCESS);
00064                         if (!WriteFile(m_handle,p_buffer,(DWORD)p_bytes,&bytes_written,0)) exception_io_from_win32(GetLastError());
00065                         if (bytes_written != p_bytes) throw exception_io("Write failure");
00066                         bytes_written_total = bytes_written;
00067                         m_position += bytes_written;
00068                 } else {
00069                         while(bytes_written_total < p_bytes) {
00070                                 p_abort.check_e();
00071                                 DWORD bytes_written = 0;
00072                                 DWORD delta = (DWORD) pfc::min_t<t_size>(p_bytes - bytes_written_total, 0x80000000);
00073                                 SetLastError(ERROR_SUCCESS);
00074                                 if (!WriteFile(m_handle,(const t_uint8*)p_buffer + bytes_written_total,delta,&bytes_written,0)) exception_io_from_win32(GetLastError());
00075                                 if (bytes_written != delta) throw exception_io("Write failure");
00076                                 bytes_written_total += bytes_written;
00077                                 m_position += bytes_written;
00078                         }
00079                 }
00080         }
00081         
00082         t_size read(void * p_buffer,t_size p_bytes,abort_callback & p_abort) {
00083                 pfc::static_assert_t< (sizeof(t_size) >= sizeof(DWORD)) >();
00084                 
00085                 t_size bytes_read_total = 0;
00086                 if (sizeof(t_size) == sizeof(DWORD)) {
00087                         p_abort.check_e();
00088                         DWORD bytes_read = 0;
00089                         SetLastError(ERROR_SUCCESS);
00090                         if (!ReadFile(m_handle,p_buffer,pfc::downcast_guarded<DWORD>(p_bytes),&bytes_read,0)) exception_io_from_win32(GetLastError());
00091                         bytes_read_total = bytes_read;
00092                         m_position += bytes_read;
00093                 } else {
00094                         while(bytes_read_total < p_bytes) {
00095                                 p_abort.check_e();
00096                                 DWORD bytes_read = 0;
00097                                 DWORD delta = (DWORD) pfc::min_t<t_size>(p_bytes - bytes_read_total, 0x80000000);
00098                                 SetLastError(ERROR_SUCCESS);
00099                                 if (!ReadFile(m_handle,(t_uint8*)p_buffer + bytes_read_total,delta,&bytes_read,0)) exception_io_from_win32(GetLastError());
00100                                 bytes_read_total += bytes_read;
00101                                 m_position += bytes_read;
00102                                 if (bytes_read != delta) break;
00103                         }
00104                 }
00105                 return bytes_read_total;
00106         }
00107 
00108 
00109         t_filesize get_size(abort_callback & p_abort) {
00110                 p_abort.check_e();
00111                 return file_win32_helpers::get_size(m_handle);
00112         }
00113 
00114         t_filesize get_position(abort_callback & p_abort) {
00115                 p_abort.check_e();
00116                 return m_position;
00117         }
00118         
00119         void resize(t_filesize p_size,abort_callback & p_abort) {
00120                 if (!p_writeable) throw exception_io_denied();
00121                 p_abort.check_e();
00122                 if (m_position != p_size) {
00123                         file_win32_helpers::seek(m_handle,p_size,file::seek_from_beginning);
00124                 }
00125                 SetLastError(ERROR_SUCCESS);
00126                 if (!SetEndOfFile(m_handle)) {
00127                         DWORD code = GetLastError();
00128                         if (m_position != p_size) try {file_win32_helpers::seek(m_handle,m_position,file::seek_from_beginning);} catch(...) {}
00129                         exception_io_from_win32(code);
00130                 }
00131                 if (m_position > p_size) m_position = p_size;
00132                 if (m_position != p_size) file_win32_helpers::seek(m_handle,m_position,file::seek_from_beginning);
00133         }
00134 
00135 #if 0
00136         void set_eof(abort_callback & p_abort) {
00137                 if (!p_writeable) throw exception_io_denied();
00138                 p_abort.check_e();
00139 
00140                 SetLastError(ERROR_SUCCESS);
00141                 if (!SetEndOfFile(m_handle)) exception_io_from_win32(GetLastError());
00142         }
00143 #endif
00144 
00145         void seek(t_filesize p_position,abort_callback & p_abort) {
00146                 if (!p_seekable) throw exception_io_object_not_seekable();
00147                 p_abort.check_e();
00148                 if (p_position > file_win32_helpers::get_size(m_handle)) throw exception_io_seek_out_of_range();
00149                 file_win32_helpers::seek(m_handle,p_position,file::seek_from_beginning);
00150                 m_position = p_position;
00151                 //return seek_ex((t_sfilesize)p_position,file::seek_from_beginning,p_abort);
00152         }
00153 #if 0
00154         void seek_ex(t_sfilesize p_position,file::t_seek_mode p_mode,abort_callback & p_abort) {
00155                 if (!p_seekable) throw exception_io_object_not_seekable();
00156                 p_abort.check_e();
00157 
00158                 file_win32_helpers::seek(m_handle,p_position,p_mode);
00159 
00160         m_position = (t_filesize) temp64;
00161         }
00162 #endif
00163 
00164         bool can_seek() {return p_seekable;}
00165         bool get_content_type(pfc::string_base & out) {return false;}
00166         bool is_in_memory() {return false;}
00167         void on_idle(abort_callback & p_abort) {p_abort.check_e();}
00168         
00169         t_filetimestamp get_timestamp(abort_callback & p_abort) {
00170                 p_abort.check_e();
00171                 FlushFileBuffers(m_handle);
00172                 SetLastError(ERROR_SUCCESS);
00173                 t_filetimestamp temp;
00174                 if (!GetFileTime(m_handle,0,0,(FILETIME*)&temp)) exception_io_from_win32(GetLastError());
00175                 return temp;
00176         }
00177 
00178         bool is_remote() {return false;}
00179         ~file_win32_wrapper_t() {CloseHandle(m_handle);}
00180 private:
00181         HANDLE m_handle;
00182         t_filesize m_position;
00183 };

Generated on Thu Aug 28 21:15:31 2008 for foobar2000 SDK by  doxygen 1.5.5