MFC中的CArchive(1)

本文介绍了MFC中CArchive类的相关内容,包括缓冲区指针、构造函数以及IsLoading()函数的用法。CArchive类用于文件的序列化操作,它根据IsLoading()返回值来判断读写模式,并在构造时初始化缓冲区。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.先贴上该类:

class CArchive
{
protected:
enum SchemaMapReservedRefs { objTypeArrayRef = 1 };
enum LoadArrayObjType{ typeUndefined = 0, typeCRuntimeClass = 1, typeCObject = 2 };
public:
// Flag values
enum Mode { store = 0, load = 1, bNoFlushOnDelete = 2, bNoByteSwap = 4 };


CArchive(CFile* pFile, UINT nMode, int nBufSize = 4096, void* lpBuf = NULL);
~CArchive();


// Attributes
BOOL IsLoading() const;
BOOL IsStoring() const;
BOOL IsByteSwapping() const;
BOOL IsBufferEmpty() const;


CFile* GetFile() const;
UINT GetObjectSchema(); // only valid when reading a CObject*
void SetObjectSchema(UINT nSchema);


// pointer to document being serialized -- must set to serialize
//  COleClientItems in a document!
CDocument* m_pDocument;


// Operations
UINT Read(void* lpBuf, UINT nMax);
void EnsureRead(void *lpBuf, UINT nCount);
void Write(const void* lpBuf, UINT nMax);
void Flush();
void Close();
void Abort();   // close and shutdown without exceptions


// reading and writing strings
void WriteString(LPCTSTR lpsz);
LPTSTR ReadString(_Out_z_cap_(nMax+1) LPTSTR lpsz, _In_ UINT nMax);
BOOL ReadString(CString& rString);


public:
// Object I/O is pointer based to avoid added construction overhead.
// Use the Serialize member function directly for embedded objects.
friend CArchive& AFXAPI operator<<(CArchive& ar, const CObject* pOb);


friend CArchive& AFXAPI operator>>(CArchive& ar, CObject*& pOb);
friend CArchive& AFXAPI operator>>(CArchive& ar, const CObject*& pOb);


// insertion operations
CArchive& operator<<(BYTE by);
CArchive& operator<<(WORD w);
CArchive& operator<<(LONG l);
CArchive& operator<<(DWORD dw);
CArchive& operator<<(float f);
CArchive& operator<<(double d);
CArchive& operator<<(LONGLONG dwdw);
CArchive& operator<<(ULONGLONG dwdw);


CArchive& operator<<(int i);
CArchive& operator<<(short w);
CArchive& operator<<(char ch);
#ifdef _NATIVE_WCHAR_T_DEFINED
CArchive& operator<<(wchar_t ch);
#endif
CArchive& operator<<(unsigned u);


template < typename BaseType , bool t_bMFCDLL>
CArchive& operator<<(const ATL::CSimpleStringT<BaseType, t_bMFCDLL>& str);


template< typename BaseType, class StringTraits >
CArchive& operator<<(const ATL::CStringT<BaseType, StringTraits>& str);

template < typename BaseType , bool t_bMFCDLL>
CArchive& operator>>(ATL::CSimpleStringT<BaseType, t_bMFCDLL>& str);


template< typename BaseType, class StringTraits >
CArchive& operator>>(ATL::CStringT<BaseType, StringTraits>& str);


CArchive& operator<<(bool b);


// extraction operations
CArchive& operator>>(BYTE& by);
CArchive& operator>>(WORD& w);
CArchive& operator>>(DWORD& dw);
CArchive& operator>>(LONG& l);
CArchive& operator>>(float& f);
CArchive& operator>>(double& d);
CArchive& operator>>(LONGLONG& dwdw);
CArchive& operator>>(ULONGLONG& dwdw);


CArchive& operator>>(int& i);
CArchive& operator>>(short& w);
CArchive& operator>>(char& ch);
#ifdef _NATIVE_WCHAR_T_DEFINED
CArchive& operator>>(wchar_t& ch);
#endif
CArchive& operator>>(unsigned& u);
CArchive& operator>>(bool& b);


// object read/write
CObject* ReadObject(const CRuntimeClass* pClass);
void WriteObject(const CObject* pOb);
// advanced object mapping (used for forced references)
void MapObject(const CObject* pOb);


// advanced versioning support
void WriteClass(const CRuntimeClass* pClassRef);
CRuntimeClass* ReadClass(const CRuntimeClass* pClassRefRequested = NULL,
UINT* pSchema = NULL, DWORD* pObTag = NULL);
void SerializeClass(const CRuntimeClass* pClassRef);


// advanced operations (used when storing/loading many objects)
void SetStoreParams(UINT nHashSize = 2053, UINT nBlockSize = 128);
void SetLoadParams(UINT nGrowBy = 1024);


void EnsureSchemaMapExists(CArray<LoadArrayObjType, const LoadArrayObjType&>** ppObjTypeArray = NULL);
// Implementation
public:
BOOL m_bForceFlat;  // for COleClientItem implementation (default TRUE)
BOOL m_bDirectBuffer;   // TRUE if m_pFile supports direct buffering
BOOL m_bBlocking;  // TRUE if m_pFile can block for unbounded periods of time
void FillBuffer(UINT nBytesNeeded);
void CheckCount();  // throw exception if m_nMapCount is too large


// special functions for reading and writing (16-bit compatible) counts
DWORD_PTR ReadCount();
void WriteCount(DWORD_PTR dwCount);


// public for advanced use
UINT m_nObjectSchema;
CString m_strFileName;


protected:
// archive objects cannot be copied or assigned
CArchive(const CArchive& arSrc);
void operator=(const CArchive& arSrc);


BOOL m_nMode;
BOOL m_bUserBuf;
int m_nBufSize;
CFile* m_pFile;
BYTE* m_lpBufCur;
BYTE* m_lpBufMax;
BYTE* m_lpBufStart;


// array/map for CObject* and CRuntimeClass* load/store
UINT m_nMapCount;
union
{
CPtrArray* m_pLoadArray;
CMapPtrToPtr* m_pStoreMap;
};
// map to keep track of mismatched schemas
CMapPtrToPtr* m_pSchemaMap;


// advanced parameters (controls performance with large archives)
UINT m_nGrowSize;
UINT m_nHashSize;
};

