mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
268 lines
5.7 KiB
268 lines
5.7 KiB
/*****************************************************************************
|
|
* *
|
|
* FMT.C *
|
|
* *
|
|
* Copyright (C) Microsoft Corporation 1990. *
|
|
* All Rights reserved. *
|
|
* *
|
|
******************************************************************************
|
|
* *
|
|
* Module Intent *
|
|
* FM caching module. Used in history and back lists. *
|
|
* *
|
|
* Currently, I don't keep a ref count of the FMs in the cache. This *
|
|
* means I can't shrink the cache until all users finish using it. *
|
|
* *
|
|
*****************************************************************************/
|
|
|
|
#include "help.h"
|
|
|
|
#pragma hdrstop
|
|
|
|
_subsystem( FMT );
|
|
|
|
/*****************************************************************************
|
|
* *
|
|
* Defines *
|
|
* *
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* *
|
|
* Typedefs *
|
|
* *
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* *
|
|
* Static Variables *
|
|
* *
|
|
*****************************************************************************/
|
|
|
|
/****************************************************************************\
|
|
*
|
|
* The following static variables define the cache. There is only one
|
|
* cache because the whole idea is to share it.
|
|
*
|
|
\****************************************************************************/
|
|
static INT16 cfm = 0; // count of FDs
|
|
static GH hrgfm = NULL; // handle to array of FDs
|
|
static FM * rgfm = NULL; // locked hrgfd (sometimes valid)
|
|
static INT16 cRefFmt = 0; // FDT ref count
|
|
|
|
/*****************************************************************************
|
|
* *
|
|
* Prototypes *
|
|
* *
|
|
*****************************************************************************/
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcInitFmt()
|
|
-
|
|
* Purpose: Enlist as a user of the FMT.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* globals IN: cRefFmt
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: rcSuccess always
|
|
*
|
|
* globals OUT: ref count cRefFmt is incremented
|
|
*
|
|
* Note: If you RcInitFmt(), you must RcFiniFmt() when you're done.
|
|
*
|
|
* +++
|
|
*
|
|
* Method: Increment the ref count.
|
|
*
|
|
\***************************************************************************/
|
|
void STDCALL RcInitFmt()
|
|
{
|
|
++cRefFmt;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: RcFiniFmt()
|
|
-
|
|
* Purpose: Tell the FMT you're done using it. When the last user
|
|
* finishes, memory is deallocated.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: rcSuccess rcFailure
|
|
*
|
|
\***************************************************************************/
|
|
void STDCALL RcFiniFmt(void)
|
|
{
|
|
INT16 ifm;
|
|
FM * qfmT;
|
|
|
|
ASSERT( 0 < cRefFmt );
|
|
|
|
if (0 == --cRefFmt) {
|
|
if (!hrgfm) {
|
|
if (rgfm == NULL)
|
|
rgfm = PtrFromGh(hrgfm);
|
|
|
|
for (ifm = 0, qfmT = rgfm; ifm < cfm; ++ifm, ++qfmT)
|
|
DisposeFm(*qfmT);
|
|
|
|
rgfm = NULL;
|
|
FreeGh(hrgfm);
|
|
hrgfm = NULL;
|
|
}
|
|
cfm = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
*
|
|
- Function: UnlockFmt()
|
|
-
|
|
* Purpose: Ensure that the FMT is unlocked.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* globals IN:
|
|
*
|
|
* PROMISES
|
|
*
|
|
* globals OUT:
|
|
*
|
|
* Notes: You should do this after performing the mapping functions
|
|
* before yielding.
|
|
*
|
|
* +++
|
|
*
|
|
* Method:
|
|
*
|
|
* Notes:
|
|
*
|
|
\***************************************************************************/
|
|
_public void STDCALL
|
|
UnlockFmt()
|
|
{
|
|
if (rgfm) {
|
|
ASSERT(NULL != hrgfm);
|
|
rgfm = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
-
|
|
- Function: IfmFromFm( fm )
|
|
-
|
|
* Purpose: Map an ifm into an fm
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: fm - map it to an ifm
|
|
*
|
|
* globals IN: rgfm
|
|
* hrgfm
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: success - valid ifm
|
|
* failure - ifmNil
|
|
*
|
|
* globals OUT: hrgfm - array of saved FMs can grow
|
|
* rgfm - guaranteed to be hrgfm, locked
|
|
* cfm - can be incremented
|
|
*
|
|
* state OUT: FMT is locked
|
|
*
|
|
\***************************************************************************/
|
|
_public INT16 STDCALL
|
|
IfmFromFm( fm )
|
|
FM fm;
|
|
|
|
{
|
|
INT16 ifm;
|
|
FM fmT;
|
|
FM * qfmT;
|
|
GH ghT;
|
|
|
|
if (!rgfm) {
|
|
if (!hrgfm) {
|
|
if (!(hrgfm = GhAlloc(GPTR, sizeof(FM))))
|
|
return ifmNil;
|
|
cfm = 1;
|
|
rgfm = PtrFromGh( hrgfm );
|
|
ASSERT(NULL != rgfm);
|
|
ifm = 0;
|
|
fmT = FmCopyFm(fm);
|
|
rgfm[ ifm ] = fmT;
|
|
return ifm;
|
|
}
|
|
rgfm = PtrFromGh(hrgfm);
|
|
ASSERT(NULL != rgfm);
|
|
}
|
|
|
|
for (ifm = 0, qfmT = rgfm; ifm < cfm; ++ifm, ++qfmT) {
|
|
if (FSameFmFm(fm, *qfmT)) {
|
|
return ifm;
|
|
}
|
|
}
|
|
|
|
ghT = GhResize(hrgfm, 0, sizeof(FM) * ++cfm);
|
|
if ( NULL == ghT )
|
|
{
|
|
--cfm;
|
|
return ifmNil;
|
|
}
|
|
hrgfm = ghT;
|
|
|
|
rgfm = PtrFromGh( hrgfm );
|
|
fmT = FmCopyFm(fm);
|
|
rgfm[ ifm ] = fmT;
|
|
|
|
return ifm;
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
-
|
|
- Function: FmFromIfm( ifm )
|
|
-
|
|
* Purpose: Map an ifm into an fm.
|
|
*
|
|
* ASSUMES
|
|
*
|
|
* args IN: ifm - in range: 0 <= ifm < cfm
|
|
*
|
|
* globals IN:
|
|
*
|
|
* PROMISES
|
|
*
|
|
* returns: success: fm - a copy of the fm in the table (so it can be
|
|
* disposed without causing problems.
|
|
* failure: NULL
|
|
*
|
|
* state OUT: FMT is locked
|
|
*
|
|
\***************************************************************************/
|
|
|
|
FM STDCALL FmFromIfm(INT16 ifm)
|
|
{
|
|
if ( 0 > ifm || ifm >= cfm )
|
|
return NULL;
|
|
|
|
if (NULL == rgfm) {
|
|
ASSERT(NULL != hrgfm);
|
|
rgfm = PtrFromGh(hrgfm);
|
|
ASSERT(NULL != rgfm);
|
|
}
|
|
|
|
return rgfm[ ifm ];
|
|
}
|
|
|
|
/* EOF */
|