windows-nt/Source/XPSP1/NT/inetsrv/query/apps/srch/brdoc.hxx
2020-09-26 16:20:57 +08:00

235 lines
5 KiB
C++

//+-------------------------------------------------------------------------
//
// 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<Hit *> _aHit;
unsigned _cHit;
IFilter* _pFilter;
unsigned * _aParaOffset; // array of offsets of paragraphs
int _cPara;
int _maxParaLen;
int _chunkCount;
CDynArrayInPlace<ChunkOffset> _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;
}