该类的构造函数有两个默认参数:CArchive(CFile* pFile, UINT nMode, int nBufSize = 4096, void* lpBuf = NULL);
m_nMode指明读写模式
BOOL m_bDirectBuffer;  指明是否是直接读写

缓冲区指针 BYTE* m_lpBufStart,指向缓冲区,这个缓冲区有可能是底层CFile(如派生类CMemFile)对象提供的,但一般是CArchive自己建立的。 
缓冲区尾部指针 BYTE* m_lpBufMax; 
缓冲区当前位置指针 BYTE* m_lpBufCur; 
初始化时,如果是读模式,当前位置在尾部,如果是写模式,当前位置在头部:m_lpBufCur = (IsLoading()) ? m_lpBufMax : m_lpBufStart;

其中_AFX_INLINE BOOL CArchive::IsLoading() const
{ return (m_nMode & CArchive::load) != 0; }用来判断是输入还是输出


下面是构造函数的源代码:

CArchive::CArchive(CFile* pFile, UINT nMode, int nBufSize, void* lpBuf) 
{
ASSERT_VALID(pFile);
if(pFile == NULL)
{
AfxThrowInvalidArgException();
}

m_strFileName = pFile->GetFilePath();


// initialize members not dependent on allocated buffer
m_nMode = nMode;
m_pFile = pFile;
m_pSchemaMap = NULL;
m_pLoadArray = NULL;
m_pDocument = NULL;
m_bForceFlat = TRUE;
m_nObjectSchema = (UINT)-1; // start with invalid schema
if (IsStoring())
m_nGrowSize = nBlockSize;
else
m_nGrowSize = nGrowSize;
m_nHashSize = nHashSize;


// initialize the buffer.  minimum size is 128
m_lpBufStart = (BYTE*)lpBuf;
m_bUserBuf = TRUE;
m_bDirectBuffer = FALSE;
m_bBlocking = m_pFile->GetBufferPtr(CFile::bufferCheck)&CFile::bufferBlocking;


if (nBufSize < nBufSizeMin)
{
// force use of private buffer of minimum size
m_nBufSize = nBufSizeMin;
m_lpBufStart = NULL;
}
else
m_nBufSize = nBufSize;


nBufSize = m_nBufSize;
if (m_lpBufStart == NULL)
{
// check for CFile providing buffering support
m_bDirectBuffer = m_pFile->GetBufferPtr(CFile::bufferCheck)&CFile::bufferDirect;
if (!m_bDirectBuffer)
{
// no support for direct buffering, allocate new buffer
m_lpBufStart = new BYTE[m_nBufSize];
m_bUserBuf = FALSE;
}
else
{
// CFile* supports direct buffering!
nBufSize = 0;   // will trigger initial FillBuffer
}
}


if (!m_bDirectBuffer)
{
ASSERT(m_lpBufStart != NULL);
ASSERT(AfxIsValidAddress(m_lpBufStart, nBufSize, IsStoring()));
}
m_lpBufMax = m_lpBufStart + nBufSize;
m_lpBufCur = (IsLoading()) ? m_lpBufMax : m_lpBufStart;


ASSERT(m_pStoreMap == NULL);        // same as m_pLoadArray
}


其中GetBufferPtr是CFile类中的函数 CFile类中本身没有缓冲区 所以直接返回0 但其子类CMemFile有缓冲数据成员CArchive可以直接用
m_bDirectBuffer直接读写变量标志了上述两种情况。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值