WEB开发网      婵犵數濞€濞佳囧磹婵犳艾鐤炬い鎰堕檮閸嬬喐銇勯弽銊с€掗梻鍕閺岋箑螣娓氼垱笑闂佽姘﹂褔婀佸┑鐘诧工妤犲憡绂嶉崜褏纾奸弶鍫涘妼缁楁岸鏌熷畡鐗堝殗闁诡喒鏅犲畷褰掝敃閵堝棙顔忔繝鐢靛仦閸ㄥ爼骞愰幘顔肩;闁规崘绉ぐ鎺撳亹闁绘垶锕╁Λ鍕⒑閹肩偛濡奸悗娑掓櫇缁顓兼径妯绘櫇闂佹寧绻傞弻濠囨晝閸屾稓鍘甸柣搴㈢⊕閿氶柣蹇ョ稻缁绘繃绻濋崘銊т紝闂佽鍨伴崯鏉戠暦閻旂⒈鏁傞柛鈾€鏅欑槐妯衡攽閻愬樊鍤熷┑顔藉劤铻為柛鏇ㄥ墯閸欏繘鏌嶉崫鍕櫣缂佲偓婢跺绠鹃柟瀛樼箘閿涘秵顨ラ悙顏勭伈闁诡喖缍婂畷鎯邦槻婵℃彃顭烽弻娑㈠Ω閵夈儺鍔夌紓浣稿€哥粔褰掑极閹剧粯鏅搁柨鐕傛嫹 ---闂傚倷鐒︾€笛兠洪埡鍛闁跨噦鎷�
开发学院软件开发VC FMD开发文集 -- CArchive原理 阅读

FMD开发文集 -- CArchive原理

 2010-03-28 20:34:54 来源:WEB开发网 闂傚倷绶氬ḿ褍螞閹绢喖绠柨鐕傛嫹闂傚倷绀侀幉锟犲垂閻㈠灚宕查柟鎵閸庡秵銇勯幒鎴濃偓鐢稿磻閹炬枼妲堟繛鍡楃С濞岊亞绱撻崒姘扁枌闁瑰嚖鎷�婵犵數濮幏鍐川椤撴繄鎹曢梻渚€娼уú銈吤洪妸鈺佺劦妞ゆ帊鑳堕埊鏇㈡煏閸モ晛浠х紒杈╁仱閺佹捇鏁撻敓锟�闂傚倷绶氬ḿ褍螞閹绢喖绠柨鐕傛嫹  闂傚倷鑳舵灙缂佺粯顨呴埢宥夊即閵忕姵鐎梺缁樺姇閹碱偆鐥閺屾洘绻濊箛鏇犵獥闂佺厧澹婃禍婊堚€旈崘顏佸亾閿濆骸澧ù鐘欏嫮绠鹃柛顐ゅ枎閻忋儲銇勯弴妯哄姦妞ゃ垺鐟╅幃鈩冩償閵囧府鎷�
核心提示:③运行时类信息的读写为了避免众多重复的同类对象写入重复的类信息,CArchive中使用CMap对象储存和检索类信息,FMD开发文集 -- CArchive原理(6),void CArchive::WriteClass(const CRuntimeClass* pClassRef){ASSERT(pClassRef !=

③运行时类信息的读写

为了避免众多重复的同类对象写入重复的类信息,CArchive中使用CMap对象储存和检索类信息。

void CArchive::WriteClass(const CRuntimeClass* pClassRef)
{
  ASSERT(pClassRef != NULL);
  ASSERT(IsStoring());  // proper direction
  if (pClassRef-> m_wSchema == 0xFFFF)
  {
    TRACE1("Warning: Cannot call WriteClass/WriteObject for %hs.
",
      pClassRef-> m_lpszClassName);
    AfxThrowNotSupportedException();
  }
  // make sure m_pStoreMap is initialized
  MapObject(NULL);
  // write out class id of pOb, with high bit set to indicate
  // new object follows
  // ASSUME: initialized to 0 map
  DWORD nClassIndex;
  if ((nClassIndex = (DWORD)(*m_pStoreMap)[(void*)pClassRef]) != 0)
  {
    // previously seen class, write out the index tagged by high bit
    if (nClassIndex < wBigObjectTag)
      *this << (WORD)(wClassTag | nClassIndex);
    else
    {
      *this << wBigObjectTag;
      *this << (dwBigClassTag | nClassIndex);
    }
  }
  else
  {
    // store new class
    *this << wNewClassTag;
    pClassRef-> Store(*this);
    // store new class reference in map, checking for overflow
    CheckCount();
    (*m_pStoreMap)[(void*)pClassRef] = (void*)m_nMapCount++;
  }
}
CRuntimeClass* CArchive::ReadClass(const CRuntimeClass* pClassRefRequested,
  UINT* pSchema, DWORD* pObTag)
{
  ASSERT(pClassRefRequested == NULL ||
    AfxIsValidAddress(pClassRefRequested, sizeof(CRuntimeClass), FALSE));
  ASSERT(IsLoading());  // proper direction
  if (pClassRefRequested != NULL && pClassRefRequested-> m_wSchema == 0xFFFF)
  {
    TRACE1("Warning: Cannot call ReadClass/ReadObject for %hs.
",
      pClassRefRequested-> m_lpszClassName);
    AfxThrowNotSupportedException();
  }
  // 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*)nSchema);
      }
    }
    CheckCount();
    m_pLoadArray-> InsertAt(m_nMapCount++, pClassRef);
  }
  else
  {
    // existing class index in obTag followed by new object
    DWORD nClassIndex = (obTag & ~dwBigClassTag);
    if (nClassIndex == 0 || nClassIndex > (DWORD)m_pLoadArray-> GetUpperBound())
      AfxThrowArchiveException(CArchiveException::badIndex,
        m_strFileName);
    pClassRef = (CRuntimeClass*)m_pLoadArray-> GetAt(nClassIndex);
    ASSERT(pClassRef != NULL);
    // determine schema stored against objects of this type
    void* pTemp;
    BOOL bFound = FALSE;
    nSchema = 0;
    if (m_pSchemaMap != NULL)
    {
      bFound = m_pSchemaMap-> Lookup( pClassRef, pTemp );
      if (bFound)
        nSchema = (UINT)pTemp;
    }
    if (!bFound)
      nSchema = pClassRef-> m_wSchema & ~VERSIONABLE_SCHEMA;
  }
  // 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
    m_nObjectSchema = nSchema;
  // store obTag for later examination
  if (pObTag != NULL)
    *pObTag = obTag;
  // return the resulting CRuntimeClass*
  return pClassRef;
}

上一页  1 2 3 4 5 6 

Tags:FMD 开发 文集

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