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