objcore.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. #ifndef WINSCP
  132. void AFXAPI AfxClassInit(CRuntimeClass* pNewClass)
  133. {
  134. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  135. AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  136. pModuleState->m_classList.AddHead(pNewClass);
  137. AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  138. }
  139. AFX_CLASSINIT_COMPAT::AFX_CLASSINIT_COMPAT(CRuntimeClass* pNewClass)
  140. {
  141. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  142. AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  143. pModuleState->m_classList.AddHead(pNewClass);
  144. AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  145. }
  146. BOOL CRuntimeClass::IsDerivedFrom(const CRuntimeClass* pBaseClass) const
  147. {
  148. ASSERT(this != NULL);
  149. ASSERT(AfxIsValidAddress(this, sizeof(CRuntimeClass), FALSE));
  150. ASSERT(pBaseClass != NULL);
  151. ASSERT(AfxIsValidAddress(pBaseClass, sizeof(CRuntimeClass), FALSE));
  152. // simple SI case
  153. const CRuntimeClass* pClassThis = this;
  154. while (pClassThis != NULL)
  155. {
  156. if (pClassThis == pBaseClass)
  157. return TRUE;
  158. #ifdef _AFXDLL
  159. pClassThis = (*pClassThis->m_pfnGetBaseClass)();
  160. #else
  161. pClassThis = pClassThis->m_pBaseClass;
  162. #endif
  163. }
  164. return FALSE; // walked to the top, no match
  165. }
  166. ////////////////////////////////////////////////////////////////////////////
  167. // CRuntimeClass special diagnostics
  168. #ifdef _DEBUG
  169. void AFXAPI AfxDoForAllClasses(void (AFX_CDECL *pfn)(const CRuntimeClass*, void*),
  170. void* pContext)
  171. {
  172. // just walk through the simple list of registered classes
  173. AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
  174. AfxLockGlobals(CRIT_RUNTIMECLASSLIST);
  175. for (CRuntimeClass* pClass = pModuleState->m_classList; pClass != NULL;
  176. pClass = pClass->m_pNextClass)
  177. {
  178. (*pfn)(pClass, pContext);
  179. }
  180. AfxUnlockGlobals(CRIT_RUNTIMECLASSLIST);
  181. #ifdef _AFXDLL
  182. // walk through the list of dynlink library registered classes
  183. AfxLockGlobals(CRIT_DYNLINKLIST);
  184. for (CDynLinkLibrary* pDLL = pModuleState->m_libraryList; pDLL != NULL;
  185. pDLL = pDLL->m_pNextDLL)
  186. {
  187. for (pClass = pDLL->m_classList; pClass != NULL;
  188. pClass = pClass->m_pNextClass)
  189. {
  190. (*pfn)(pClass, pContext);
  191. }
  192. }
  193. AfxUnlockGlobals(CRIT_DYNLINKLIST);
  194. #endif
  195. }
  196. #endif //_DEBUG
  197. #endif // WINSCP
  198. /////////////////////////////////////////////////////////////////////////////