|
|
1.1 ! root 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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.