//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 2000. // // File: brdoc.hxx // // Contents: // // History: 15 Aug 1996 DLee Created // //-------------------------------------------------------------------------- #pragma once class ChunkOffset { public: void SetChunkId (ULONG id) { _idChunk = id; } void SetOffset (ULONG off) { _offset = off; } ULONG ChunkId () const { return _idChunk; } ULONG Offset () const { return _offset; } private: ULONG _idChunk; ULONG _offset; }; class Position { public: Position () { Init (); } Position ( int para, int begOff, int len ) : _para (para), _begOff(begOff), _endOff (_begOff + len) {} void Init () { _para = 0; _begOff = 0; _endOff = 0; } int Para () const { return _para; } int BegOff () const { return _begOff; } int EndOff () const { return _endOff; } int Len () const { return _endOff - _begOff; } void SetLen (int len) { _endOff = _begOff + len; } void IncBegOff () { _begOff++; } void NewLine () { _begOff = 0; _para++; } int Compare( const Position& pos) const; private: int _para; int _begOff; int _endOff; }; class Hit { public: Hit( const Position * aPos, unsigned cPos ); ~Hit(); unsigned Count() const { return _cPos; } const Position& GetPos (int i) const { Win4Assert ( i < int(_cPos) ); return _aPos[i]; } private: Position * _aPos; unsigned _cPos; }; class ParaLine { public: ParaLine() : next(0) {} int offEnd; ParaLine* next; }; class Document { friend class HitIter; public: Document (); Document (WCHAR const* filename, LONG rank, BOOL fDelete ); ~Document(); void Free(); // // Initialization methods // SCODE Init(ISearchQueryHits *pSearch); BOOL ConvertPositionsToHit( LONG rank ); // // Viewing methods // BOOL GetLine(int nPara, int off, int& cwc, WCHAR* buf); void GetWord(int nPara, int offSrc, int cwcSrc, WCHAR* buf); const WCHAR* Filename() const { return _filename;} int MaxParaLen () const { return _maxParaLen; } int Paras () const {return _cPara; } WCHAR* Buffer () const { return _buffer; } WCHAR* BufEnd () const { return _bufEnd; } LONG Rank () const { return _rank; } BOOL IsInit () const { return _isInit; } unsigned Hits () const { return _cHit; } ChunkOffset OffsetToChunkOffset ( ULONG offset ) const { for (int i = 0; i < _chunkCount; i++) if (offset < _chunk[i].Offset()) break; Win4Assert ( i > 0 ); i -= 1; ChunkOffset off; off.SetChunkId (_chunk[i].ChunkId()); off.SetOffset (offset - _chunk[i].Offset()); return off; } ParaLine const * GetParaLine() const { return _aParaLine; } private: void AllocBuffer( WCHAR const * pwcPath ); void BindToFilter( WCHAR const * pwcPath ); void ReadFile (); void BreakParas(); void BreakLines(); WCHAR * EatPara( WCHAR * pCur ); Position RegionToPos ( FILTERREGION& region ); ISearchQueryHits* _pSearch; WCHAR * _filename; LONG _rank; WCHAR * _buffer; ULONG _bufLen; WCHAR * _bufEnd; BOOL _isInit; CDynArrayInPlace _aHit; unsigned _cHit; IFilter* _pFilter; unsigned * _aParaOffset; // array of offsets of paragraphs int _cPara; int _maxParaLen; int _chunkCount; CDynArrayInPlace _chunk; ParaLine* _aParaLine; BOOL _fDelete; }; class HitIter { public: HitIter () : _pDoc (0), _cHit(0), _iHit(0), _iRestoreHit(0) {} void Init (const Document* pDoc) { _pDoc = pDoc; _cHit = pDoc->Hits(); _iHit = 0; _iRestoreHit = 0; } BOOL FirstHit(); BOOL PrevHit(); BOOL NextHit(); void SaveHit() { _iRestoreHit = _iHit; } void RestoreHit() { _iHit = _iRestoreHit; } BOOL isSavedCurrent() { return _iRestoreHit == _iHit; } BOOL isLastHit() { return(_cHit == 0 || _iHit == _cHit - 1); } BOOL isFirstHit() { return(_iHit == 0); } int GetPositionCount () const; Position GetPosition ( int i ) const; int HitCount() { return _cHit; } int CurrentHit() { return _iHit; } int ParaCount() { return _pDoc->Paras(); } private: const Document* _pDoc; unsigned _cHit; unsigned _iHit; unsigned _iRestoreHit; }; inline BOOL HitIter::PrevHit() { if ( _cHit!= 0 && _iHit > 0 ) { _iHit--; return TRUE; } return FALSE; } inline BOOL HitIter::FirstHit() { if ( _cHit != 0 ) { _iHit = 0; return TRUE; } return FALSE; } inline BOOL HitIter::NextHit() { if ( _cHit != 0 && _iHit + 1 < _cHit) { _iHit++; return TRUE; } return FALSE; }