MFC技术内幕系列之(五)---MFC文档序列化内幕[6]

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 bigwhite20xx 的 blog

_afx_inline carchive& afxapi operator>>(carchive& ar, cobject*& pob)
 { pob = ar.readobject(null); return ar; }

--->//in arcobj.cpp
 cobject* carchive::readobject(const cruntimeclass* pclassrefrequested)
 {
 ...//
 // attempt to load next stream as cruntimeclass
 uint nschema;
 dword obtag;
 cruntimeclass* pclassref = readclass(pclassrefrequested, &nschema, &obtag);//***

 // check to see if tag to already loaded object
 cobject* pob;
 if (pclassref == null)
 {
  if (obtag > (dword)m_ploadarray->getupperbound())
  {
   // tag is too large for the number of objects read so far
   afxthrowarchiveexception(carchiveexception::badindex,
    m_strfilename);
  }

  pob = (cobject*)m_ploadarray->getat(obtag);
  if (pob != null && pclassrefrequested != null &&
    !pob->iskindof(pclassrefrequested))
  {
   // loaded an object but of the wrong class
   afxthrowarchiveexception(carchiveexception::badclass,
    m_strfilename);
  }
 }
 else
 {
  // allocate a new object based on the class just acquired
  pob = pclassref->createobject();//***
  if (pob == null)
   afxthrowmemoryexception();

  // add to mapping array before de-serializing
  checkcount();
  m_ploadarray->insertat(m_nmapcount++, pob);

  // serialize the object with the schema number set in the archive
  uint nschemasave = m_nobjectschema;
  m_nobjectschema = nschema;
  pob->serialize(*this);//***
  m_nobjectschema = nschemasave;
  assert_valid(pob);
 }

 return pob;
 }

--->//读取cruntimeclass信息
  cruntimeclass* carchive::readclass(const cruntimeclass* pclassrefrequested,
 uint* pschema, dword* pobtag)
 {
 ...//
 // make sure m_ploadarray is initialized
 mapobject(null);

 // read object tag - if prefixed by wbigobjecttag then dword tag follows
 dword obtag;
 word wtag;
 *this >> wtag;//***读取标志位
 if (wtag == wbigobjecttag)
  *this >> obtag;
 else
  obtag = ((wtag & wclasstag) << 16) | (wtag & ~wclasstag);

 // check for object tag (throw exception if expecting class tag)
 if (!(obtag & dwbigclasstag))
 {
  if (pobtag == null)
   afxthrowarchiveexception(carchiveexception::badindex, m_strfilename);

  *pobtag = obtag;
  return null;
 }

 cruntimeclass* pclassref;
 uint nschema;
 if (wtag == wnewclasstag)
 {
  // new object follows a new class id
  if ((pclassref = cruntimeclass::load(*this, &nschema)) == null)//***
   afxthrowarchiveexception(carchiveexception::badclass, m_strfilename);

  // check nschema against the expected schema
  if ((pclassref->m_wschema & ~versionable_schema) != nschema)
  {
   if (!(pclassref->m_wschema & versionable_schema))
   {
    // schema doesn't match and not marked as versionable_schema
    afxthrowarchiveexception(carchiveexception::badschema,
     m_strfilename);
   }
   else
   {
    // they differ -- store the schema for later retrieval
    if (m_pschemamap == null)
     m_pschemamap = new cmapptrtoptr;
    assert_valid(m_pschemamap);
    m_pschemamap->setat(pclassref, (void*)(dword_ptr)nschema);
   }
  }
  checkcount();
  m_ploadarray->insertat(m_nmapcount++, pclassref);
 }
 else
 {
   ...//
        }

 // check for correct derivation
 if (pclassrefrequested != null &&
  !pclassref->isderivedfrom(pclassrefrequested))
 {
  afxthrowarchiveexception(carchiveexception::badclass, m_strfilename);
 }

 // store nschema for later examination
 if (pschema != null)
  *pschema = nschema;
 else

本文关键:文档序列化
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top