|
|
Microsoft Windows NT Build 297 06-28-1992
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and Microsoft
// QuickHelp documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "afx.h"
#pragma hdrstop
#include <errno.h>
#ifdef AFX_AUX_SEG
#pragma code_seg(AFX_AUX_SEG)
#endif
#define CFile_shareMask ((UINT)(CFile::shareExclusive | CFile::shareDenyWrite | CFile::shareDenyRead | CFile::shareDenyNone | CFile::shareCompat))
// buffer size for small and medium model Read/Write operations
#define nLocalBuf ((UINT)525)
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
////////////////////////////////////////////////////////////////////////////
// CStdioFile implementation
IMPLEMENT_DYNAMIC(CStdioFile, CFile)
CStdioFile::CStdioFile()
{
m_pStream = NULL;
}
CStdioFile::CStdioFile(FILE* pOpenStream) : CFile(hFileNull)
{
m_pStream = pOpenStream;
m_hFile = _fileno(pOpenStream);
}
CStdioFile::CStdioFile(const char* pszFileName, UINT nOpenFlags)
{
ASSERT(pszFileName != NULL);
ASSERT(AfxIsValidAddress(pszFileName, strlen(pszFileName), FALSE));
CFileException e;
if (!Open(pszFileName, nOpenFlags, &e))
AfxThrowFileException(e.m_cause, e.m_lOsError);
}
CStdioFile::~CStdioFile()
{
ASSERT_VALID(this);
if (m_pStream && m_bCloseOnDelete)
Close();
}
BOOL
CStdioFile::Open(const char* pszFileName, UINT nOpenFlags, CFileException* pException)
{
ASSERT(pException == NULL || AfxIsValidAddress(pException, sizeof(CFileException)));
ASSERT(pszFileName != NULL);
ASSERT(AfxIsValidAddress(pszFileName, strlen(pszFileName), FALSE));
ASSERT((nOpenFlags & CFile_shareMask) == 0);
m_hFile = hFileNull;
m_bCloseOnDelete = FALSE;
char szMode[4];
int nMode = 0;
if (nOpenFlags & CFile::modeCreate)
szMode[nMode++] = 'w';
else if (nOpenFlags & CFile::modeWrite)
szMode[nMode++] = 'a';
else
szMode[nMode++] = 'r';
if (nOpenFlags & CFile::modeReadWrite)
szMode[nMode++] = '+';
if (nOpenFlags & CFile::typeBinary)
szMode[nMode++] = 'b';
else
szMode[nMode++] = 't';
szMode[nMode++] = '\0';
if ((m_pStream = fopen(pszFileName, szMode)) == NULL)
{
if (pException != NULL)
{
pException->m_lOsError = _doserrno;
pException->m_cause = CFileException::accessDenied;
}
return FALSE;
}
m_hFile = _fileno(m_pStream);
m_bCloseOnDelete = TRUE;
return TRUE;
}
UINT
CStdioFile::Read(void FAR* lpBuf, UINT nCount)
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
ASSERT(AfxIsValidAddress(lpBuf, nCount));
UINT nRead = 0;
#ifdef _NEARDATA
// S/M model, need to copy lpBuf to NEAR data (_read is NEAR)
char buf[nLocalBuf];
UINT nReadReq = 0;
UINT nReadCur = 0;
UINT nReadT = 0;
while (nReadCur < nCount )
{
nReadReq = ((nCount - nRead < nLocalBuf) ? nCount - nRead : nLocalBuf);
nReadT = fread(buf, sizeof(BYTE), nReadReq, m_pStream);
nRead += nReadT;
_fmemcpy(lpBuf, buf, nReadT);
lpBuf = (BYTE FAR*)lpBuf + nReadT;
if (nReadT < nReadReq)
{
if (feof(m_pStream) && !ferror(m_pStream))
break;
else
{
clearerr(m_pStream);
AfxThrowFileException(CFileException::generic, _doserrno);
}
}
nReadCur += nReadReq;
}
#else
if ((nRead = fread(lpBuf, sizeof(BYTE), nCount, m_pStream)) == 0 && !feof(m_pStream))
AfxThrowFileException(CFileException::generic, _doserrno);
#endif
if (ferror(m_pStream ))
{
clearerr(m_pStream);
AfxThrowFileException(CFileException::generic, _doserrno);
}
return nRead;
}
void
CStdioFile::Write(const void FAR* lpBuf, UINT nCount)
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
ASSERT(lpBuf != NULL);
ASSERT(AfxIsValidAddress(lpBuf, nCount, FALSE));
#ifdef _NEARDATA
// S/M model, need to copy lpBuf to NEAR data (_read is NEAR)
void FAR* lpBufT = (void FAR*)lpBuf;
UINT nWrite = 0;
while (nWrite < nCount)
{
char buf[nLocalBuf];
UINT nWriteT;
_fmemcpy(buf, lpBufT,(nWriteT = nCount - nWrite < nLocalBuf ? nCount - nWrite : nLocalBuf));
if (fwrite(buf, sizeof(BYTE), nWriteT, m_pStream) != nWriteT)
AfxThrowFileException(CFileException::generic, _doserrno);
lpBufT = (BYTE FAR*)lpBufT + nWriteT;
nWrite += nWriteT;
}
#else
if (fwrite(lpBuf, sizeof(BYTE), nCount, m_pStream) == -1)
AfxThrowFileException(CFileException::generic, _doserrno);
#endif
}
void
CStdioFile::WriteString(const char FAR* lpsz)
{
ASSERT(lpsz != NULL);
ASSERT(m_pStream != NULL);
register char ch;
while ((ch = *lpsz++) != '\0')
if (fputc(ch, m_pStream) == EOF)
AfxThrowFileException(CFileException::diskFull, _doserrno);
}
char FAR*
CStdioFile::ReadString(char FAR* lpsz, UINT nMax)
{
ASSERT(lpsz != NULL);
ASSERT(AfxIsValidAddress(lpsz, nMax));
ASSERT(m_pStream != NULL);
register UINT nRead = 0;
register char FAR* lpszT = lpsz;
while ((UINT)nRead < nMax - 1)
{
int chOrEOF; // because it could be an EOF which isn't a char
if ((chOrEOF = fgetc(m_pStream)) == EOF)
{
if (feof(m_pStream))
break;
// real error
clearerr(m_pStream);
AfxThrowFileException(CFileException::generic, _doserrno);
}
nRead++;
if ((*lpszT++ = (char)chOrEOF) == '\n')
break;
}
*lpszT = '\0';
return (lpsz == lpszT ? NULL : lpsz);
}
LONG
CStdioFile::Seek(LONG lOff, UINT nFrom)
{
ASSERT_VALID(this);
ASSERT(nFrom == CFile::begin || nFrom == CFile::end || nFrom == CFile::current);
ASSERT(sizeof(fpos_t) <= sizeof(DWORD));
ASSERT(m_pStream != NULL);
fpos_t pos;
if (fseek(m_pStream, lOff, nFrom) != 0)
AfxThrowFileException(CFileException::badSeek, _doserrno);
fgetpos(m_pStream, &pos);
return (DWORD)pos;
}
DWORD
CStdioFile::GetPosition() const
{
ASSERT_VALID(this);
ASSERT(sizeof(fpos_t) <= sizeof(DWORD));
ASSERT(m_pStream != NULL);
fpos_t pos;
if (fgetpos(m_pStream, &pos) != 0)
AfxThrowFileException(CFileException::invalidFile, _doserrno);
return (DWORD)pos;
}
void
CStdioFile::Flush()
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
if (fflush(m_pStream) != 0)
AfxThrowFileException(CFileException::endOfFile, _doserrno);
}
void
CStdioFile::Close()
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
if (m_pStream && fclose(m_pStream))
AfxThrowFileException(CFileException::invalidFile, _doserrno);
m_hFile = hFileNull;
m_bCloseOnDelete = FALSE;
m_pStream = NULL;
}
CFile*
CStdioFile::Duplicate() const
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
AfxThrowNotSupportedException();
return NULL;
}
void
CStdioFile::LockRange(DWORD /* dwPos */, DWORD /* dwCount */)
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
AfxThrowNotSupportedException();
}
void
CStdioFile::UnlockRange(DWORD /* dwPos */, DWORD /* dwCount */)
{
ASSERT_VALID(this);
ASSERT(m_pStream != NULL);
AfxThrowNotSupportedException();
}
#ifdef _DEBUG
void
CStdioFile::Dump(CDumpContext& dc) const
{
ASSERT_VALID(this);
CFile::Dump(dc);
dc << " and FILE* " << (void*)m_pStream << " ";
}
#endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.