_SERIALIZATION AND MFC_ by Chane Cullen Listing One _AFX_INLINE CArchive& CArchive::operator<<(BYTE by) { if (m_lpBufCur + sizeof(BYTE) > m_lpBufMax) Flush(); *(UNALIGNED BYTE*)m_lpBufCur = by; m_lpBufCur += sizeof(BYTE); return *this;} #ifndef _MAC || _WU_BIG_ENDIAN _AFX_INLINE CArchive& CArchive::operator<<(WORD w) { if (m_lpBufCur + sizeof(WORD) > m_lpBufMax) Flush(); *(UNALIGNED WORD*)m_lpBufCur = w; m_lpBufCur += sizeof(WORD); return *this; } _AFX_INLINE CArchive& CArchive::operator<<(LONG l) { if (m_lpBufCur + sizeof(LONG) > m_lpBufMax) Flush(); *(UNALIGNED LONG*)m_lpBufCur = l; m_lpBufCur += sizeof(LONG); return *this; } _AFX_INLINE CArchive& CArchive::operator<<(DWORD dw) { if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) Flush(); *(UNALIGNED DWORD*)m_lpBufCur=dw;m_lpBufCur += sizeof(DWORD); return *this;} _AFX_INLINE CArchive& CArchive::operator<<(float f) { if (m_lpBufCur + sizeof(float) > m_lpBufMax) Flush(); *(UNALIGNED _AFX_FLOAT*)m_lpBufCur = *(_AFX_FLOAT*)&f; m_lpBufCur += sizeof(float); return *this; } _AFX_INLINE CArchive& CArchive::operator<<(double d) { if (m_lpBufCur + sizeof(double) > m_lpBufMax) Flush(); *(UNALIGNED _AFX_DOUBLE*)m_lpBufCur = *(_AFX_DOUBLE*)&d; m_lpBufCur += sizeof(double); return *this; } #endif _AFX_INLINE CArchive& CArchive::operator>>(BYTE& by) { if (m_lpBufCur + sizeof(BYTE) > m_lpBufMax) FillBuffer(sizeof(BYTE) - (UINT)(m_lpBufMax - m_lpBufCur)); by = *(UNALIGNED BYTE*)m_lpBufCur; m_lpBufCur += sizeof(BYTE); return *this; } #ifndef _MAC || WU_BIG_ENDIAN _AFX_INLINE CArchive& CArchive::operator>>(WORD& w) { if (m_lpBufCur + sizeof(WORD) > m_lpBufMax) FillBuffer(sizeof(WORD) - (UINT)(m_lpBufMax - m_lpBufCur)); w = *(UNALIGNED WORD*)m_lpBufCur; m_lpBufCur += sizeof(WORD); return *this; } _AFX_INLINE CArchive& CArchive::operator>>(DWORD& dw) { if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) FillBuffer(sizeof(DWORD) - (UINT)(m_lpBufMax - m_lpBufCur)); dw = *(UNALIGNED DWORD*)m_lpBufCur;m_lpBufCur += sizeof(DWORD);return *this;} _AFX_INLINE CArchive& CArchive::operator>>(float& f) { if (m_lpBufCur + sizeof(float) > m_lpBufMax) FillBuffer(sizeof(float) - (UINT)(m_lpBufMax - m_lpBufCur)); *(_AFX_FLOAT*)&f = *(UNALIGNED _AFX_FLOAT*)m_lpBufCur; m_lpBufCur += sizeof(float); return *this; } _AFX_INLINE CArchive& CArchive::operator>>(double& d) { if (m_lpBufCur + sizeof(double) > m_lpBufMax) FillBuffer(sizeof(double) - (UINT)(m_lpBufMax - m_lpBufCur)); *(_AFX_DOUBLE*)&d = *(UNALIGNED _AFX_DOUBLE*)m_lpBufCur; m_lpBufCur += sizeof(double); return *this; } _AFX_INLINE CArchive& CArchive::operator>>(LONG& l) { if (m_lpBufCur + sizeof(LONG) > m_lpBufMax) FillBuffer(sizeof(LONG) - (UINT)(m_lpBufMax - m_lpBufCur)); l = *(UNALIGNED LONG*)m_lpBufCur; m_lpBufCur += sizeof(LONG); return *this; } #endif Listing Two #ifdef _MAC || WU_BIG_ENDIAN struct _AFXWORD { BYTE WordBits[sizeof(WORD)]; }; struct _AFXDWORD { BYTE DwordBits[sizeof(DWORD)]; }; struct _AFXFLOAT { BYTE FloatBits[sizeof(float)]; }; struct _AFXDOUBLE { BYTE DoubleBits[sizeof(double)]; }; Listing Three CArchive& CArchive::operator<<(WORD w) { if (m_lpBufCur + sizeof(WORD) > m_lpBufMax) Flush(); if (!(m_nMode & bNoByteSwap)) { _AFXWORD wAfx; *(WORD*)&wAfx = w; ASSERT(sizeof(WORD) == 2); BYTE* pb = m_lpBufCur; *pb++ = wAfx.WordBits[1]; *pb = wAfx.WordBits[0]; } else { *(WORD FAR*)m_lpBufCur = w; } m_lpBufCur += sizeof(WORD); return *this; } CArchive& CArchive::operator>>(WORD& w) { if (m_lpBufCur + sizeof(WORD) > m_lpBufMax) FillBuffer(sizeof(WORD) - (UINT)(m_lpBufMax - m_lpBufCur)); w = *(WORD FAR*)m_lpBufCur; m_lpBufCur += sizeof(WORD); if (!(m_nMode & bNoByteSwap)) { _AFXWORD wAfx; *(WORD*)&wAfx = w; ASSERT(sizeof(WORD) == 2); (*(_AFXWORD*)&w).WordBits[0] = wAfx.WordBits[1]; (*(_AFXWORD*)&w).WordBits[1] = wAfx.WordBits[0]; } return *this; } Listing Four CArchive& CArchive::operator<<(LONG l) { ASSERT(sizeof(LONG) == sizeof(DWORD)); return operator<<((DWORD) l); } CArchive& CArchive::operator>>(LONG& l) { ASSERT(sizeof(LONG) == sizeof(DWORD)); return operator>>((DWORD&) l); } Listing Five CArchive& CArchive::operator<<(DWORD dw) { if (m_lpBufCur + sizeof(DWORD) > m_lpBufMax) Flush(); if (!(m_nMode & bNoByteSwap)) { _AFXDWORD dwAfx; *(DWORD*)&dwAfx = dw; ASSERT(sizeof(DWORD) == 4); BYTE* pb = m_lpBufCur; *pb++ = dwAfx.DwordBits[3]; *pb++ = dwAfx.DwordBits[2]; *pb++ = dwAfx.DwordBits[1]; *pb = dwAfx.DwordBits[0]; } else { *(DWORD FAR*)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 FAR*)m_lpBufCur; m_lpBufCur += sizeof(DWORD); if (!(m_nMode & bNoByteSwap)) { _AFXDWORD dwAfx; *(DWORD*)&dwAfx = dw; ASSERT(sizeof(DWORD) == 4); (*(_AFXDWORD*)&dw).DwordBits[0] = dwAfx.DwordBits[3]; (*(_AFXDWORD*)&dw).DwordBits[1] = dwAfx.DwordBits[2]; (*(_AFXDWORD*)&dw).DwordBits[2] = dwAfx.DwordBits[1]; (*(_AFXDWORD*)&dw).DwordBits[3] = dwAfx.DwordBits[0]; } return *this; } Listing Six CArchive& CArchive::operator<<(float f) { if (m_lpBufCur + sizeof(float) > m_lpBufMax) Flush(); if (!(m_nMode & bNoByteSwap)) { _AFXFLOAT fAfx; *(float*)&fAfx = f; ASSERT(sizeof(float) == 4); BYTE* pb = m_lpBufCur; *pb++ = fAfx.FloatBits[3]; *pb++ = fAfx.FloatBits[2]; *pb++ = fAfx.FloatBits[1]; *pb = fAfx.FloatBits[0]; } else { *(_AFXFLOAT FAR*)m_lpBufCur = *(_AFXFLOAT FAR*)&f; } m_lpBufCur += sizeof(float); return *this; } CArchive& CArchive::operator>>(float& f) { if (m_lpBufCur + sizeof(float) > m_lpBufMax) FillBuffer(sizeof(float) - (UINT)(m_lpBufMax - m_lpBufCur)); *(_AFXFLOAT FAR*)&f = *(_AFXFLOAT FAR*)m_lpBufCur; m_lpBufCur += sizeof(float); if (!(m_nMode & bNoByteSwap)) { _AFXFLOAT fAfx; *(float*)&fAfx = f; ASSERT(sizeof(float) == 4); (*(_AFXFLOAT*)&f).FloatBits[0] = fAfx.FloatBits[3]; (*(_AFXFLOAT*)&f).FloatBits[1] = fAfx.FloatBits[2]; (*(_AFXFLOAT*)&f).FloatBits[2] = fAfx.FloatBits[1]; (*(_AFXFLOAT*)&f).FloatBits[3] = fAfx.FloatBits[0]; } return *this; } Listing Seven CArchive& CArchive::operator<<(double d) { if (m_lpBufCur + sizeof(double) > m_lpBufMax) Flush(); if (!(m_nMode & bNoByteSwap)) { _AFXDOUBLE dAfx; *(double*)&dAfx = d; ASSERT(sizeof(double) == 8); BYTE* pb = m_lpBufCur; *pb++ = dAfx.DoubleBits[7]; *pb++ = dAfx.DoubleBits[6]; *pb++ = dAfx.DoubleBits[5]; *pb++ = dAfx.DoubleBits[4]; *pb++ = dAfx.DoubleBits[3]; *pb++ = dAfx.DoubleBits[2]; *pb++ = dAfx.DoubleBits[1]; *pb = dAfx.DoubleBits[0]; } else { *(_AFXDOUBLE FAR*)m_lpBufCur = *(_AFXDOUBLE FAR*)&d; } m_lpBufCur += sizeof(double); return *this; } CArchive& CArchive::operator>>(double& d) { if (m_lpBufCur + sizeof(double) > m_lpBufMax) FillBuffer(sizeof(double) - (UINT)(m_lpBufMax - m_lpBufCur)); *(_AFXDOUBLE FAR*)&d = *(_AFXDOUBLE FAR*)m_lpBufCur; m_lpBufCur += sizeof(double); if (!(m_nMode & bNoByteSwap)) { _AFXDOUBLE dAfx; *(double*)&dAfx = d; ASSERT(sizeof(double) == 8); (*(_AFXDOUBLE*)&d).DoubleBits[0] = dAfx.DoubleBits[7]; (*(_AFXDOUBLE*)&d).DoubleBits[1] = dAfx.DoubleBits[6]; (*(_AFXDOUBLE*)&d).DoubleBits[2] = dAfx.DoubleBits[5]; (*(_AFXDOUBLE*)&d).DoubleBits[3] = dAfx.DoubleBits[4]; (*(_AFXDOUBLE*)&d).DoubleBits[4] = dAfx.DoubleBits[3]; (*(_AFXDOUBLE*)&d).DoubleBits[5] = dAfx.DoubleBits[2]; (*(_AFXDOUBLE*)&d).DoubleBits[6] = dAfx.DoubleBits[1]; (*(_AFXDOUBLE*)&d).DoubleBits[7] = dAfx.DoubleBits[0]; } return *this; } Listing Eight _AFXWIN_INLINE CArchive& AFXAPI operator<<(CArchive& ar, POINT point) { #ifndef _MAC || WU_BIG_ENDIAN ar.Write(&point, sizeof(POINT)); #else ar << point.x << point.y; #endif return ar; } _AFXWIN_INLINE CArchive& AFXAPI operator>>(CArchive& ar, POINT& point) { #ifndef _MAC || WU_BIG_ENDIAN ar.Read(&point, sizeof(POINT)); #else ar >> point.x >> point.y; #endif return ar; } Listing Nine _AFXWIN_INLINE CArchive& AFXAPI operator<<(CArchive& ar, RECT rect) { #ifndef _MAC || WU_BIG_ENDIAN ar.Write(&rect, sizeof(RECT)); #else ar << rect.left << rect.top << rect.right << rect.bottom; #endif return ar; } _AFXWIN_INLINE CArchive& AFXAPI operator>>(CArchive& ar, RECT& rect) { #ifndef _MAC || WU_BIG_ENDIAN ar.Read(&rect, sizeof(RECT)); #else ar >> rect.left >> rect.top >> rect.right >> rect.bottom; #endif return ar; } _AFXWIN_INLINE CArchive& AFXAPI operator<<(CArchive& ar, SIZE size) { #ifndef _MAC || WU_BIG_ENDIAN ar.Write(&size, sizeof(SIZE)); #else ar << size.cx << size.cy; #endif return ar; } _AFXWIN_INLINE CArchive& AFXAPI operator>>(CArchive& ar, size& SIZE) { #ifndef _MAC || WU_BIG_ENDIAN ar.Read(&size, sizeof(SIZE)); #else ar >> size.cx >> size.cy; #endif return ar; } Listing Ten template void AFXAPI SerializeElements(CArchive& ar, TYPE* pElements, int nCount) { ASSERT(AfxIsValidAddress(pElements, nCount * sizeof(TYPE))); // default is bit-wise read/write if (ar.IsStoring()) ar.Write((void*)pElements, nCount * sizeof(TYPE)); // untyped write else ar.Read((void*)pElements, nCount * sizeof(TYPE)); // untyped read } Listing Eleven CStroke : public CObject { . . . }; CArray< CMyKidsObject, CMyKidsObject& > kidsArray; void SerializeElements( CArchive& ar, CMyKidsObject* pKids, int nCount ) { for ( int i = 0; i < nCount; i++, pKids++ ) { // Serialize each CMyKidsObject object if ( ar.IsStoring() ) ar << pKids; else ar >> pKids; } } Listing Twelve template void CArray::Serialize(CArchive& ar) { ASSERT_VALID(this); CObject::Serialize(ar); if (ar.IsStoring()) { ar << (WORD) m_nSize; } else { WORD nOldSize; ar >> nOldSize; SetSize(nOldSize); } SerializeElements(ar, m_pData, m_nSize); } Listing Thirteen void SerializeElements( CArchive& ar, CPoint* pPoints, int nCount ) { for ( int i = 0; i < nCount; i++, pPoints++ ) { // Serialize each CPoint object if ( ar.IsStoring() ) ar << pPoints; else ar >> pPoints; } }