CFile source code
Last Update:2018-12-05
Source: Internet
Author: User
//////////////////////////////////////// /// // <Br/> // file-raw unbuffered disk file I/O </P> <p> class cfile: public cobject <br/>{< br/> declare_dynamic (cfile) </P> <p> public: <br/> // flag values <br/> Enum openflags {<br/> moderead = 0x0000 <br/> modewrite = 0x0001, <br/> modereadwrite = 0x0002, <br/> export compat = 0x0000, <br/> export exclusive = 0x0010, <br/> sharedenywrit E = 0x0020, <br/> sharedenyread = 0x0030, <br/> sharedenynone = 0x0040, <br/> modenoinherit = 0x0080, <br/> modecreate = 0x1000, <br/> modenotruncate = 0x2000, <br/> typetext = 0X4000, // typetext and typebinary are used in <br/> typebinary = (INT) 0x8000 // Derived classes only <br/> }; </P> <p> Enum attribute {<br/> normal = 0x00, x01, <br/> hidden = 0x02, <br/> system = 0x04, <br/> volume = 0x08, <br/> Director Y = 0x10, <br/> archive = 0x20 <br/>}; </P> <p> Enum seekposition {begin = 0x0, current = 0x1, end = 0x2}; </P> <p> Enum {hfilenull =-1 }; </P> <p> // constructors <br/> cfile (); <br/> cfile (INT hfile); <br/> cfile (lpctstr lpszfilename, uint nopenflags); </P> <p> // attributes <br/> uint m_hfile; <br/> operator hfile () const; </P> <p> virtual DWORD getposition () const; <br/> bool getstatus (cfilestatus & rstatus) con St; <br/> virtual cstring getfilename () const; <br/> virtual cstring getfiletitle () const; <br/> virtual cstring getfilepath () const; <br/> virtual void setfilepath (lpctstr lpsznewname); </P> <p> // Operations <br/> virtual bool open (lpctstr lpszfilename, uint nopenflags, <br/> cfileexception * perror = NULL); </P> <p> static void Pascal Rename (lpctstr lpszoldname, <br/> lpctstr lpsznewname ); <br/> static void P Ascal remove (lpctstr lpszfilename); <br/> static bool Pascal getstatus (lpctstr lpszfilename, <br/> cfilestatus & rstatus); <br/> static void Pascal setstatus (lpctstr lpszfilename, <br/> const cfilestatus & status); </P> <p> DWORD seektoend (); <br/> void seektobegin (); </P> <p> // backward compatible readhuge and writehuge <br/> DWORD readhuge (void * lpbuffer, DWORD dwcount); <br/> void writehuge (const void * lpbuf Fer, DWORD dwcount); </P> <p> // overridables <br/> virtual cfile * duplicate () const; </P> <p> virtual long seek (long Loff, uint nfrom); <br/> virtual void setlength (DWORD dwnewlen); <br/> virtual DWORD getlength () const; </P> <p> virtual uint read (void * lpbuf, uint ncount); <br/> virtual void write (const void * lpbuf, uint ncount ); </P> <p> virtual void lockrange (DWORD dwpos, DWORD dwcount); <br/> virtual void unl Ockrange (DWORD dwpos, DWORD dwcount); </P> <p> virtual void abort (); <br/> virtual void flush (); <br/> virtual void close (); </P> <p> // implementation <br/> Public: <br/> virtual ~ Cfile (); <br/> # ifdef _ debug <br/> virtual void assertvalid () const; <br/> virtual void dump (cdumpcontext & DC) const; <br/> # endif <br/> Enum buffercommand {bufferread, bufferwrite, buffercommit, buffercheck}; <br/> virtual uint getbufferptr (uint ncommand, uint ncount = 0, <br/> void ** ppbufstart = null, void ** ppbufmax = NULL); </P> <p> protected: <br/> bool m_bcloseondelete; <br/> cstring m_strfilename; <br /> }; </P> <p> ///////////////////////////////// //////////////////////////////////////// /// <br/> // cfile implementation </P> <p> cfile:: cfile () <br/>{< br/> m_hfile = (uint) hfilenull; <br/> m_bcloseondelete = false; <br/>}</P> <p> cfile: cfile (INT hfile) <br/>{< br/> m_hfile = hfile; <br/> m_bcloseondelete = false; <br/>}</P> <p> cfile: cfile (lpctstr lpszfilename, uint nopenflags) <br/>{< br/> assert (afxisvali Dstring (lpszfilename); </P> <p> cfileexception E; <br/> If (! Open (lpszfilename, nopenflags, & E) <br/> afxthrowfileexception (E. m_cause, E. m_loserror, E. m_strfilename); <br/>}</P> <p> cfile ::~ Cfile () <br/>{< br/> If (m_hfile! = (Uint) hfilenull & m_bcloseondelete) <br/> close (); <br/>}</P> <p> cfile * cfile: duplicate () const <br/>{< br/> assert_valid (this); <br/> assert (m_hfile! = (Uint) hfilenull); </P> <p> cfile * pfile = new cfile (hfilenull); <br/> handle hfile; <br/> If (!: Duplicatehandle (: getcurrentprocess (), (handle) m_hfile, <br/>: getcurrentprocess (), & hfile, 0, false, duplicate_same_access )) <br/>{< br/> Delete pfile; <br/> cfileexception: throwoserror (long): getlasterror ()); <br/>}< br/> pfile-> m_hfile = (uint) hfile; <br/> assert (pfile-> m_hfile! = (Uint) hfilenull); <br/> pfile-> m_bcloseondelete = m_bcloseondelete; <br/> return pfile; <br/>}</P> <p> bool cfile:: open (lpctstr lpszfilename, uint nopenflags, <br/> cfileexception * pexception) <br/>{< br/> assert_valid (this ); <br/> assert (afxisvalidstring (lpszfilename); <br/> assert (pexception = NULL | <br/> afxisvalidaddress (pexception, sizeof (cfileexception ))); <br/> assert (nopenflags & typetext) = 0); // text mode not supported </P> <p> // cfile objects are always binary and createfile does not need flag <br/> nopenflags & = ~ (Uint) typebinary; </P> <p> m_bcloseondelete = false; <br/> m_hfile = (uint) hfilenull; <br/> m_strfilename.empty (); </P> <p> tchar sztemp [_ max_path]; <br/> afxfullpath (sztemp, lpszfilename); <br/> m_strfilename = sztemp; </P> <p> assert (sizeof (handle) = sizeof (uint); <br/> assert (random compat = 0 ); </P> <p> // map read/write mode <br/> assert (moderead | modewrite | modereadwrite) = 3 ); <br/> DWORD dwaccess = 0; <br/> S Witch (nopenflags & 3) <br/>{< br/> case moderead: <br/> dwaccess = generic_read; <br/> break; <br/> case modewrite: <br/> dwaccess = generic_write; <br/> break; <br/> case modereadwrite: <br/> dwaccess = generic_read | generic_write; <br/> break; <br/> default: <br/> assert (false ); // invalid share mode <br/>}</P> <p> // map share mode <br/> DWORD dw1_mode = 0; <br/> switch (nopenflags & 0x70) // map compatibi Lity mode to exclusive <br/>{< br/> default: <br/> assert (false); // invalid share mode? <Br/> case when compat: <br/> case when exclusive: <br/> dw1_mode = 0; <br/> break; <br/> case sharedenywrite: <br/> dw1_mode = file_1__read; <br/> break; <br/> case sharedenyread: <br/> dw1_mode = file_1__write; <br/> break; <br/> case sharedenynone: <br/> dw1_mode = file_0000_write | file_0000_read; <br/> break; <br/>}</P> <p> // note: typetext and typebinary are used in Derived classes only. </P> <p> // map modenoinherit flag <br/> security_attributes SA; <br/> SA. nlength = sizeof (SA); <br/> SA. lpsecuritydescriptor = NULL; <br/> SA. binherithandle = (nopenflags & modenoinherit) = 0; </P> <p> // map creation flags <br/> DWORD dwcreateflag; <br/> If (nopenflags & modecreate) <br/>{< br/> If (nopenflags & modenotruncate) <br/> dwcreateflag = open_always; <br/> else <br/> dwcreateflag = create_always; <B R/>}< br/> else <br/> dwcreateflag = open_existing; </P> <p> // attempt file creation <br/> handle hfile = :: createfile (lpszfilename, dwaccess, dwsharemode, & SA, <br/> dwcreateflag, file_attribute_normal, null); <br/> If (hfile = invalid_handle_value) <br/>{< br/> If (pexception! = NULL) <br/>{< br/> pexception-> m_loserror =: getlasterror (); <br/> pexception-> m_cause = <br/> cfileexception :: oserrortoexception (pexception-> m_loserror); </P> <p> // use passed file name (not expanded vesion) when reporting <br/> // an error while opening </P> <p> pexception-> m_strfilename = lpszfilename; <br/>}< br/> return false; <br/>}< br/> m_hfile = (hfile) hfile; <br/> m_bcloseondelete = true; </P> <p> re Turn true; <br/>}</P> <p> uint cfile: Read (void * lpbuf, uint ncount) <br/>{< br/> assert_valid (this); <br/> assert (m_hfile! = (Uint) hfilenull); </P> <p> If (ncount = 0) <br/> return 0; // avoid Win32 "null-read" </P> <p> assert (lpbuf! = NULL); <br/> assert (afxisvalidaddress (lpbuf, ncount); </P> <p> DWORD dwread; <br/> If (!: Readfile (handle) m_hfile, lpbuf, ncount, & dwread, null) <br/> cfileexception: throwoserror (long): getlasterror ()); </P> <p> return (uint) dwread; <br/>}</P> <p> void cfile: Write (const void * lpbuf, uint ncount) <br/>{< br/> assert_valid (this); <br/> assert (m_hfile! = (Uint) hfilenull); </P> <p> If (ncount = 0) <br/> return; // avoid Win32 "null-write" option </P> <p> assert (lpbuf! = NULL); <br/> assert (afxisvalidaddress (lpbuf, ncount, false); </P> <p> DWORD nwritten; <br/> If (!: Writefile (handle) m_hfile, lpbuf, ncount, & nwritten, null) <br/> cfileexception: throwoserror (long): getlasterror (), m_strfilename ); </P> <p> // win32s will not return an error all the time (usually disk_full) <br/> If (nwritten! = Ncount) <br/> afxthrowfileexception (cfileexception: diskfull,-1, m_strfilename); <br/>}</P> <p> long cfile :: seek (long Loff, uint nfrom) <br/>{< br/> assert_valid (this); <br/> assert (m_hfile! = (Uint) hfilenull); <br/> assert (nfrom = begin | nfrom = end | nfrom = Current ); <br/> assert (begin = file_begin & End = file_end & current = file_current); </P> <p> DWORD dwnew = :: setfilepointer (handle) m_hfile, Loff, null, (DWORD) nfrom); <br/> If (dwnew = (DWORD)-1) <br/> cfileexception :: throwoserror (long): getlasterror (); </P> <p> return dwnew; <br/>}</P> <p> DWORD cfile :: getposition () const <B R/>{< br/> assert_valid (this); <br/> assert (m_hfile! = (Uint) hfilenull); </P> <p> DWORD dwpos =: setfilepointer (handle) m_hfile, 0, null, file_current ); <br/> If (dwpos = (DWORD)-1) <br/> cfileexception: throwoserror (long): getlasterror ()); </P> <p> return dwpos; <br/>}</P> <p> void cfile: flush () <br/>{< br/> assert_valid (this); </P> <p> If (m_hfile = (uint) hfilenull) <br/> return; </P> <p> If (!: Flushfilebuffers (handle) m_hfile) <br/> cfileexception: throwoserror (long): getlasterror ()); <br/>}</P> <p> void cfile: Close () <br/>{< br/> assert_valid (this ); <br/> assert (m_hfile! = (Uint) hfilenull); </P> <p> bool berror = false; <br/> If (m_hfile! = (Uint) hfilenull) <br/> berror =!: Closehandle (handle) m_hfile); </P> <p> m_hfile = (uint) hfilenull; <br/> m_bcloseondelete = false; <br/> m_strfilename.empty (); </P> <p> If (berror) <br/> cfileexception: throwoserror (long): getlasterror ()); <br/>}</P> <p> void cfile: Abort () <br/>{< br/> assert_valid (this ); <br/> If (m_hfile! = (Uint) hfilenull) <br/>{< br/> // close but ignore errors <br/>: closehandle (handle) m_hfile ); <br/> m_hfile = (uint) hfilenull; <br/>}< br/> m_strfilename.empty (); <br/>}</P> <p> void cfile :: lockrange (DWORD dwpos, DWORD dwcount) <br/>{< br/> assert_valid (this); <br/> assert (m_hfile! = (Uint) hfilenull); </P> <p> If (!: Lockfile (handle) m_hfile, dwpos, 0, dwcount, 0) <br/> cfileexception: throwoserror (long): getlasterror ()); <br/>}</P> <p> void cfile: unlockrange (DWORD dwpos, DWORD dwcount) <br/>{< br/> assert_valid (this ); <br/> assert (m_hfile! = (Uint) hfilenull); </P> <p> If (!: Unlockfile (handle) m_hfile, dwpos, 0, dwcount, 0) <br/> cfileexception: throwoserror (long): getlasterror ()); <br/>}</P> <p> void cfile: setlength (DWORD dwnewlen) <br/>{< br/> assert_valid (this ); <br/> assert (m_hfile! = (Uint) hfilenull); </P> <p> seek (long) dwnewlen, (uint) Begin); </P> <p> If (!: Setendoffile (handle) m_hfile) <br/> cfileexception: throwoserror (long): getlasterror ()); <br/>}</P> <p> DWORD cfile: getlength () const <br/>{< br/> assert_valid (this ); </P> <p> DWORD dwlen, dwcur; </P> <p> // seek is a non const operation <br/> cfile * pfile = (cfile *) this; <br/> dwcur = pfile-> seek (0l, current); <br/> dwlen = pfile-> seektoend (); <br/> verify (dwcur = (DWORD) pfile-> seek (dwcur, begin); </P> <p> Return dwlen; <br/>}</P> <p> // cfile does not support direct buffering (cmemfile does) <br/> uint cfile: getbufferptr (uint ncommand, uint/* ncount */, <br/> void **/* ppbufstart */, void **/* ppbufmax */) <br/>{< br/> assert (ncommand = buffercheck); <br/> unused (ncommand ); // not used in retail build </P> <p> return 0; // no support <br/>}</P> <p> void Pascal cfile :: rename (maid, maid Me) <br/>{< br/> If (!: Movefile (lptstr) lpszoldname, (lptstr) lpsznewname) <br/> cfileexception: throwoserror (long): getlasterror ()); <br/>}</P> <p> void Pascal cfile: Remove (lpctstr lpszfilename) <br/>{< br/> If (!: Deletefile (lptstr) lpszfilename) <br/> cfileexception: throwoserror (long): getlasterror (); <br/>}< br/>