home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK10 / MFC / SRC / FILEMEM.CP$ / filemem
Encoding:
Text File  |  1992-01-18  |  6.0 KB  |  305 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 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
  305.