WEB开发网
开发学院软件开发VC FMD开发文集 -- CArchive原理 阅读

FMD开发文集 -- CArchive原理

 2010-03-28 20:34:54 来源:WEB开发网   
核心提示:双字的插入(写)CArchive& CArchive::operator<<(DWORD dw){if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) //缓冲区空间不够Flush();//缓冲区内容提交到实际存储煤质,if (!(m_nMode & bNoByte

双字的插入(写)

CArchive& CArchive::operator<<(DWORD dw)
{
  if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) //缓冲区空间不够
    Flush(); //缓冲区内容提交到实际存储煤质。
  if (!(m_nMode & bNoByteSwap))
    _AfxByteSwap(dw, m_lpBufCur); //处理字节顺序
  else
    *(DWORD*)m_lpBufCur = dw;   //添入缓冲区
  m_lpBufCur += sizeof(DWORD);     //移动当前指针
  return *this;
}
双字的提取(读)CArchive& CArchive::operator>>(DWORD& dw)
{
  if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) //缓冲区要读完了
    FillBuffer(sizeof(DWORD) - (UINT)(m_lpBufMax - m_lpBufCur)); //重新读入内容到缓冲区
  dw = *(DWORD*)m_lpBufCur;    //读取双字
  m_lpBufCur += sizeof(DWORD);  //移动当前位置指针
  if (!(m_nMode & bNoByteSwap))
    _AfxByteSwap(dw, (BYTE*)&dw); //处理字节顺序
  return *this;
}
四.缓冲区的更新

以上操作中,当缓冲区将插入满或缓冲区将提取空时,都将对缓冲区进行更新处理。

缓冲区将插入满时调用Flush();void CArchive::Flush()
{
  ASSERT_VALID(m_pFile);
  ASSERT(m_bDirectBuffer || m_lpBufStart != NULL);
  ASSERT(m_bDirectBuffer || m_lpBufCur != NULL);
  ASSERT(m_lpBufStart == NULL ||
    AfxIsValidAddress(m_lpBufStart, m_lpBufMax - m_lpBufStart, IsStoring()));
  ASSERT(m_lpBufCur == NULL ||
    AfxIsValidAddress(m_lpBufCur, m_lpBufMax - m_lpBufCur, IsStoring()));
  if (IsLoading())
  {
    // unget the characters in the buffer, seek back unused amount
    if (m_lpBufMax != m_lpBufCur)
      m_pFile-> Seek(-(m_lpBufMax - m_lpBufCur), CFile::current);
    m_lpBufCur = m_lpBufMax;  // 指向尾
  }
  else  //写模式
  {
    if (!m_bDirectBuffer)
    {
      // 内容写入到文件
      if (m_lpBufCur != m_lpBufStart)
        m_pFile-> Write(m_lpBufStart, m_lpBufCur - m_lpBufStart);
    }
    else
    {
      //如果是直接针对内存区域的的(例如CMemFile中) (只需移动相关指针,指向新的一块内存)
      if (m_lpBufCur != m_lpBufStart)
        m_pFile-> GetBufferPtr(CFile::bufferCommit, m_lpBufCur - m_lpBufStart);
      // get next buffer
      VERIFY(m_pFile-> GetBufferPtr(CFile::bufferWrite, m_nBufSize,
        (void**)&m_lpBufStart, (void**)&m_lpBufMax) == (UINT)m_nBufSize);
      ASSERT((UINT)m_nBufSize == (UINT)(m_lpBufMax - m_lpBufStart));
    }
    m_lpBufCur = m_lpBufStart; //指向缓冲区首
  }
}
缓冲区将提取空,会调用FillBuffer。 nBytesNeeded为当前剩余部分上尚有用的字节void CArchive::FillBuffer(UINT nBytesNeeded)
{
  ASSERT_VALID(m_pFile);
  ASSERT(IsLoading());
  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, m_lpBufMax - m_lpBufStart, FALSE));
  ASSERT(m_lpBufCur == NULL ||
    AfxIsValidAddress(m_lpBufCur, m_lpBufMax - m_lpBufCur, FALSE));
  UINT nUnused = m_lpBufMax - m_lpBufCur;
  ULONG nTotalNeeded = ((ULONG)nBytesNeeded) + nUnused;
  // 从文件中读取
  if (!m_bDirectBuffer)
  {
    ASSERT(m_lpBufCur != NULL);
    ASSERT(m_lpBufStart != NULL);
    ASSERT(m_lpBufMax != NULL);
    if (m_lpBufCur > m_lpBufStart)
    {
      //保留剩余的尚未处理的部分,将它们移动到头
      if ((int)nUnused > 0)
      {
        memmove(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 = m_nBufSize-nUnused;
      UINT nBytes;
      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 < nBytesNeeded);
      m_lpBufCur = m_lpBufStart;
      m_lpBufMax = m_lpBufStart + nRead;
    }
  }
  else
  {
    // 如果是针对内存区域(CMemFile),移动相关指针,指向新的一块内存
    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);
}

上一页  1 2 3 4 5 6  下一页

Tags:FMD 开发 文集

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接