|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1998.
//
// File: linkhits.hxx
//
// Classes: CInternalQuery - class used to convert a textual query to
// a CDbRestriction
// CGetEnvVars - class used to obtain and store CGI environment
// variables
// CQueryStringParser - class used to parse the QUERY_STRING
// CGI variable
// CURLUnescaper - class to unescape URL fragments
// CSortQueryHits - class used to sort the positions making up
// the hits returned by a query into the order
// in which these positions appear in the document
// CLinkQueryHits - class used to generate an HTML page allowing
// the user to navigate among the words making up
// the hits using "<<" (prev) and ">>" (next)
// tags.
//
// Contents: class declarations for the hit-highliting feature in TRIPOLI
//
//
// History: 05-15-96 t-matts Created
//
//--------------------------------------------------------------------------
#pragma once
#include <dbcmdtre.hxx>
#include <restrict.hxx>
#include <vquery.hxx>
#include <plist.hxx>
#include <strrest.hxx>
#include <string.hxx>
#include <cgiesc.hxx>
#include <scanner.hxx>
#include "cdoc.hxx"
#include "whtmplat.hxx"
const int MAX_VARIABLE_SIZE = 4096; const int MAX_HILITE_TYPE = 32; const int _MAX_BUFFER = 4096;
class CLinkQueryHits; class CCollectVar; class CGetEnvVars; class PHttpOutput; class CURLUnescaper; class CSmartByteArray;
LCID GetLCID( CWebServer & webServer );
//
// names of CGI variables and QUERY_STRING parameters globally defined to avoid
// hard-coded checks when parsing
//
extern const WCHAR CommandLineVarName[]; extern const WCHAR RestrictionVarName[]; extern const WCHAR IDQFilenameVarName[]; extern const WCHAR HiliteTypeVarName[]; extern const WCHAR ColorVarName[]; extern const WCHAR BoldVarName[]; extern const WCHAR ItalicVarName[]; extern const WCHAR ParaTag[]; extern const WCHAR HRule[];
extern const WCHAR Red24BitMask[]; extern const WCHAR Blue24BitMask[]; extern const WCHAR Green24BitMask[]; extern const WCHAR Black24BitMask[]; extern const WCHAR Yellow24BitMask[];
//+---------------------------------------------------------------------------
//
// Class: CLanguageInfo
//
// Purpose: Class to track client and output code page.
//
// History: 9-12-96 srikants Created
//
// Notes: For converting the URL, we use locales in the following order
// of precedence:
//
// 1. HTTP_ACCEPT_LANGUAGE
// 2. Server/System Default
//
// For output of webhits results and for interpreting the
// CiRestriction, we use the following precedence.
//
// 1. CiLocale
// 2. HTTP_ACCEPT_LANGUAGE
// 3. Server/System Default
//
//----------------------------------------------------------------------------
class CLanguageInfo {
public:
enum { eAnsiCodePage = 1252 };
CLanguageInfo() : _urlCodePage(eAnsiCodePage), _outputCodePage(0) { _urlLCID = GetSystemDefaultLCID(); _queryLCID = _urlLCID; }
void SetUrlLangInfo( UINT codePage, LCID lcid ) { _urlCodePage = codePage; _urlLCID = lcid; } LCID GetUrlLCID() const { return _urlLCID; } ULONG GetUrlCodePage() const { return _urlCodePage; }
void SetRestrictionLangInfo( UINT codePage, LCID lcid ) { if ( codePage != _outputCodePage ) { _outputCodePage = SetCodePageForCRunTimes( codePage ); }
_queryLCID = lcid; }
void SetRestrictionLocale(LCID lcid) { _queryLCID = lcid; }
void SetRestrictionCodepage(UINT codepage) { _urlCodePage = codepage; }
ULONG GetOutputCodePage() const { return _outputCodePage; } LCID GetQueryLCID() const { return _queryLCID; }
private:
UINT SetCodePageForCRunTimes( UINT codePage );
//
// These variables are set depending upon the HTTP_ACCEPT_LANGUAGE.
// If there is no HTTP_ACCEPT_LANGUAGE, System default is used.
//
UINT _urlCodePage; // code page of the browser (HTTP_ACCEPT_LANGUAGE)
LCID _urlLCID; // LCID of the browser (HTTP_ACCEPT_LANGUAGE)
//
// These are set depending upon CiLocale, HTTP_ACCEPT_LANGUAGE,
// System Default, in that order.
//
LCID _queryLCID; // LCID in which the query must be interpreted
UINT _outputCodePage; // code page of the document and output
};
//+-------------------------------------------------------------------------
//
// Class: CInternalQueryx
//
// Purpose: Convert a textual query to a DbRestriction
//
// History: 05-14-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CInternalQuery { public:
CInternalQuery(CGetEnvVars& rGetEnvVars, CEmptyPropertyList& rPList, LCID lcid );
~CInternalQuery();
CDbRestriction& GetDbRestrictionRef() { Win4Assert(0 != _pDbRestriction); return *_pDbRestriction; }
void CreateISearch( WCHAR const * pwszPath );
ISearchQueryHits & GetISearchRef() { Win4Assert( 0 != _pISearch ); return *_pISearch; }
private:
CDbRestriction* _pDbRestriction; ISearchQueryHits * _pISearch;
};
inline CInternalQuery::~CInternalQuery()
{ delete _pDbRestriction; if ( 0 != _pISearch ) _pISearch->Release(); }
//+-------------------------------------------------------------------------
//
// Class: CSmartByteArray
//
// Purpose: Dynamically re-sizing text container, with a CopyTo operator
// that allows fast copies and automatically appends a '\0'.
// Used to extract chunks of text from memory
//
// History: 07-11-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CSmartByteArray { public:
//
// default size of buffer until something larger is placed in it through
// CopyTo
//
enum DefSize{ DEFAULT_BUFFER_SIZE = 1024 };
CSmartByteArray(); void CopyTo(char* pszText, ULONG cbToCopy);
XArray<CHAR>& GetXPtr() { return _xszBuffer; } char * GetPointer() { return _xszBuffer.GetPointer(); }
private:
XArray<CHAR> _xszBuffer;
};
//+-------------------------------------------------------------------------
//
// Class: CCollectVar
//
// Purpose: Used to retrieve environment variables as well
// temporarily store them.
//
// History: 07-02-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CCollectVar { public:
enum DefSize{ DEFAULT_BUFF_SIZE = 1024 };
CCollectVar( CURLUnescaper& rUnescaper, CWebServer & webServer );
//
// returns ref. to smart pointer to variable value
//
const WCHAR* GetVarValue() { return _xwcsBuffer.GetPointer(); } int GetVarSize() { return _cwcVarSize; }
BOOL GetEnvVar(CHAR const * pszVariableName);
const char * GetMultiByteStr() const { return _xszBuffer.GetPointer(); } int GetMultiByteStrLen() const { return _cbVarSize; }
void UnescapeAndConvertToUnicode();
private:
CURLUnescaper& _rUnescaper; CWebServer & _webServer;
XArray<WCHAR> _xwcsBuffer; // Buffer to store the unicode str
int _cwcVarSize; // Length of the un-escaped unicode
// string in WCHARS excluding
// terminating NULL.
XArray<CHAR> _xszBuffer; // Buffer to store the ansi string
int _cbVarSize; // Length of string excluding the
};
//+-------------------------------------------------------------------------
//
// Class: CQueryStringParser
//
// Purpose: Used to parse the QUERY_STRING CGI variable
//
// History: 07-08-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CQueryStringParser { public:
CQueryStringParser( char * pszQUERY_STRING, CURLUnescaper& rUnescaper);
void GetVarName(XPtrST<WCHAR>& rDestVarName) { rDestVarName.Set(_xwszVarName.Acquire()); } void GetVarValue(XPtrST<WCHAR>& rDestVarValue) { rDestVarValue.Set(_xwszVarValue.Acquire()); }
BOOL NextVar(); BOOL IsNull() { return _isNull; }
private:
char * EatChar(char *psz); char * ValidateArgument(char * psz); char * EatVariableName(char * psz);
char * FindVarEnd(char * psz);
char * _pszQS; char * _pszQSEnd; char * _pBeg; char * _pEnd;
BOOL _isNull;
XArray<WCHAR> _xwszVarName; XArray<WCHAR> _xwszVarValue;
CURLUnescaper& _rUnescaper; CSmartByteArray _smartBuffer; };
//+-------------------------------------------------------------------------
//
// Class: CURLUnescaper
//
// Purpose: Unescape an URL fragment
//
// History: 07-09-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CURLUnescaper {
public:
CURLUnescaper( UINT codePage );
ULONG UnescapeAndConvertToUnicode( char const * pszMbStr, ULONG cc, XArray<WCHAR> & xwcsBuffer );
private:
UINT _codePage;
};
//+-------------------------------------------------------------------------
//
// Class: CGetEnvVars
//
// Purpose: Get CGI environment variables necessary to perform hit
// highliting
//
// History: 05-20-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CGetEnvVars { public:
enum { eMaxUserReplParams = 10 };
enum REQUEST_METHOD { GET, POST };
enum HiliteType { SUMMARY=0, FULL, PRETTY };
CGetEnvVars( CWebServer & webServer, CLanguageInfo & langInfo, CCollectVar& rCollectVar, CURLUnescaper& rUnescaper );
const WCHAR* GetRestriction() const { return _xwcsRestriction.GetPointer(); }
const char * GetQueryString() const { return _xszQueryString.GetPointer(); }
const WCHAR* GetQueryFileVPath() const { return _xwcsQueryFileVPath.GetPointer(); }
const WCHAR* GetQueryFilePPath() const { return _xwcsQueryFilePPath.GetPointer(); }
void AcceptQueryFilePPath( WCHAR * pwcsPPath, DWORD dwFlags ) { _xwcsQueryFilePPath.Set( pwcsPPath ); _dwQueryFileFlags = dwFlags; }
void AcceptWebHitsFilePPath( WCHAR * pwcsPPath, DWORD dwFlags ) { _xwcsWebHitsFilePPath.Set( pwcsPPath ); _dwWebHitsFileFlags = dwFlags; }
ULONG GetDialect() const { return _dialect; }
const WCHAR* GetWebHitsFileVPath() const { return _xwcsWebHitsFileVPath.GetPointer(); }
const WCHAR* GetWebHitsFilePPath() const { return _xwcsWebHitsFilePPath.GetPointer(); }
const WCHAR* GetTemplateFileVPath() const { return _xwcsTemplateFileVPath.GetPointer(); }
const WCHAR* GetTemplateFilePPath() const { return _xwcsTemplateFilePPath.GetPointer(); }
const WCHAR* GetBeginHiliteTag() const { return _xwcsBeginHiliteTag.GetPointer(); }
const WCHAR* GetEndHiliteTag() const { return _xwcsEndHiliteTag.GetPointer(); }
const WCHAR * GetUserParam( ULONG n ) const { Win4Assert( n > 0 && n <= eMaxUserReplParams ); return _aUserParams[n-1]; }
void AcceptTemplateFilePPath( WCHAR * pwcsPPath, DWORD dwFlags ) { _xwcsTemplateFilePPath.Set( pwcsPPath ); _dwTemplateFileFlags = dwFlags; }
DWORD GetTemplateFileFlags() const { return _dwTemplateFileFlags; } DWORD GetQueryFileFlags() const { return _dwQueryFileFlags; } DWORD GetWebHitsFileFlags() const { return _dwWebHitsFileFlags; }
const WCHAR* GetLocale() const { return _locale.GetPointer(); } const WCHAR* GetCodepage() const { return _codepage.GetPointer(); } HiliteType GetHiliteType() { return _hiliteType; } LCID GetLCID() { return _lcid; } XPtrST<WCHAR>& GetColour() { return _xwc24BitColourMask; } BOOL GetBold() { return _isBold; } BOOL GetItalic() { return _isItalic; } BOOL IsFixedFont() const { return _isFixedFont; } UINT GetFixedFontLineLen() const { return _ccFixedFontLine; }
private:
void RetrieveFilename(); void RetrieveVPath(); void RetrieveQueryString(); int RetrieveCONTENT_LENGTH(); void RetrieveREQUEST_METHOD(); void RetrieveTextStream(ULONG cbContentLength);
//
// method used to parse parameters in QUERY_STRING
//
void ParseQUERY_STRING(); void DetermineCodePage();
void VerifyQSVariablesComplete(); void SetVar(XPtrST<WCHAR>& xwszVarName, XPtrST<WCHAR>& xwszVarValue);
ULONG IsUserParam( WCHAR const * pwcsParam );
//
// method through which the hit-highlighter was invoked
//
REQUEST_METHOD _method;
CLanguageInfo & _langInfo; CWebServer & _webServer;
XArray<WCHAR> _locale; XArray<WCHAR> _codepage; ULONG _dialect;
XPtrST<WCHAR> _xwcsRestriction;
XPtrST<WCHAR> _xwcsWebHitsFileVPath; XPtrST<WCHAR> _xwcsWebHitsFilePPath; DWORD _dwWebHitsFileFlags;
XPtrST<WCHAR> _xwcsQueryFileVPath; XPtrST<WCHAR> _xwcsQueryFilePPath; DWORD _dwQueryFileFlags;
XPtrST<WCHAR> _xwcsTemplateFileVPath; XPtrST<WCHAR> _xwcsTemplateFilePPath; DWORD _dwTemplateFileFlags;
XPtrST<WCHAR> _xwcsBeginHiliteTag; XPtrST<WCHAR> _xwcsEndHiliteTag;
XPtrST<WCHAR> _xwc24BitColourMask;
XArray<char> _xszQueryString;
CDynArray<WCHAR> _aUserParams;
HiliteType _hiliteType; LCID _lcid;
BOOL _isBold; BOOL _isItalic; BOOL _isFixedFont; UINT _ccFixedFontLine;
//
// ref to variable-retrieving object used to actually get the vars
//
CCollectVar& _rCollectVar; CURLUnescaper& _rUnescaper; };
class CWebhitsTemplate;
//+-------------------------------------------------------------------------
//
// Class: PHttpOutput
//
// Purpose: An abstracted interface for outputting text
//
// History: 06-17-1996 t-matts Created
//
//--------------------------------------------------------------------------
class PHttpOutput { public:
PHttpOutput( CWebServer & webServer, CLanguageInfo & langInfo );
~PHttpOutput() { Flush(); }
void Flush();
void Init( CGetEnvVars* rGetEnvVars, CWebhitsTemplate * pTemplate = 0 );
virtual void OutputHttp( const WCHAR* pwcsBuffer, ULONG cLength, BOOL fRawText = FALSE ); void OutputHttpText( WCHAR * pwcsBuffer, ULONG cLength );
virtual void OutputHTMLHeader(); virtual void OutputHilite(const WCHAR* pwszString, ULONG cwcBuffLength);
void OutputHTMLFooter(); void OutputLeftTag(int tagParam); void OutputRightTag(int tagParam); void OutputParaTag() { OutputHttp(ParaTag,wcslen(ParaTag)); } void OutputHRULE() { OutputHttp(HRule,wcslen(HRule)); } void OutputEllipsis(); void OutputErrorHeader();
void OutputErrorMessage( WCHAR * pwcsBuffer, ULONG ccBuffer );
void TagPosition(int tagParam);
BOOL HasPrintedHeader() { return _hasPrintedHeader; }
void OutputPreformattedTag();
BOOL IsTemplateFilePresent() const { return 0 != _pTemplate; }
protected:
void WriteToStdout( WCHAR const * pwszBuffer, ULONG cwc );
void WriteNewline();
void WriteBreakTag();
void OutputPreFormatRawText( WCHAR const * pwszBuffer, ULONG cwc );
enum { MAX_OUTPUT_BUF = 1024 };
static BOOL IsNewLine( WCHAR wc ) { return wc == L'\n'|| wc == L'\r' || wc == UNICODE_PARAGRAPH_SEPARATOR; }
//
// flag to remember whether the header has been printed
//
CWebServer & _webServer; CLanguageInfo & _langInfo;
BOOL _hasPrintedHeader;
// temporary output buffer and a count of the number of characters in it
WCHAR _wcOutputBuffer[MAX_OUTPUT_BUF]; int _cwcOutputBuffer;
// stores the 24 bit colour mask used to tag the hilighting font
XPtrST<WCHAR> _xwc24BitColourMask; BOOL _isItalic; BOOL _isBold;
BOOL _newLine;
BOOL _isInPreformat; // tells if in the pre-formatted mode
unsigned _ccCurrLine; // Number of chars in the current line
unsigned _ccMaxLine; // Maximum # of chars per line
//
// the output object requires knowledge of certain environment variables
//
CGetEnvVars* _pGetEnvVars;
CVirtualString _escapedStr; XArray<BYTE> _mbStr; // Place to store multi-byte string
CVirtualString _vsResult;
CWebhitsTemplate * _pTemplate; // Template file
BOOL _fUseHiliteTags; ULONG _cwcBeginHiliteTag; ULONG _cwcEndHiliteTag; };
//+-------------------------------------------------------------------------
//
// Class: PHttpFullOutput
//
// Purpose: PHttpOutput with an additional method to output header info
// specific to the full hit-highliting
//
// History: 06-17-1996 t-matts Created
//
//--------------------------------------------------------------------------
class PHttpFullOutput:public PHttpOutput { public:
void OutputFullHeader();
PHttpFullOutput( CWebServer & webServer, CLanguageInfo & langInfo ) : PHttpOutput( webServer, langInfo ) {} };
//+-------------------------------------------------------------------------
//
// Class: CExtractedHit
//
// Purpose: Do a summary-like highliting of a single hit. I.e. extract a
// single hit.
//
// History: 06-16-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CExtractedHit { public:
CExtractedHit(CDocument& rDocument, Hit& rHit, PHttpOutput& rOutput, int cwcMargin, int cwcSeparation, int cwcDelim);
void ExtractHit(); void PrintPreamble(const Position& rStartPosition, int cwcDist); void PrintPostamble(const Position& rEndPosition, int cwcDist); void PrintBtwPositions( const Position& rStartPosition, const Position& rEndPosition ); void DisplayPosition(const Position& rPos);
private:
int EatNullPositions();
ULONG ComputeDistance (const Position& rStartPos, const Position& rEndPos);
void SortHit();
CDocument& _rDocument; Hit& _rHit; PHttpOutput& _rOutput;
//
// buffer used for output and a count of the number of characters in it
//
int _cwcOutputBuffer;
// formatting parameters
//
// _cwcMargin - the maximum number of characters that will be printed
// before and after each hit
//
int _cwcMargin;
//
// _cwcDelim - the max number of characters that will follow/precede
// a position if the space between two consecutive positions in the
// same hit is truncated
//
int _cwcDelim;
//
// _cwcSeparation - the max number of characters that may separate
// two consecutive positions in the same hit before truncattion takes
// place
//
int _cwcSeparation; };
//+-------------------------------------------------------------------------
//
// Member: CExtractedHit::EatNullPositions, private inline
//
// Synopsis: Assuming that the positions in _rHit are sorted, returns the
// index of the first non-null position. If all of the positions
// are null positions, or the hit contains 0 positions, returns -1.
//
//--------------------------------------------------------------------------
inline int CExtractedHit::EatNullPositions() { int cPos = _rHit.GetPositionCount();
for (int i=0;i<cPos;i++) { if (!_rHit.GetPos(i).IsNullPosition()) return i; } return -1; }
//+-------------------------------------------------------------------------
//
// Class: CExtractHits
//
// Purpose: Functor to iterate over the hits in a document and output a
// summary for each one
//
// History: 06-16-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CExtractHits { public: CExtractHits ( CDocument& rDocument, HitIter& rHitIter, PHttpOutput&, int cwcMargin = 150, int cwcSeparation = 80, int cwcDelim = 40 ); };
//+-------------------------------------------------------------------------
//
// Class: CSortQueryHits
//
// Purpose: Sort the positions returned as part of the hits in a document
// object in the order in which they will appear in the document
//
// History: 05-20-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CSortQueryHits { public:
CSortQueryHits(HitIter& rHitIter) :_rHitIter(rHitIter),_aPosition(0),_positionCount(0) { }
~CSortQueryHits() { delete[] _aPosition;} void Init(); Position& GetPosition(int i) {return _aPosition[i];} int GetPositionCount() {return _positionCount;}
private:
HitIter& _rHitIter; Position* _aPosition; int _positionCount; //total # of distinct positions
int CountPositions(); };
//+-------------------------------------------------------------------------
//
// Class: CLinkQueryHits
//
// Purpose: Insert the HTML tags necessary to enable next/prev navigation
// through hits
//
// History: 05-16-1996 t-matts Created
//
//--------------------------------------------------------------------------
class CLinkQueryHits { public:
enum{BUFFER_SIZE = 4096,BOGUS_RANK = 1000};
CLinkQueryHits( CInternalQuery& rCInternalQuery, CGetEnvVars& rGetEnvVars, PHttpFullOutput& rHttpOutput, DWORD cmsReadTimeout, CReleasableLock & lockSingleThreadedFilter, CEmptyPropertyList & propertyList, ULONG ulDisplayScript );
void InsertLinks();
private:
BOOL MoveToNextDifferentPosition();
BOOL AtBeginningOfPosition(); BOOL LastTag(); BOOL IsSeparatedBySpaces(int startOffset, int endOffset);
void OutputBuffer() { _rHttpOutput.OutputHttp(_wcOutputBuffer, _ccOutputBuffer ); }
CGetEnvVars& _rGetEnvVars; CInternalQuery& _rInternalQuery; PHttpFullOutput& _rHttpOutput; CDocument _document; HitIter _HitIter; CSortQueryHits _sortedHits;
//
// buffer used to store document pieces retrieved from CDocument
//
WCHAR _Buffer[BUFFER_SIZE];
//
// buffer used for output & a count of characters in it
//
WCHAR _wcOutputBuffer[BUFFER_SIZE]; int _ccOutputBuffer;
//
// information regarding the current position in the document
//
int _currentOffset; // current offset in buffer
int _posIndex; // index of current position
int _tagCount; // # of tag
//
// the total number of positions (not necessarily distinct)
//
int _posCount;
//
// data members to store the offset of the next position
//
int _nextBegOffset; int _nextEndOffset; };
//+-------------------------------------------------------------------------
//
// Member: CLinkQueryHits::AtBeginningOfPosition
//
// Synopsis: returns true if we are positioned at the beginning of a
// position
//
//--------------------------------------------------------------------------
inline BOOL CLinkQueryHits::AtBeginningOfPosition() { return (_currentOffset == _nextBegOffset); }
//+-------------------------------------------------------------------------
//
// Member: CLinkQueryHits::LastTag()
//
// Synopsis: returns true if the tag to be output is the last one in the
// document and FALSE if not
//
//--------------------------------------------------------------------------
inline BOOL CLinkQueryHits::LastTag() { return ((_tagCount == _posCount-1) || (_posIndex == _posCount-1)); }
//+-------------------------------------------------------------------------
//
// Member: CLinkQueryHits::MoveToNextDifferentPosition()
//
// Synopsis: goes through the array of sorted positions until it finds the
// the next one
//
//--------------------------------------------------------------------------
inline BOOL CLinkQueryHits::MoveToNextDifferentPosition() {
for(;_posIndex <_posCount;_posIndex++) { Position nextPos = _sortedHits.GetPosition(_posIndex);
_nextBegOffset = nextPos.GetBegOffset(); _nextEndOffset = nextPos.GetEndOffset();
if (_nextEndOffset > _currentOffset) break; } if (_posIndex == _posCount) return FALSE;
return TRUE; }
//+---------------------------------------------------------------------------
//
// Class: CWebhitsTemplate
//
// Purpose: A class that encapsulates a template file for webhits.
//
// History: 9-07-96 srikants Created
//
//----------------------------------------------------------------------------
class CWebhitsTemplate { public:
CWebhitsTemplate( CGetEnvVars const & envVars, ULONG codePage );
CWTXFile & GetWTXFile() { return _wtxFile; } CWHVarSet & GetVariableSet() { return _variableSet; }
BOOL DoesHeaderExist() const { return _wtxFile.DoesHeaderExist(); } BOOL DoesFooterExist() const { return _wtxFile.DoesFooterExist(); }
private:
CWHVarSet _variableSet; CWTXFile _wtxFile; };
|