311 lines
6.0 KiB
C++
311 lines
6.0 KiB
C++
/*
|
|
* @doc INTERNAL
|
|
*
|
|
* @module RTFLOG.CPP - RichEdit RTF log
|
|
*
|
|
* Contains the code for the RTFLog class which can be used
|
|
* to log the number of times RTF tags are read by the RTF reader
|
|
* for use in coverage testing
|
|
*
|
|
* Authors:<nl>
|
|
* Created for RichEdit 2.0: Brad Olenick
|
|
*
|
|
* Copyright (c) 1995-1996, Microsoft Corporation. All rights reserved.
|
|
*/
|
|
|
|
#include "_common.h"
|
|
#include "_rtflog.h"
|
|
#include "tokens.h"
|
|
|
|
extern INT cKeywords;
|
|
extern const KEYWORD rgKeyword[];
|
|
|
|
/*
|
|
* CRTFLog::CRTFLog()
|
|
*
|
|
* @mfunc
|
|
* Constructor -
|
|
* 1. Opens a file mapping to log hit counts, creating
|
|
* the backing file if neccessary
|
|
* 2. Map a view of the file mapping into memory
|
|
* 3. Register a windows message for change notifications
|
|
*
|
|
*/
|
|
CRTFLog::CRTFLog() : _rgdwHits(NULL), _hfm(NULL), _hfile(NULL)
|
|
{
|
|
#ifndef PEGASUS
|
|
const char cstrMappingName[] = "RTFLOG";
|
|
const char cstrWM[] = "RTFLOGWM";
|
|
const int cbMappingSize = sizeof(ELEMENT) * ISize();
|
|
|
|
BOOL fNewFile = FALSE;
|
|
|
|
// check for existing file mapping
|
|
if(!(_hfm = OpenFileMappingA(FILE_MAP_ALL_ACCESS,
|
|
TRUE,
|
|
cstrMappingName)))
|
|
{
|
|
// no existing file mapping
|
|
|
|
// get the file with which to create the file mapping
|
|
|
|
// first, attempt to open an existing file
|
|
if(!(_hfile = CreateFileA(LpcstrLogFilename(),
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL)))
|
|
{
|
|
// no existing file, attempt to create new
|
|
if(!(_hfile = CreateFileA(LpcstrLogFilename(),
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
fNewFile = TRUE;
|
|
}
|
|
|
|
if(!(_hfm = CreateFileMappingA(_hfile,
|
|
NULL,
|
|
PAGE_READWRITE,
|
|
0,
|
|
cbMappingSize,
|
|
cstrMappingName)))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
LPVOID lpv;
|
|
if(!(lpv = MapViewOfFile(_hfm,
|
|
FILE_MAP_ALL_ACCESS,
|
|
0,
|
|
0,
|
|
cbMappingSize)))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// register windows message for change notifications
|
|
SideAssert(_uMsg = RegisterWindowMessageA(cstrWM));
|
|
|
|
// memory-mapped file is now mapped to _rgdwHits
|
|
_rgdwHits = (PELEMENT)lpv;
|
|
|
|
// zero the memory-mapped file if we created it new
|
|
// (Win95 gives us a new file w/ garbage in it for some reason)
|
|
if(fNewFile)
|
|
{
|
|
Reset();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
* CRTFLog::Reset()
|
|
*
|
|
* @mfunc
|
|
* Resets the hitcount of each element in the log to 0
|
|
*
|
|
*/
|
|
void CRTFLog::Reset()
|
|
{
|
|
if(!FInit())
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(INDEX i = 0; i < ISize(); i++)
|
|
{
|
|
(*this)[i] = 0;
|
|
}
|
|
|
|
// notify clients of change
|
|
ChangeNotifyAll();
|
|
}
|
|
|
|
|
|
/*
|
|
* CRTFLog::UGetWindowMsg
|
|
*
|
|
* @mdesc
|
|
* Returns the window message id used for change notifications
|
|
*
|
|
* @rdesc
|
|
* UINT window message id
|
|
*
|
|
* @devnote
|
|
* This should be inline, but the AssertSz macro doesn't compile
|
|
* properly on the Mac if its placed in a header file
|
|
*
|
|
*/
|
|
UINT CRTFLog::UGetWindowMsg() const
|
|
{
|
|
AssertSz(FInit(), "CRTFLog::UGetWindowMsg(): CRTFLog not initialized properly");
|
|
|
|
return _uMsg;
|
|
}
|
|
|
|
|
|
/*
|
|
* CRTFLog::operator[]
|
|
*
|
|
* @mdesc
|
|
* Returns reference to element i of RTF log (l-value)
|
|
*
|
|
* @rdesc
|
|
* ELEMENT & reference to element i of log
|
|
*
|
|
* @devnote
|
|
* This should be inline, but the AssertSz macro doesn't compile
|
|
* properly on the Mac if its placed in a header file
|
|
*
|
|
*/
|
|
CRTFLog::ELEMENT &CRTFLog::operator[](INDEX i)
|
|
{
|
|
AssertSz(i < ISize(), "CRTFLog::operator[]: index out of range");
|
|
AssertSz(FInit(), "CRTFLog::operator[]: CRTFLog not initialized properly");
|
|
|
|
return _rgdwHits[i];
|
|
}
|
|
|
|
|
|
/*
|
|
* CRTFLog::operator[]
|
|
*
|
|
* @mdesc
|
|
* Returns reference to element i of RTF log (r-value)
|
|
*
|
|
* @rdesc
|
|
* const ELEMENT & reference to element i of log
|
|
*
|
|
* @devnote
|
|
* This should be inline, but the AssertSz macro doesn't compile
|
|
* properly on the Mac if its placed in a header file
|
|
*
|
|
*/
|
|
const CRTFLog::ELEMENT &CRTFLog::operator[](INDEX i) const
|
|
{
|
|
AssertSz(i < ISize(), "CRTFLog::operator[]: index out of range");
|
|
AssertSz(FInit(), "CRTFLog::operator[]: CRTFLog not initialized properly");
|
|
|
|
return _rgdwHits[i];
|
|
}
|
|
|
|
|
|
/*
|
|
* CRTFLog::LpcstrLogFilename()
|
|
*
|
|
* @mfunc
|
|
* Returns name of file to be used for log
|
|
*
|
|
* @rdesc
|
|
* LPCSTR pointer to static buffer containing file name
|
|
*/
|
|
LPCSTR CRTFLog::LpcstrLogFilename() const
|
|
{
|
|
const char cstrLogFilename[] = "RTFLOG";
|
|
static char szBuf[MAX_PATH] = "";
|
|
#ifndef PEGASUS
|
|
if(!szBuf[0])
|
|
{
|
|
DWORD cchLength;
|
|
char szBuf2[MAX_PATH];
|
|
|
|
SideAssert(cchLength = GetTempPathA(MAX_PATH, szBuf2));
|
|
|
|
// append trailing backslash if neccessary
|
|
if(szBuf2[cchLength - 1] != '\\')
|
|
{
|
|
szBuf2[cchLength] = '\\';
|
|
szBuf2[cchLength + 1] = 0;
|
|
}
|
|
|
|
wsprintfA(szBuf, "%s%s", szBuf2, cstrLogFilename);
|
|
}
|
|
#endif
|
|
return szBuf;
|
|
}
|
|
|
|
|
|
/*
|
|
* CRTFLog::IIndexOfKeyword(LPCSTR lpcstrKeyword, PINDEX piIndex)
|
|
*
|
|
* @mfunc
|
|
* Returns the index of the log element which corresponds to
|
|
* the RTF keyword, lpcstrKeyword
|
|
*
|
|
* @rdesc
|
|
* BOOL flag indicating whether index was found
|
|
*/
|
|
BOOL CRTFLog::IIndexOfKeyword(LPCSTR lpcstrKeyword, PINDEX piIndex) const
|
|
{
|
|
INDEX i;
|
|
|
|
for(i = 0; i < ISize(); i++)
|
|
{
|
|
if(strcmp(lpcstrKeyword, rgKeyword[i].szKeyword) == 0)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(i == ISize())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(piIndex)
|
|
{
|
|
*piIndex = i;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*
|
|
* CRTFLog::IIndexOfToken(TOKEN token, PINDEX piIndex)
|
|
*
|
|
* @mfunc
|
|
* Returns the index of the log element which corresponds to
|
|
* the RTF token, token
|
|
*
|
|
* @rdesc
|
|
* BOOL flag indicating whether index was found
|
|
*/
|
|
BOOL CRTFLog::IIndexOfToken(TOKEN token, PINDEX piIndex) const
|
|
{
|
|
INDEX i;
|
|
|
|
for(i = 0; i < ISize(); i++)
|
|
{
|
|
if(token == rgKeyword[i].token)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(i == ISize())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(piIndex)
|
|
{
|
|
*piIndex = i;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|