objcore.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_CORE1_SEG
  12. #pragma code_seg(AFX_CORE1_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. /////////////////////////////////////////////////////////////////////////////
  19. // Runtime Typing
  20. // special runtime-class structure for CObject (no base class)
  21. #ifdef _AFXDLL
  22. CRuntimeClass* PASCAL CObject::_GetBaseClass()
  23. { return NULL; }
  24. AFX_COMDAT const AFX_DATADEF struct CRuntimeClass CObject::classCObject =
  25. { "CObject", sizeof(CObject), 0xffff, NULL, &CObject::_GetBaseClass, NULL };
  26. #else
  27. AFX_COMDAT const AFX_DATADEF struct CRuntimeClass CObject::classCObject =
  28. { "CObject", sizeof(CObject), 0xffff, NULL, NULL, NULL };
  29. #endif
  30. CRuntimeClass* CObject::GetRuntimeClass() const
  31. {
  32. return RUNTIME_CLASS(CObject);
  33. }
  34. BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
  35. {
  36. ASSERT(this != NULL);
  37. // it better be in valid memory, at least for CObject size
  38. ASSERT(AfxIsValidAddress(this, sizeof(CObject)));
  39. // simple SI case
  40. CRuntimeClass* pClassThis = GetRuntimeClass();
  41. return pClassThis->IsDerivedFrom(pClass);
  42. }
  43. CObject* AFX_CDECL AfxDynamicDownCast(CRuntimeClass* pClass, CObject* pObject)
  44. {
  45. if (pObject != NULL && pObject->IsKindOf(pClass))
  46. return pObject;
  47. else
  48. return NULL;
  49. }
  50. #ifdef _DEBUG
  51. CObject* AFX_CDECL AfxStaticDownCast(CRuntimeClass* pClass, CObject* pObject)
  52. {
  53. ASSERT(pObject == NULL || pObject->IsKindOf(pClass));
  54. return pObject;
  55. }
  56. #endif
  57. /////////////////////////////////////////////////////////////////////////////
  58. // Diagnostic Support
  59. #ifdef _DEBUG
  60. void AFXAPI AfxAssertValidObject(const CObject* pOb,
  61. LPCSTR lpszFileName, int nLine)
  62. {
  63. if (pOb == NULL)
  64. {
  65. TRACE0("ASSERT_VALID fails with NULL pointer.\n");
  66. if (AfxAssertFailedLine(lpszFileName, nLine))
  67. AfxDebugBreak();
  68. return; // quick escape
  69. }
  70. if (!AfxIsValidAddress(pOb, sizeof(CObject)))
  71. {
  72. TRACE0("ASSERT_VALID fails with illegal pointer.\n");
  73. if (AfxAssertFailedLine(lpszFileName, nLine))
  74. AfxDebugBreak();
  75. return; // quick escape
  76. }
  77. // check to make sure the VTable pointer is valid
  78. ASSERT(sizeof(CObject) == sizeof(void*));
  79. if (!AfxIsValidAddress(*(void**)pOb, sizeof(void*), FALSE))
  80. {
  81. TRACE0("ASSERT_VALID fails with illegal vtable pointer.\n");
  82. if (AfxAssertFailedLine(lpszFileName, nLine))
  83. AfxDebugBreak();
  84. return; // quick escape
  85. }
  86. if (!AfxIsValidAddress(pOb, pOb->GetRuntimeClass()->m_nObjectSize, FALSE))
  87. {
  88. TRACE0("ASSERT_VALID fails with illegal pointer.\n");
  89. if (AfxAssertFailedLine(lpszFileName, nLine))
  90. AfxDebugBreak();
  91. return; // quick escape
  92. }
  93. pOb->AssertValid();
  94. }
  95. void CObject::AssertValid() const
  96. {
  97. ASSERT(this != NULL);
  98. }
  99. void CObject::Dump(CDumpContext& dc) const
  100. {
  101. dc << "a " << GetRuntimeClass()->m_lpszClassName <<
  102. " at " << (void*)this << "\n";
  103. UNUSED(dc); // unused in release build
  104. }
  105. #endif //_DEBUG
  106. ////////////////////////////////////////////////////////////////////////////
  107. // Allocation/Creation
  108. CObject* CRuntimeClass::CreateObject()
  109. {
  110. if (m_pfnCreateObject == NULL)
  111. {
  112. TRACE(_T("Error: Trying to create object which is not ")
  113. _T("DECLARE_DYNCREATE \nor DECLARE_SERIAL: %hs.\n"),
  114. m_lpszClassName);
  115. return NULL;
  116. }
  117. CObject* pObject = NULL;
  118. TRY
  119. {
  120. pObject = (*m_pfnCreateObject)();
  121. }
  122. END_TRY
  123. return pObject;
  124. }
  125. ////////////////////////////////////////////////////////////////////////////
  126. // Class loader & class serialization
  127. BOOL CObject::IsSerializable() const
  128. {
  129. return (GetRuntimeClass()->m_wSchema != 0xffff);
  130. }
  131. void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
  132. {
  133. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  134. AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  135. pModuleState->m_classList.AddHead(pNewClass);
  136. AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  137. }
  138. AFX_CLASSINIT_COMPAT::AFX_CLASSINIT_COMPAT(CRuntimeClass* pNewClass)
  139. {
  140. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  141. AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  142. pModuleState->m_classList.AddHead(pNewClass);
  143. AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  144. }
  145. BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const
  146. {
  147. ASSERT(this != NULL);
  148. ASSERT(AfxIsValidAddress(this, sizeof(CRuntimeClass), FALSE));
  149. ASSERT(pBaseClass != NULL);
  150. ASSERT(AfxIsValidAddress(pBaseClass, sizeof(CRuntimeClass), FALSE));
  151. // simple SI case
  152. const CRuntimeClass* pClassThis = this;
  153. while (pClassThis != NULL)
  154. {
  155. if (pClassThis == pBaseClass)
  156. return TRUE;
  157. #ifdef _AFXDLL
  158. pClassThis = (*pClassThis->m_pfnGetBaseClass)();
  159. #else
  160. pClassThis = pClassThis->m_pBaseClass;
  161. #endif
  162. }
  163. return FALSE; // walked to the top, no match
  164. }
  165. ////////////////////////////////////////////////////////////////////////////
  166. // CRuntimeClass special diagnostics
  167. #ifdef _DEBUG
  168. void AFXAPI AfxDoForAllClasses(void (AFX_CDECL *pfn)(const CRuntimeClass*, void*),
  169. void* pContext)
  170. {
  171. // just walk through the simple list of registered classes
  172. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  173. AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  174. for (CRuntimeClass* pClass = pModuleState->m_classList; pClass != NULL;
  175. pClass = pClass->m_pNextClass)
  176. {
  177. (*pfn)(pClass, pContext);
  178. }
  179. AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  180. #ifdef _AFXDLL
  181. // walk through the list of dynlink library registered classes
  182. AfxLockGlobals(CRIT_DYNLINKLIST);
  183. for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
  184. pDLL = pDLL->m_pNextDLL)
  185. {
  186. for (pClass = pDLL->m_classList; pClass != NULL;
  187. pClass = pClass->m_pNextClass)
  188. {
  189. (*pfn)(pClass, pContext);
  190. }
  191. }
  192. AfxUnlockGlobals(CRIT_DYNLINKLIST);
  193. #endif
  194. }
  195. #endif //_DEBUG
  196. /////////////////////////////////////////////////////////////////////////////