|
|
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.