home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c031 / 10.ddi / MFC / SRC / FILETXT.CP$ / filetxt
Encoding:
Text File  |  1992-03-08  |  7.3 KB  |  336 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and Microsoft
  7. // QuickHelp documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "afx.h"
  12. #pragma hdrstop
  13.  
  14. #include <errno.h>
  15.  
  16. #ifdef AFX_AUX_SEG
  17. #pragma code_seg(AFX_AUX_SEG)
  18. #endif
  19.  
  20. #define CFile_shareMask ((UINT)(CFile::shareExclusive | CFile::shareDenyWrite | CFile::shareDenyRead | CFile::shareDenyNone | CFile::shareCompat))
  21.  
  22. // buffer size for small and medium model Read/Write operations
  23. #define nLocalBuf ((UINT)525)
  24.  
  25. #ifdef _DEBUG
  26. #undef THIS_FILE
  27. static char BASED_CODE THIS_FILE[] = __FILE__;
  28. #endif
  29.  
  30. #define new DEBUG_NEW
  31.  
  32. ////////////////////////////////////////////////////////////////////////////
  33. // CStdioFile implementation
  34.  
  35. IMPLEMENT_DYNAMIC(CStdioFile, CFile)
  36.  
  37. CStdioFile::CStdioFile()
  38. {
  39.     m_pStream = NULL;
  40. }
  41.  
  42. CStdioFile::CStdioFile(FILE* pOpenStream) : CFile(hFileNull)
  43. {
  44.     m_pStream = pOpenStream;
  45.     m_hFile = _fileno(pOpenStream);
  46. }
  47.  
  48. CStdioFile::CStdioFile(const char* pszFileName, UINT nOpenFlags)
  49. {
  50.     ASSERT(pszFileName != NULL);
  51.     ASSERT(AfxIsValidAddress(pszFileName, strlen(pszFileName), FALSE));
  52.  
  53.     CFileException e;
  54.     if (!Open(pszFileName, nOpenFlags, &e))
  55.         AfxThrowFileException(e.m_cause, e.m_lOsError);
  56. }
  57.  
  58. CStdioFile::~CStdioFile()
  59. {   
  60.     ASSERT_VALID(this);
  61.  
  62.     if (m_pStream && m_bCloseOnDelete)
  63.         Close();
  64. }
  65.  
  66. BOOL
  67. CStdioFile::Open(const char* pszFileName, UINT nOpenFlags, CFileException* pException)
  68. {
  69.     ASSERT(pException == NULL || AfxIsValidAddress(pException, sizeof(CFileException)));
  70.     ASSERT(pszFileName != NULL);
  71.     ASSERT(AfxIsValidAddress(pszFileName, strlen(pszFileName), FALSE));
  72.     ASSERT((nOpenFlags & CFile_shareMask) == 0);
  73.  
  74.     m_hFile = hFileNull;
  75.     m_bCloseOnDelete = FALSE;
  76.  
  77.     char szMode[4];
  78.     int nMode = 0;
  79.  
  80.     if (nOpenFlags & CFile::modeCreate)
  81.         szMode[nMode++] = 'w';
  82.     else if (nOpenFlags & CFile::modeWrite)
  83.         szMode[nMode++] = 'a';
  84.     else
  85.         szMode[nMode++] = 'r';
  86.     
  87.     if (nOpenFlags & CFile::modeReadWrite)
  88.         szMode[nMode++] = '+';
  89.  
  90.     if (nOpenFlags & CFile::typeBinary)
  91.         szMode[nMode++] = 'b';
  92.     else
  93.         szMode[nMode++] = 't';
  94.  
  95.     szMode[nMode++] = '\0';
  96.         
  97.     if ((m_pStream = fopen(pszFileName, szMode)) == NULL)
  98.     {
  99.         if (pException != NULL)
  100.         {
  101.             pException->m_lOsError = _doserrno;
  102.             pException->m_cause = CFileException::accessDenied;
  103.         }
  104.         return FALSE;
  105.     }
  106.  
  107.     m_hFile = _fileno(m_pStream);
  108.     m_bCloseOnDelete = TRUE;
  109.     return TRUE;
  110. }
  111.  
  112. UINT
  113. CStdioFile::Read(void FAR* lpBuf, UINT nCount)
  114. {
  115.     ASSERT_VALID(this);
  116.     ASSERT(m_pStream != NULL);
  117.     ASSERT(AfxIsValidAddress(lpBuf, nCount));
  118.  
  119.     UINT nRead = 0;
  120.  
  121. #ifdef _NEARDATA
  122.     // S/M model, need to copy lpBuf to NEAR data (_read is NEAR)
  123.     char buf[nLocalBuf];
  124.     UINT nReadReq = 0;
  125.     UINT nReadCur = 0;
  126.     UINT nReadT = 0;
  127.  
  128.     while (nReadCur < nCount )
  129.     {
  130.         nReadReq = ((nCount - nRead < nLocalBuf) ? nCount - nRead : nLocalBuf);
  131.         nReadT = fread(buf, sizeof(BYTE), nReadReq, m_pStream);
  132.         nRead += nReadT;
  133.  
  134.         _fmemcpy(lpBuf, buf, nReadT);
  135.         lpBuf = (BYTE FAR*)lpBuf + nReadT;
  136.  
  137.         if (nReadT < nReadReq)
  138.         {
  139.             if (feof(m_pStream) && !ferror(m_pStream))
  140.                 break;
  141.             else
  142.             {
  143.                 clearerr(m_pStream);
  144.                 AfxThrowFileException(CFileException::generic, _doserrno);
  145.             }
  146.         }
  147.         nReadCur += nReadReq;
  148.     }
  149.     
  150. #else
  151.     if ((nRead = fread(lpBuf, sizeof(BYTE), nCount, m_pStream)) == 0 && !feof(m_pStream))
  152.         AfxThrowFileException(CFileException::generic, _doserrno);
  153. #endif
  154.     if (ferror(m_pStream ))
  155.     {
  156.         clearerr(m_pStream);
  157.         AfxThrowFileException(CFileException::generic, _doserrno);
  158.     }
  159.     return nRead;
  160. }
  161.  
  162. void
  163. CStdioFile::Write(const void FAR* lpBuf, UINT nCount)
  164. {
  165.     ASSERT_VALID(this);
  166.     ASSERT(m_pStream != NULL);
  167.     ASSERT(lpBuf != NULL);
  168.  
  169.     ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));
  170.  
  171. #ifdef _NEARDATA
  172.     // S/M model, need to copy lpBuf to NEAR data (_read is NEAR)
  173.     void FAR* lpBufT = (void FAR*)lpBuf;
  174.     UINT nWrite = 0;
  175.  
  176.     while (nWrite < nCount)
  177.     {
  178.         char buf[nLocalBuf];
  179.         UINT nWriteT;
  180.  
  181.         _fmemcpy(buf, lpBufT,(nWriteT = nCount - nWrite < nLocalBuf ? nCount - nWrite : nLocalBuf));
  182.         if (fwrite(buf, sizeof(BYTE), nWriteT, m_pStream) != nWriteT)
  183.             AfxThrowFileException(CFileException::generic, _doserrno);
  184.         lpBufT = (BYTE FAR*)lpBufT + nWriteT;
  185.         nWrite += nWriteT;
  186.     }
  187. #else
  188.     if (fwrite(lpBuf, sizeof(BYTE), nCount, m_pStream) == -1)
  189.         AfxThrowFileException(CFileException::generic, _doserrno);
  190. #endif
  191. }
  192.  
  193.  
  194. void
  195. CStdioFile::WriteString(const char FAR* lpsz)
  196. {
  197.     ASSERT(lpsz != NULL);
  198.     ASSERT(m_pStream != NULL);
  199.  
  200.     register char ch;
  201.     while ((ch = *lpsz++) != '\0')
  202.         if (fputc(ch, m_pStream) == EOF)
  203.             AfxThrowFileException(CFileException::diskFull, _doserrno);
  204. }
  205.  
  206. char FAR*   
  207. CStdioFile::ReadString(char FAR* lpsz, UINT nMax)
  208. {
  209.     ASSERT(lpsz != NULL);
  210.     ASSERT(AfxIsValidAddress(lpsz, nMax));
  211.     ASSERT(m_pStream != NULL);
  212.  
  213.     register UINT nRead = 0;
  214.     register char FAR* lpszT = lpsz;
  215.  
  216.     while ((UINT)nRead < nMax - 1)
  217.     {
  218.         int chOrEOF; // because it could be an EOF which isn't a char
  219.  
  220.         if ((chOrEOF = fgetc(m_pStream)) == EOF)
  221.         {
  222.             if (feof(m_pStream))
  223.                 break;
  224.             // real error
  225.             clearerr(m_pStream);
  226.             AfxThrowFileException(CFileException::generic, _doserrno);
  227.         }
  228.         nRead++;
  229.         if ((*lpszT++ = (char)chOrEOF) == '\n')
  230.             break;
  231.     }
  232.     *lpszT = '\0';
  233.     return (lpsz == lpszT ? NULL : lpsz);
  234. }
  235.  
  236. LONG
  237. CStdioFile::Seek(LONG lOff, UINT nFrom)
  238. {
  239.     ASSERT_VALID(this);
  240.     ASSERT(nFrom == CFile::begin || nFrom == CFile::end || nFrom == CFile::current);
  241.     ASSERT(sizeof(fpos_t) <= sizeof(DWORD));
  242.     ASSERT(m_pStream != NULL);
  243.  
  244.     fpos_t pos;
  245.  
  246.     if (fseek(m_pStream, lOff, nFrom) != 0)
  247.         AfxThrowFileException(CFileException::badSeek, _doserrno);
  248.     
  249.     fgetpos(m_pStream, &pos);
  250.     return (DWORD)pos;
  251. }
  252.  
  253.  
  254. DWORD
  255. CStdioFile::GetPosition() const
  256. {
  257.     ASSERT_VALID(this);
  258.     ASSERT(sizeof(fpos_t) <= sizeof(DWORD));
  259.     ASSERT(m_pStream != NULL);
  260.  
  261.     fpos_t pos;
  262.  
  263.     if (fgetpos(m_pStream, &pos) != 0)
  264.         AfxThrowFileException(CFileException::invalidFile, _doserrno);
  265.     
  266.     return (DWORD)pos;
  267. }
  268.  
  269.  
  270. void
  271. CStdioFile::Flush()
  272. {
  273.     ASSERT_VALID(this);
  274.     ASSERT(m_pStream != NULL);
  275.  
  276.     if (fflush(m_pStream) != 0)
  277.         AfxThrowFileException(CFileException::endOfFile, _doserrno);
  278. }
  279.  
  280. void
  281. CStdioFile::Close()
  282. {
  283.     ASSERT_VALID(this);
  284.     ASSERT(m_pStream != NULL);
  285.  
  286.     if (m_pStream && fclose(m_pStream))
  287.         AfxThrowFileException(CFileException::invalidFile, _doserrno);
  288.  
  289.     m_hFile = hFileNull;
  290.     m_bCloseOnDelete = FALSE;
  291.     m_pStream = NULL;
  292. }
  293.  
  294. CFile*
  295. CStdioFile::Duplicate() const
  296. {
  297.     ASSERT_VALID(this);
  298.     ASSERT(m_pStream != NULL);
  299.  
  300.     AfxThrowNotSupportedException();
  301.     return NULL;
  302. }
  303.  
  304. void
  305. CStdioFile::LockRange(DWORD /* dwPos */, DWORD /* dwCount */)
  306. {
  307.     ASSERT_VALID(this);
  308.     ASSERT(m_pStream != NULL);
  309.  
  310.     AfxThrowNotSupportedException();
  311. }
  312.  
  313.  
  314. void
  315. CStdioFile::UnlockRange(DWORD /* dwPos */, DWORD /* dwCount */)
  316. {
  317.     ASSERT_VALID(this);
  318.     ASSERT(m_pStream != NULL);
  319.  
  320.     AfxThrowNotSupportedException();
  321. }
  322.  
  323.  
  324. #ifdef _DEBUG
  325. void
  326. CStdioFile::Dump(CDumpContext& dc) const
  327. {
  328.     ASSERT_VALID(this);
  329.  
  330.     CFile::Dump(dc);
  331.  
  332.     dc << " and FILE* " << (void*)m_pStream << " ";
  333. }
  334. #endif
  335.  
  336.