Leaked source code of windows server 2003
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.

376 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1994.
  5. //
  6. // File: TSource.cxx
  7. //
  8. // Contents: TEXT_SOURCE implementation
  9. //
  10. // Classes: CTextSource
  11. //
  12. // History: 14-Apr-94 KyleP Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. //+-------------------------------------------------------------------------
  18. //
  19. // Member: CTextSource::CTextSource, public
  20. //
  21. // Synopsis: Constructor
  22. //
  23. // Arguments: [pFilter] -- IFilter (source of data)
  24. // [Stat] -- Chunk statistics
  25. //
  26. // History: 01-Aug-93 AmyA Created
  27. // 14-Apr-94 KyleP Sync with wordbreaker spec
  28. //
  29. //--------------------------------------------------------------------------
  30. CTextSource::CTextSource( IFilter * pFilter, STAT_CHUNK & Stat, CSourceMapper* pMapper )
  31. : _pMapper (pMapper),
  32. _pFilter(pFilter),
  33. _Stat( Stat ),
  34. _sc( S_OK )
  35. {
  36. #if 0
  37. CFullPropSpec & ps = *((CFullPropSpec *)&Stat.attribute);
  38. ciDebugOut(( DEB_WORDS,
  39. "TEXT SOURCE: Initial chunk of "
  40. "%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\\",
  41. ps.GetPropSet().Data1,
  42. ps.GetPropSet().Data2,
  43. ps.GetPropSet().Data3,
  44. ps.GetPropSet().Data4[0], ps.GetPropSet().Data4[1],
  45. ps.GetPropSet().Data4[2], ps.GetPropSet().Data4[3],
  46. ps.GetPropSet().Data4[4], ps.GetPropSet().Data4[5],
  47. ps.GetPropSet().Data4[6], ps.GetPropSet().Data4[7] ));
  48. if ( ps.IsPropertyName() )
  49. ciDebugOut(( DEB_WORDS | DEB_NOCOMPNAME,
  50. "%ws\n", ps.GetPropertyName() ));
  51. else
  52. ciDebugOut(( DEB_WORDS | DEB_NOCOMPNAME,
  53. "0x%x\n", ps.GetPropertyPropid() ));
  54. #endif
  55. iEnd = 0;
  56. iCur = 0;
  57. awcBuffer = _awcFilterBuffer;
  58. pfnFillTextBuffer = CTextSource::FillBuf;
  59. if (_pMapper)
  60. {
  61. if (_Stat.idChunk == _Stat.idChunkSource)
  62. {
  63. _pMapper->NewChunk ( _Stat.idChunk, 0 );
  64. }
  65. else
  66. {
  67. _pMapper->NewDerivedChunk (
  68. _Stat.idChunkSource,
  69. _Stat.cwcStartSource,
  70. _Stat.cwcLenSource);
  71. }
  72. }
  73. FillBuf( this );
  74. }
  75. //+-------------------------------------------------------------------------
  76. //
  77. // Member: CTextSource::FillBuf, public
  78. //
  79. // Synopsis: Fills buffer with IFilter::GetText and IFilter::GetChunk
  80. //
  81. // History: 01-Aug-93 AmyA Created
  82. // 20-Apr-94 KyleP Sync with spec
  83. //
  84. // Notes: NOTE! In several places, this function casts const away
  85. // from awcBuffer. This is an acceptable cast from const to
  86. // non-const. The buffer is const to the client but non-const
  87. // to the server.
  88. //
  89. //--------------------------------------------------------------------------
  90. SCODE CTextSource::FillBuf( TEXT_SOURCE * pTextSource )
  91. {
  92. CTextSource * pthis = (CTextSource *)pTextSource;
  93. //
  94. // Never continue past an error condition other than FILTER_E_NO_MORE_TEXT
  95. //
  96. if ( FAILED( pthis->_sc ) && pthis->_sc != FILTER_E_NO_MORE_TEXT )
  97. return( pthis->_sc );
  98. //
  99. // Move any existing text to beginning of buffer.
  100. //
  101. Win4Assert ( pthis->iEnd >= pthis->iCur );
  102. ULONG ccLeftOver = pthis->iEnd - pthis->iCur;
  103. if ( ccLeftOver > 0 )
  104. {
  105. RtlMoveMemory( (WCHAR *)pthis->awcBuffer,
  106. &pthis->awcBuffer[pthis->iCur],
  107. ccLeftOver * sizeof (WCHAR) );
  108. }
  109. if (pthis->_pMapper)
  110. {
  111. // this much has been processed from the current chunk
  112. pthis->_pMapper->Advance ( pthis->iCur );
  113. }
  114. pthis->iCur = 0;
  115. pthis->iEnd = ccLeftOver;
  116. ULONG ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver;
  117. const BUFFER_SLOP = 10; // Buffer is attempted to be filled until BUFFER_SLOP remains
  118. //
  119. // Get some more text. If *previous* call to GetText returned
  120. // FILTER_S_LAST_TEXT, or FILTER_E_NO_MORE_TEXT then don't even
  121. // bother trying.
  122. //
  123. if ( pthis->_sc == FILTER_S_LAST_TEXT || pthis->_sc == FILTER_E_NO_MORE_TEXT )
  124. pthis->_sc = FILTER_E_NO_MORE_TEXT;
  125. else
  126. {
  127. pthis->_sc = pthis->_pFilter->GetText( &ccRead,
  128. (WCHAR *) &pthis->awcBuffer[ccLeftOver] );
  129. if ( SUCCEEDED( pthis->_sc ) )
  130. {
  131. pthis->iEnd += ccRead;
  132. ccLeftOver += ccRead;
  133. ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver;
  134. while ( pthis->_sc == S_OK && ccRead > BUFFER_SLOP )
  135. {
  136. //
  137. // Attempt to fill in as much of buffer as possible before returning
  138. //
  139. pthis->_sc = pthis->_pFilter->GetText( &ccRead,
  140. (WCHAR *) &pthis->awcBuffer[ccLeftOver] );
  141. if ( SUCCEEDED( pthis->_sc ) )
  142. {
  143. pthis->iEnd += ccRead;
  144. ccLeftOver += ccRead;
  145. ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver;
  146. }
  147. }
  148. #if 0
  149. DebugPrintBuffer( pthis );
  150. #endif
  151. //
  152. // Either return FILTER_S_LAST_TEXT or return S_OK because we have succeeded in
  153. // adding text to the buffer
  154. //
  155. if ( pthis->_sc == FILTER_S_LAST_TEXT )
  156. return FILTER_S_LAST_TEXT;
  157. else
  158. return S_OK;
  159. }
  160. if ( pthis->_sc != FILTER_E_NO_MORE_TEXT )
  161. {
  162. //
  163. // Weird failure, hence return, else goto next chunk
  164. //
  165. return pthis->_sc;
  166. }
  167. }
  168. //
  169. // Go to next chunk, if necessary.
  170. //
  171. while ( pthis->_sc == FILTER_E_NO_MORE_TEXT )
  172. {
  173. pthis->_sc = pthis->_pFilter->GetChunk( &pthis->_Stat );
  174. if ( pthis->_sc == FILTER_E_END_OF_CHUNKS )
  175. return WBREAK_E_END_OF_TEXT;
  176. if ( FAILED( pthis->_sc ) )
  177. return( pthis->_sc );
  178. if ( pthis->_Stat.flags & CHUNK_VALUE )
  179. {
  180. pthis->_sc = FILTER_E_NO_TEXT;
  181. return WBREAK_E_END_OF_TEXT;
  182. }
  183. if ( pthis->_Stat.breakType != CHUNK_NO_BREAK )
  184. {
  185. pthis->_sc = WBREAK_E_END_OF_TEXT;
  186. return WBREAK_E_END_OF_TEXT;
  187. }
  188. #if 0
  189. ciDebugOut(( DEB_WORDS, "TEXT SOURCE: NoBreak chunk\n" ));
  190. #endif
  191. if (pthis->_pMapper)
  192. {
  193. ULONG idChunk = pthis->_Stat.idChunk;
  194. if (idChunk == pthis->_Stat.idChunkSource)
  195. {
  196. pthis->_pMapper->NewChunk ( idChunk, ccLeftOver );
  197. }
  198. else
  199. {
  200. pthis->_sc = WBREAK_E_END_OF_TEXT;
  201. return WBREAK_E_END_OF_TEXT;
  202. }
  203. }
  204. ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver;
  205. pthis->_sc = pthis->_pFilter->GetText( &ccRead,
  206. (WCHAR *) &pthis->awcBuffer[ccLeftOver] );
  207. if ( SUCCEEDED( pthis->_sc ) )
  208. {
  209. pthis->iEnd += ccRead;
  210. ccLeftOver += ccRead;
  211. ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver;
  212. while ( pthis->_sc == S_OK && ccRead > BUFFER_SLOP )
  213. {
  214. //
  215. // Attempt to fill in as much of buffer as possible before returning
  216. //
  217. pthis->_sc = pthis->_pFilter->GetText( &ccRead,
  218. (WCHAR *) &pthis->awcBuffer[ccLeftOver] );
  219. if ( SUCCEEDED( pthis->_sc ) )
  220. {
  221. pthis->iEnd += ccRead;
  222. ccLeftOver += ccRead;
  223. ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver;
  224. }
  225. }
  226. #if 0
  227. DebugPrintBuffer( pthis );
  228. #endif
  229. //
  230. // Either return FILTER_S_LAST_TEXT or return S_OK because we have succeeded in
  231. // adding text to the buffer
  232. //
  233. if ( pthis->_sc == FILTER_S_LAST_TEXT )
  234. return FILTER_S_LAST_TEXT;
  235. else
  236. return S_OK;
  237. }
  238. }
  239. if ( FAILED( pthis->_sc ) )
  240. return( pthis->_sc );
  241. if ( ccRead == 0 )
  242. return WBREAK_E_END_OF_TEXT;
  243. Win4Assert( pthis->iCur == 0 );
  244. Win4Assert( pthis->iEnd == ccLeftOver );
  245. #if 0
  246. ciDebugOut(( DEB_WORDS, "TEXT SOURCE: Fill buffer with %d characters. %d left over\n",
  247. pthis->iEnd, ccLeftOver ));
  248. #endif
  249. return S_OK;
  250. }
  251. //+-------------------------------------------------------------------------
  252. //
  253. // Member: CTextSource::DebugPrintBuffer
  254. //
  255. // Synopsis: Debug print the text buffer
  256. //
  257. // Arguments: [pThis] -- Pointer to text source
  258. //
  259. // History: 08-Apr-97 SitaramR Created
  260. //
  261. //--------------------------------------------------------------------------
  262. void CTextSource::DebugPrintBuffer( CTextSource *pthis )
  263. {
  264. #if 0
  265. if ( ciInfoLevel & DEB_WORDS )
  266. {
  267. ciDebugOut(( DEB_WORDS, "CTextSource::FillBuf -- iCur = %u, iEnd = %u\n",
  268. pthis->iCur, pthis->iEnd ));
  269. BOOL fOk = TRUE;
  270. for ( unsigned i = pthis->iCur; i < pthis->iEnd; i++ )
  271. {
  272. if ( pthis->awcBuffer[i] > 0xFF )
  273. {
  274. fOk = FALSE;
  275. break;
  276. }
  277. }
  278. if ( fOk )
  279. {
  280. unsigned j = 0;
  281. WCHAR awcTemp[71];
  282. for ( unsigned i = pthis->iCur; i < pthis->iEnd; i++ )
  283. {
  284. awcTemp[j] = pthis->awcBuffer[i];
  285. j++;
  286. if ( j == sizeof(awcTemp)/sizeof(awcTemp[0]) - 1 )
  287. {
  288. awcTemp[j] = 0;
  289. ciDebugOut(( DEB_WORDS, "%ws\n", awcTemp ));
  290. j = 0;
  291. }
  292. }
  293. awcTemp[j] = 0;
  294. ciDebugOut(( DEB_WORDS, "%ws\n", awcTemp ));
  295. }
  296. else
  297. {
  298. unsigned j = 0;
  299. for ( unsigned i = pthis->iCur; i < pthis->iEnd; i++ )
  300. {
  301. if ( 0 == j )
  302. ciDebugOut(( DEB_WORDS, "%04X", pthis->awcBuffer[i] ));
  303. else if ( 14 == j )
  304. {
  305. ciDebugOut(( DEB_WORDS | DEB_NOCOMPNAME, " %04X\n", pthis->awcBuffer[i] ));
  306. }
  307. else
  308. ciDebugOut(( DEB_WORDS | DEB_NOCOMPNAME, " %04X", pthis->awcBuffer[i] ));
  309. j++;
  310. if ( j > 14 )
  311. j = 0;
  312. }
  313. ciDebugOut(( DEB_WORDS | DEB_NOCOMPNAME, "\n" ));
  314. }
  315. }
  316. #endif
  317. }