|
|
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 <limits.h>
15: #include <malloc.h>
16:
17: #ifdef AFX_CORE_SEG
18: #pragma code_seg(AFX_CORE_SEG)
19: #endif
20:
21: #ifdef _DEBUG
22: #undef THIS_FILE
23: static char BASED_CODE THIS_FILE[] = __FILE__;
24: #endif
25:
26: #define new DEBUG_NEW
27:
28: ////////////////////////////////////////////////////////////////////////////
29: // CMemFile implementation
30:
31: IMPLEMENT_DYNAMIC(CMemFile, CFile)
32:
33: CMemFile::CMemFile(UINT nGrowBytes /* = 1024 */)
34: {
35: ASSERT(nGrowBytes <= USHRT_MAX);
36:
37: m_hFile = hFileNull;
38: m_nGrowBytes = nGrowBytes;
39: m_nPosition = 0;
40: m_nBufferSize = 0;
41: m_nFileSize = 0;
42: m_lpBuffer = NULL;
43: m_nBufferSize = 0;
44: }
45:
46: CMemFile::~CMemFile()
47: {
48: // Close should have already been called, but we check anyway
49: if (m_lpBuffer)
50: Close();
51: ASSERT(m_lpBuffer == NULL);
52:
53: m_nGrowBytes = 0;
54: m_nPosition = 0;
55: m_nBufferSize = 0;
56: m_nFileSize = 0;
57: }
58:
59: BYTE FAR*
60: CMemFile::Alloc(UINT nBytes)
61: {
62: return (BYTE FAR*)_fmalloc(nBytes);
63: }
64:
65: BYTE FAR*
66: CMemFile::Realloc(BYTE FAR* pMem, UINT nBytes)
67: {
68: return (BYTE FAR*)_frealloc(pMem, nBytes);
69: }
70:
71: BYTE FAR*
72: CMemFile::Memcpy(BYTE FAR* pMemTarget, const BYTE FAR* pMemSource, UINT nBytes)
73: {
74: ASSERT(pMemTarget != NULL);
75: ASSERT(pMemSource != NULL);
76: ASSERT(AfxIsValidAddress(pMemTarget, nBytes));
77: ASSERT(AfxIsValidAddress(pMemSource, nBytes, FALSE));
78:
79: return (BYTE FAR*)_fmemcpy(pMemTarget, pMemSource, nBytes);
80: }
81:
82: void
83: CMemFile::Free(BYTE FAR* pMem)
84: {
85: ASSERT(pMem != NULL);
86:
87: _ffree(pMem);
88: }
89:
90: DWORD
91: CMemFile::GetPosition() const
92: {
93: ASSERT_VALID(this);
94: return (DWORD)m_nPosition;
95: }
96:
97: void
98: CMemFile::GrowFile(DWORD dwNewLen)
99: {
100: ASSERT_VALID(this);
101: ASSERT((dwNewLen & 0xFFFF0000) == 0L);
102:
103: if (dwNewLen > m_nBufferSize)
104: {
105: // grow the buffer
106: DWORD dwNewBufferSize = (DWORD)m_nBufferSize;
107:
108: while (dwNewBufferSize < dwNewLen)
109: dwNewBufferSize += m_nGrowBytes;
110:
111: if (dwNewBufferSize > USHRT_MAX)
112: AfxThrowFileException(CFileException::diskFull);
113: ASSERT((dwNewBufferSize & 0xFFFF0000) == 0L);
114:
115: BYTE FAR* lpNew;
116: if (m_lpBuffer == NULL)
117: lpNew = Alloc((UINT)dwNewBufferSize);
118: else
119: lpNew = Realloc(m_lpBuffer, (UINT)dwNewBufferSize);
120:
121: if (lpNew == NULL)
122: AfxThrowMemoryException();
123:
124: m_lpBuffer = lpNew;
125: m_nBufferSize = (UINT)dwNewBufferSize;
126: }
127: ASSERT_VALID(this);
128: }
129:
130: void
131: CMemFile::SetLength(DWORD dwNewLen)
132: {
133: ASSERT_VALID(this);
134: ASSERT((UINT)dwNewLen <= USHRT_MAX);
135:
136: if (dwNewLen > m_nBufferSize)
137: GrowFile(dwNewLen);
138:
139: if (dwNewLen < m_nPosition)
140: m_nPosition = (UINT)dwNewLen;
141:
142: m_nFileSize = (UINT)dwNewLen;
143: ASSERT_VALID(this);
144: }
145:
146:
147: UINT
148: CMemFile::Read(void FAR* lpBuf, UINT nCount)
149: {
150: ASSERT_VALID(this);
151: ASSERT(lpBuf != NULL);
152: ASSERT(AfxIsValidAddress(lpBuf, nCount));
153:
154: UINT nRead;
155:
156: if (m_nPosition > m_nFileSize)
157: return 0;
158:
159: if (m_nPosition + nCount > m_nFileSize)
160: nRead = m_nFileSize - m_nPosition;
161: else
162: nRead = nCount;
163:
164: Memcpy((BYTE FAR*)lpBuf, m_lpBuffer + m_nPosition, nRead);
165: m_nPosition += nRead;
166:
167: ASSERT_VALID(this);
168:
169: return nRead;
170: }
171:
172: void
173: CMemFile::Write(const void FAR* lpBuf, UINT nCount)
174: {
175: ASSERT_VALID(this);
176: ASSERT(lpBuf != NULL);
177: ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));
178:
179: if (m_nPosition + nCount > m_nBufferSize)
180: GrowFile(m_nPosition + nCount);
181:
182: ASSERT(m_nPosition + nCount <= m_nBufferSize);
183:
184: Memcpy(m_lpBuffer + m_nPosition, (BYTE FAR*)lpBuf, nCount);
185:
186: m_nPosition += nCount;
187:
188: if (m_nPosition > m_nFileSize)
189: m_nFileSize = m_nPosition;
190:
191: ASSERT_VALID(this);
192: }
193:
194:
195: LONG
196: CMemFile::Seek(LONG lOff, UINT nFrom)
197: {
198: ASSERT_VALID(this);
199: ASSERT(lOff <= USHRT_MAX);
200: ASSERT(nFrom == CFile::begin || nFrom == CFile::end || nFrom == CFile::current);
201:
202: LONG lNewPos = m_nPosition;
203:
204: if (nFrom == CFile::begin)
205: lNewPos = lOff;
206: else if (nFrom == CFile::current)
207: lNewPos += lOff;
208: else if (nFrom == CFile::end)
209: lNewPos = m_nFileSize + lOff;
210: else
211: return -1;
212:
213: if (lNewPos < 0)
214: AfxThrowFileException(CFileException::badSeek);
215:
216: m_nPosition = (UINT)lNewPos;
217:
218: ASSERT_VALID(this);
219: return m_nPosition;
220: }
221:
222: void
223: CMemFile::Flush()
224: {
225: ASSERT_VALID(this);
226: }
227:
228: void
229: CMemFile::Close()
230: {
231: ASSERT_VALID(this);
232: m_nGrowBytes = 0;
233: m_nPosition = 0;
234: m_nBufferSize = 0;
235: m_nFileSize = 0;
236: if (m_lpBuffer)
237: Free(m_lpBuffer);
238: m_lpBuffer = NULL;
239: }
240:
241: void
242: CMemFile::LockRange(DWORD /* dwPos */, DWORD /* dwCount */)
243: {
244: ASSERT_VALID(this);
245: AfxThrowNotSupportedException();
246: }
247:
248:
249: void
250: CMemFile::UnlockRange(DWORD /* dwPos */, DWORD /* dwCount */)
251: {
252: ASSERT_VALID(this);
253: AfxThrowNotSupportedException();
254: }
255:
256: CFile*
257: CMemFile::Duplicate() const
258: {
259: ASSERT_VALID(this);
260: AfxThrowNotSupportedException();
261: return NULL;
262: }
263:
264: BOOL
265: CMemFile::GetStatus(CFileStatus& rStatus) const
266: {
267: ASSERT_VALID(this);
268:
269: rStatus.m_ctime = 0;
270: rStatus.m_mtime = 0;
271: rStatus.m_atime = 0;
272: rStatus.m_size = m_nFileSize;
273: rStatus.m_attribute = CFile::normal;
274: rStatus.m_szFullName[0] = '\0';
275: return TRUE;
276: }
277:
278: #ifdef _DEBUG
279:
280: void
281: CMemFile::Dump(CDumpContext& dc) const
282: {
283: ASSERT_VALID(this);
284:
285: CFile::Dump(dc);
286:
287: dc << "\n\tfile size = " << m_nFileSize;
288: dc << "\n\tbuffer size = " << m_nBufferSize;
289: dc << "\n\tposition = " << m_nPosition;
290: dc << "\n\tgrowth rate = " << m_nGrowBytes;
291: }
292:
293: void
294: CMemFile::AssertValid() const
295: {
296: CFile::AssertValid();
297:
298: ASSERT((m_lpBuffer == NULL && m_nBufferSize == 0) || AfxIsValidAddress(m_lpBuffer, m_nBufferSize));
299: ASSERT(m_nFileSize <= m_nBufferSize);
300: // m_nPosition might be after the end of file, so we cannot ASSERT
301: // its validity
302: }
303:
304: #endif // _DEBUG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.