Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
5.0 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997
  5. //
  6. // File: stemcf.cxx
  7. //
  8. // Contents: Stemmer class factory
  9. //
  10. // History: weibz, 10-Sep-1997 created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <pch.cxx>
  14. #include "stemcf.hxx"
  15. #include "stemmer.hxx"
  16. extern long gulcInstances;
  17. //+-------------------------------------------------------------------------
  18. //
  19. // Method: CStemmerCF::CStemmerCF
  20. //
  21. // Synopsis: Stemmer class factory constructor
  22. //
  23. //--------------------------------------------------------------------------
  24. CStemmerCF::CStemmerCF( LCID lcid )
  25. : _cRefs( 1 ), _lcid( lcid )
  26. {
  27. InterlockedIncrement( &gulcInstances );
  28. }
  29. //+-------------------------------------------------------------------------
  30. //
  31. // Method: CStemmerCF::~CStemmerCF
  32. //
  33. // Synopsis: Stemmer class factory destructor
  34. //
  35. //--------------------------------------------------------------------------
  36. CStemmerCF::~CStemmerCF()
  37. {
  38. InterlockedDecrement( &gulcInstances );
  39. }
  40. //+-------------------------------------------------------------------------
  41. //
  42. // Method: CStemmerCF::QueryInterface
  43. //
  44. // Synopsis: Rebind to other interface
  45. //
  46. // Arguments: [riid] -- IID of new interface
  47. // [ppvObject] -- New interface * returned here
  48. //
  49. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  50. //
  51. //--------------------------------------------------------------------------
  52. SCODE STDMETHODCALLTYPE CStemmerCF::QueryInterface( REFIID riid,
  53. void ** ppvObject )
  54. {
  55. //
  56. // Optimize QueryInterface by only checking minimal number of bytes.
  57. //
  58. // IID_IUnknown = 00000000-0000-0000-C000-000000000046
  59. // IID_IClassFactory = 00000001-0000-0000-C000-000000000046
  60. // --
  61. // |
  62. // +--- Unique!
  63. //
  64. Assert( (IID_IUnknown.Data1 & 0x000000FF) == 0x00 );
  65. Assert( (IID_IClassFactory.Data1 & 0x000000FF) == 0x01 );
  66. IUnknown *pUnkTemp;
  67. SCODE sc = S_OK;
  68. switch( riid.Data1 & 0x000000FF )
  69. {
  70. case 0x00:
  71. if ( riid == IID_IUnknown )
  72. pUnkTemp = (IUnknown *)this;
  73. else
  74. sc = E_NOINTERFACE;
  75. break;
  76. case 0x01:
  77. if ( riid == IID_IClassFactory )
  78. pUnkTemp = (IUnknown *)(IClassFactory *)this;
  79. else
  80. sc = E_NOINTERFACE;
  81. break;
  82. default:
  83. pUnkTemp = 0;
  84. sc = E_NOINTERFACE;
  85. break;
  86. }
  87. if( 0 != pUnkTemp )
  88. {
  89. *ppvObject = (void * )pUnkTemp;
  90. pUnkTemp->AddRef();
  91. }
  92. else
  93. *ppvObject = 0;
  94. return(sc);
  95. }
  96. //+-------------------------------------------------------------------------
  97. //
  98. // Method: CStemmerCF::AddRef
  99. //
  100. // Synopsis: Increments refcount
  101. //
  102. //--------------------------------------------------------------------------
  103. ULONG STDMETHODCALLTYPE CStemmerCF::AddRef()
  104. {
  105. return InterlockedIncrement( &_cRefs );
  106. }
  107. //+-------------------------------------------------------------------------
  108. //
  109. // Method: CStemmerCF::Release
  110. //
  111. // Synopsis: Decrement refcount. Delete if necessary.
  112. //
  113. //--------------------------------------------------------------------------
  114. ULONG STDMETHODCALLTYPE CStemmerCF::Release()
  115. {
  116. unsigned long uTmp = InterlockedDecrement( &_cRefs );
  117. if ( 0 == uTmp )
  118. delete this;
  119. return(uTmp);
  120. }
  121. //+-------------------------------------------------------------------------
  122. //
  123. // Method: CStemmerCF::CreateInstance
  124. //
  125. // Synopsis: Creates new CStemmer object
  126. //
  127. // Arguments: [pUnkOuter] -- 'Outer' IUnknown
  128. // [riid] -- Interface to bind
  129. // [ppvObject] -- Interface returned here
  130. //
  131. //--------------------------------------------------------------------------
  132. SCODE STDMETHODCALLTYPE CStemmerCF::CreateInstance( IUnknown * pUnkOuter,
  133. REFIID riid,
  134. void * * ppvObject )
  135. {
  136. CStemmer *pIUnk = 0;
  137. SCODE sc = S_OK;
  138. __try
  139. {
  140. pIUnk = new CStemmer( _lcid );
  141. sc = pIUnk->QueryInterface( riid , ppvObject );
  142. pIUnk->Release(); // Release extra refcount from QueryInterface
  143. }
  144. __except(1)
  145. {
  146. Assert( 0 == pIUnk );
  147. sc = E_UNEXPECTED;
  148. }
  149. return (sc);
  150. }
  151. //+-------------------------------------------------------------------------
  152. //
  153. // Method: CStemmerCF::LockServer
  154. //
  155. // Synopsis: Force class factory to remain loaded
  156. //
  157. // Arguments: [fLock] -- TRUE if locking, FALSE if unlocking
  158. //
  159. // Returns: S_OK
  160. //
  161. //--------------------------------------------------------------------------
  162. SCODE STDMETHODCALLTYPE CStemmerCF::LockServer(BOOL fLock)
  163. {
  164. if(fLock)
  165. InterlockedIncrement( &gulcInstances );
  166. else
  167. InterlockedDecrement( &gulcInstances );
  168. return(S_OK);
  169. }