16,548
社区成员




// 摘自 afx.inl
_AFX_INLINE CArchive& CArchive::operator>>(int& i)
{ return CArchive::operator>>((LONG&)i); }
_AFX_INLINE CArchive& CArchive::operator>>(LONG& l)
{
if(!IsLoading())
AfxThrowArchiveException(CArchiveException::writeOnly,m_strFileName);
if (m_lpBufCur + sizeof(LONG) > m_lpBufMax)
FillBuffer(UINT(sizeof(LONG) - (m_lpBufMax - m_lpBufCur)));
l = *(UNALIGNED LONG*)m_lpBufCur; m_lpBufCur += sizeof(LONG); return *this;
}
// 摘自arccore.cpp
void CArchive::FillBuffer(UINT nBytesNeeded)
{
ASSERT_VALID(m_pFile);
ASSERT(IsLoading());
if(!IsLoading())
AfxThrowArchiveException(CArchiveException::writeOnly,m_strFileName);
ASSERT(m_bDirectBuffer || m_lpBufStart != NULL);
ASSERT(m_bDirectBuffer || m_lpBufCur != NULL);
ASSERT(nBytesNeeded > 0);
ASSERT(nBytesNeeded <= (UINT)m_nBufSize);
ASSERT(m_lpBufStart == NULL ||
AfxIsValidAddress(m_lpBufStart, UINT(m_lpBufMax - m_lpBufStart), FALSE));
ASSERT(m_lpBufCur == NULL ||
AfxIsValidAddress(m_lpBufCur, UINT(m_lpBufMax - m_lpBufCur), FALSE));
UINT nUnused = UINT(m_lpBufMax - m_lpBufCur);
ULONG nTotalNeeded = ((ULONG)nBytesNeeded) + nUnused;
// fill up the current buffer from file
if (!m_bDirectBuffer)
{
ASSERT(m_lpBufCur != NULL);
ASSERT(m_lpBufStart != NULL);
ASSERT(m_lpBufMax != NULL);
if (m_lpBufCur > m_lpBufStart)
{
// copy unused
if ((int)nUnused > 0)
{
Checked::memmove_s(m_lpBufStart, (size_t)(m_lpBufMax - m_lpBufStart),
m_lpBufCur, nUnused);
m_lpBufCur = m_lpBufStart;
m_lpBufMax = m_lpBufStart + nUnused;
}
// read to satisfy nBytesNeeded or nLeft if possible
UINT nRead = nUnused;
UINT nLeft;
UINT nBytes;
// Only read what we have to, to avoid blocking waiting on data
// we don't need
if (m_bBlocking)
nLeft = nBytesNeeded-nUnused;
else
nLeft = m_nBufSize-nUnused;
BYTE* lpTemp = m_lpBufStart + nUnused;
do
{
nBytes = m_pFile->Read(lpTemp, nLeft);
lpTemp = lpTemp + nBytes;
nRead += nBytes;
nLeft -= nBytes;
}
while (nBytes > 0 && nLeft > 0 && nRead < nTotalNeeded);
m_lpBufCur = m_lpBufStart;
m_lpBufMax = m_lpBufStart + nRead;
}
}
else
{
// seek to unused portion and get the buffer starting there
if (nUnused != 0)
m_pFile->Seek(-(LONG)nUnused, CFile::current);
UINT nActual = m_pFile->GetBufferPtr(CFile::bufferRead, m_nBufSize,
(void**)&m_lpBufStart, (void**)&m_lpBufMax);
ASSERT(nActual == (UINT)(m_lpBufMax - m_lpBufStart));
m_lpBufCur = m_lpBufStart; }
// not enough data to fill request?
if ((ULONG)(m_lpBufMax - m_lpBufCur) < nTotalNeeded)
AfxThrowArchiveException(CArchiveException::endOfFile);
}