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