|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 1994.
//
// File: TSource.cxx
//
// Contents: TEXT_SOURCE implementation
//
// Classes: CTextSource
//
// History: 14-Apr-94 KyleP Created
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
//+-------------------------------------------------------------------------
//
// Member: CTextSource::CTextSource, public
//
// Synopsis: Constructor
//
// Arguments: [pFilter] -- IFilter (source of data)
// [Stat] -- Chunk statistics
//
// History: 01-Aug-93 AmyA Created
// 14-Apr-94 KyleP Sync with wordbreaker spec
//
//--------------------------------------------------------------------------
CTextSource::CTextSource( IFilter * pFilter, STAT_CHUNK & Stat, CSourceMapper* pMapper ) : _pMapper (pMapper), _pFilter(pFilter), _Stat( Stat ), _sc( S_OK ) { iEnd = 0; iCur = 0; awcBuffer = _awcFilterBuffer; pfnFillTextBuffer = CTextSource::FillBuf;
if (_pMapper) { if (_Stat.idChunk == _Stat.idChunkSource) { _pMapper->NewChunk ( _Stat.idChunk, 0 ); } else { _pMapper->NewDerivedChunk ( _Stat.idChunkSource, _Stat.cwcStartSource, _Stat.cwcLenSource); } }
FillBuf( this ); }
//+-------------------------------------------------------------------------
//
// Member: CTextSource::FillBuf, public
//
// Synopsis: Fills buffer with IFilter::GetText and IFilter::GetChunk
//
// History: 01-Aug-93 AmyA Created
// 20-Apr-94 KyleP Sync with spec
//
// Notes: NOTE! In several places, this function casts const away
// from awcBuffer. This is an acceptable cast from const to
// non-const. The buffer is const to the client but non-const
// to the server.
//
//--------------------------------------------------------------------------
SCODE CTextSource::FillBuf( TEXT_SOURCE * pTextSource ) { CTextSource * pthis = (CTextSource *)pTextSource;
//
// Never continue past an error condition other than FILTER_E_NO_MORE_TEXT
//
if ( FAILED( pthis->_sc ) && pthis->_sc != FILTER_E_NO_MORE_TEXT ) return( pthis->_sc );
//
// Move any existing text to beginning of buffer.
//
Win4Assert ( pthis->iEnd >= pthis->iCur );
ULONG ccLeftOver = pthis->iEnd - pthis->iCur;
if ( ccLeftOver > 0 ) { RtlMoveMemory( (WCHAR *)pthis->awcBuffer, &pthis->awcBuffer[pthis->iCur], ccLeftOver * sizeof (WCHAR) ); }
if (pthis->_pMapper) { // this much has been processed from the current chunk
pthis->_pMapper->Advance ( pthis->iCur ); }
pthis->iCur = 0; pthis->iEnd = ccLeftOver; ULONG ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver; const BUFFER_SLOP = 10; // Buffer is attempted to be filled until BUFFER_SLOP remains
//
// Get some more text. If *previous* call to GetText returned
// FILTER_S_LAST_TEXT, or FILTER_E_NO_MORE_TEXT then don't even
// bother trying.
//
if ( pthis->_sc == FILTER_S_LAST_TEXT || pthis->_sc == FILTER_E_NO_MORE_TEXT ) pthis->_sc = FILTER_E_NO_MORE_TEXT; else { pthis->_sc = pthis->_pFilter->GetText( &ccRead, (WCHAR *) &pthis->awcBuffer[ccLeftOver] );
if ( SUCCEEDED( pthis->_sc ) ) { pthis->iEnd += ccRead; ccLeftOver += ccRead; ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver;
while ( pthis->_sc == S_OK && ccRead > BUFFER_SLOP ) { //
// Attempt to fill in as much of buffer as possible before returning
//
pthis->_sc = pthis->_pFilter->GetText( &ccRead, (WCHAR *) &pthis->awcBuffer[ccLeftOver] ); if ( SUCCEEDED( pthis->_sc ) ) { pthis->iEnd += ccRead; ccLeftOver += ccRead; ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver; } }
#if 0
DebugPrintBuffer( pthis ); #endif
//
// Either return FILTER_S_LAST_TEXT or return S_OK because we have succeeded in
// adding text to the buffer
//
if ( pthis->_sc == FILTER_S_LAST_TEXT ) return FILTER_S_LAST_TEXT; else return S_OK; }
if ( pthis->_sc != FILTER_E_NO_MORE_TEXT ) { //
// Weird failure, hence return, else goto next chunk
//
return pthis->_sc; } }
//
// Go to next chunk, if necessary.
//
while ( pthis->_sc == FILTER_E_NO_MORE_TEXT ) { pthis->_sc = pthis->_pFilter->GetChunk( &pthis->_Stat );
if ( pthis->_sc == FILTER_E_END_OF_CHUNKS ) return WBREAK_E_END_OF_TEXT;
if ( FAILED( pthis->_sc ) ) return( pthis->_sc );
if ( pthis->_Stat.flags & CHUNK_VALUE ) { pthis->_sc = FILTER_E_NO_TEXT; return WBREAK_E_END_OF_TEXT; }
if ( pthis->_Stat.breakType != CHUNK_NO_BREAK ) { pthis->_sc = WBREAK_E_END_OF_TEXT; return WBREAK_E_END_OF_TEXT; }
#if 0
ciDebugOut(( DEB_WORDS, "TEXT SOURCE: NoBreak chunk\n" )); #endif
if (pthis->_pMapper) { ULONG idChunk = pthis->_Stat.idChunk; if (idChunk == pthis->_Stat.idChunkSource) { pthis->_pMapper->NewChunk ( idChunk, ccLeftOver ); } else { pthis->_sc = WBREAK_E_END_OF_TEXT; return WBREAK_E_END_OF_TEXT; } }
ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver; pthis->_sc = pthis->_pFilter->GetText( &ccRead, (WCHAR *) &pthis->awcBuffer[ccLeftOver] );
if ( SUCCEEDED( pthis->_sc ) ) { pthis->iEnd += ccRead; ccLeftOver += ccRead; ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver;
while ( pthis->_sc == S_OK && ccRead > BUFFER_SLOP ) { //
// Attempt to fill in as much of buffer as possible before returning
//
pthis->_sc = pthis->_pFilter->GetText( &ccRead, (WCHAR *) &pthis->awcBuffer[ccLeftOver] ); if ( SUCCEEDED( pthis->_sc ) ) { pthis->iEnd += ccRead; ccLeftOver += ccRead; ccRead = PAGE_SIZE / sizeof(WCHAR) - ccLeftOver; } }
#if 0
DebugPrintBuffer( pthis ); #endif
//
// Either return FILTER_S_LAST_TEXT or return S_OK because we have succeeded in
// adding text to the buffer
//
if ( pthis->_sc == FILTER_S_LAST_TEXT ) return FILTER_S_LAST_TEXT; else return S_OK; } }
if ( FAILED( pthis->_sc ) ) return( pthis->_sc );
if ( ccRead == 0 ) return WBREAK_E_END_OF_TEXT;
Win4Assert( pthis->iCur == 0 ); Win4Assert( pthis->iEnd == ccLeftOver );
#if 0
ciDebugOut(( DEB_WORDS, "TEXT SOURCE: Fill buffer with %d characters. %d left over\n", pthis->iEnd, ccLeftOver )); #endif
return S_OK; }
//+-------------------------------------------------------------------------
//
// Member: CTextSource::DebugPrintBuffer
//
// Synopsis: Debug print the text buffer
//
// Arguments: [pThis] -- Pointer to text source
//
// History: 08-Apr-97 SitaramR Created
//
//--------------------------------------------------------------------------
void CTextSource::DebugPrintBuffer( CTextSource *pthis ) { #if 0
if ( ciInfoLevel & DEB_WORDS ) { ciDebugOut(( DEB_WORDS, "CTextSource::FillBuf -- iCur = %u, iEnd = %u\n", pthis->iCur, pthis->iEnd ));
BOOL fOk = TRUE; for ( unsigned i = pthis->iCur; i < pthis->iEnd; i++ ) { if ( pthis->awcBuffer[i] > 0xFF ) { fOk = FALSE; break; } }
if ( fOk ) { unsigned j = 0; WCHAR awcTemp[71];
for ( unsigned i = pthis->iCur; i < pthis->iEnd; i++ ) { awcTemp[j] = pthis->awcBuffer[i]; j++;
if ( j == sizeof(awcTemp)/sizeof(awcTemp[0]) - 1 ) { awcTemp[j] = 0; ciDebugOut(( DEB_WORDS, "%ws\n", awcTemp )); j = 0; } }
awcTemp[j] = 0; ciDebugOut(( DEB_WORDS, "%ws\n", awcTemp )); } else { unsigned j = 0;
for ( unsigned i = pthis->iCur; i < pthis->iEnd; i++ ) { if ( 0 == j ) ciDebugOut(( DEB_WORDS, "%04X", pthis->awcBuffer[i] )); else if ( 14 == j ) { ciDebugOut(( DEB_WORDS | DEB_NOCOMPNAME, " %04X\n", pthis->awcBuffer[i] )); } else ciDebugOut(( DEB_WORDS | DEB_NOCOMPNAME, " %04X", pthis->awcBuffer[i] ));
j++;
if ( j > 14 ) j = 0; }
ciDebugOut(( DEB_WORDS | DEB_NOCOMPNAME, "\n" )); }
} #endif
}
|