// 循环队列实现高速缓存的读写 // 教材上有对循环队列的讲解,不过头指针,尾指针重合的时候不好理解 // 这里仿造标准库中的begin(),end()节点,使得头指针,为指针永远不重合,相对好理解点 // 实现了对简单类型的数据的输入输出缓存,不支持CString,std::string等复杂类型,因为用的memcpy拷贝的数据 template<class CType> class CInputOutputCache { public: CInputOutputCache(const int iCalcheSize) { if (iCalcheSize < 1) { return; } m_pCacheData = new CType[iCalcheSize+2]; if (m_pCacheData == NULL) { return; } m_pRead = m_pCacheData; m_pWrite = m_pCacheData+1; m_iCacheSize = iCalcheSize; }; // 写iLen个数据,返回实际写的个数 int Write(const CType* pBufWrite, const int iLen) { if (m_pCacheData == NULL) { return 0; } int iFreeSpace = GetFreeSpace(); int iWriteLen = 0; if (iFreeSpace >= iLen) { iWriteLen = iLen; } else { iWriteLen = iFreeSpace; } CType* pWritted = AddPoint(m_pWrite, iWriteLen); if (pWritted > m_pWrite) { memcpy(m_pWrite, pBufWrite, iWriteLen); } else { int iFirstTimeWriteSize = m_pCacheData + m_iCacheSize + 2 - m_pWrite; memcpy(m_pWrite, pBufWrite, iFirstTimeWriteSize); memcpy(m_pCacheData, pBufWrite, iWriteLen-iFirstTimeWriteSize); } m_pWrite = pWritted; return iWriteLen; }; // 读iLen个数据,返回实际读的个数 int Read(CType* pBufRead, const int iLen) { if (m_pCacheData == NULL) { return 0; } int iValidLen = GetValidLen(); int iReaded = 0; if (iValidLen >= iLen) { iReaded = iLen; } else { iReaded = iValidLen; } CType* pReaded = AddPoint(m_pRead, iReaded); if (pReaded > m_pRead) { memcpy(pBufRead, m_pRead+1, iReaded); } else { int iFirstTimeReadSize = m_pCacheData + m_iCacheSize + 2 - (m_pRead+1); memcpy(pBufRead, m_pRead+1, iFirstTimeReadSize); memcpy(pBufRead, m_pCacheData, iReaded-iFirstTimeReadSize); } m_pRead = pReaded; return iReaded; }; int GetFreeSpace() { if (m_pCacheData == NULL) { return 0; } return m_iCacheSize - GetValidLen(); }; int GetValidLen() { if (m_pCacheData == NULL) { return 0; } if (m_pRead > m_pWrite) { return m_iCacheSize - (m_pRead - m_pWrite -1); } else if (m_pRead < m_pWrite) { return m_pWrite - m_pRead -1; } } private: CType* AddPoint(CType* pData, int iSize) { int iOffset = pData - m_pCacheData; int iOffsetAdded = iOffset + iSize; if (iOffsetAdded >= m_iCacheSize+2) { iOffsetAdded = iOffsetAdded - (m_iCacheSize + 2); } return m_pCacheData + iOffsetAdded; } CType* m_pCacheData; // 缓存 int m_iCacheSize; // 缓存大小 CType* m_pRead; // 读指针 CType* m_pWrite; // 写指针 }; int _tmain(int argc, _TCHAR* argv[]) { char sRead[20]; CInputOutputCache<char> inputOutputCalche(10); int i = inputOutputCalche.Write("1234567890123", 12); inputOutputCalche.Read(sRead, 3); int iValidLen = inputOutputCalche.GetValidLen(); int iFreeSpace = inputOutputCalche.GetFreeSpace(); inputOutputCalche.Write("12345", 5); inputOutputCalche.Read(sRead, 3); }