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.
461 lines
7.8 KiB
461 lines
7.8 KiB
//-----------------------------------------------------------------------------
|
|
// FileInfo.h
|
|
//
|
|
// Copyright (C) 1993, Microsoft Corporation
|
|
//
|
|
// Purpose:
|
|
// Define the FILEINFO and CLASSDEP stuff regarding all info from the
|
|
// file system and other data for the /mr/file* streams
|
|
//
|
|
// Revision History:
|
|
//
|
|
// [] 13-Jan-1995 Dans Created
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
#if !defined(_fileinfo_h)
|
|
#define _fileinfo_h 1
|
|
|
|
#include "CBitVect.h"
|
|
#include "ClasInfo.h"
|
|
|
|
typedef CBitVect<cbitsName> BITVECT;
|
|
|
|
//
|
|
// The fileinfo stream
|
|
//
|
|
struct FI : public FILEINFO {
|
|
|
|
FI (
|
|
NI ni =niNil,
|
|
DWORD dw =0,
|
|
BldId _bldid =0,
|
|
NI niOpt =niNil,
|
|
NI niRel =niNil,
|
|
QWORD qwft =0,
|
|
QWORD qwfs =0
|
|
) {
|
|
niFile = ni;
|
|
dwStatus = dw;
|
|
fiTime.qwft = qwft;
|
|
fiSize = qwfs;
|
|
bldid = _bldid;
|
|
niOptions = niOpt;
|
|
niRelated = niRel;
|
|
dwReserved = 0;
|
|
}
|
|
|
|
void
|
|
SetFstatus ( DWORD fsm ) {
|
|
dwStatus |= fsm;
|
|
}
|
|
|
|
void
|
|
ClearFstatus ( DWORD fsm ) {
|
|
dwStatus &= ~fsm;
|
|
}
|
|
|
|
void
|
|
ClearFstatus() {
|
|
dwStatus = 0;
|
|
}
|
|
|
|
void
|
|
ClearFstatusOutOfDate() {
|
|
ClearFstatus ( fsmOutOfDate );
|
|
}
|
|
|
|
BOOL
|
|
FTargOutOfDate() {
|
|
return (dwStatus & (fsmOutOfDate | fsmHasTarget)) == (fsmOutOfDate | fsmHasTarget);
|
|
}
|
|
|
|
BOOL
|
|
FIsOutOfDate() {
|
|
return !!(dwStatus & fsmOutOfDate);
|
|
}
|
|
|
|
BOOL
|
|
FHasTarget() {
|
|
return !!(dwStatus & fsmHasTarget);
|
|
}
|
|
|
|
BOOL
|
|
FIsTarget() {
|
|
return !!(dwStatus & fsmIsTarget);
|
|
}
|
|
|
|
BOOL
|
|
FIsFsmSet ( FSM fsm ) {
|
|
return !!(dwStatus & fsm);
|
|
}
|
|
|
|
void
|
|
SetBuildId ( BldId _bldid ) {
|
|
bldid = _bldid;
|
|
}
|
|
|
|
BldId
|
|
BuildId() const {
|
|
return bldid;
|
|
}
|
|
|
|
NI
|
|
Ni() const {
|
|
return niFile;
|
|
}
|
|
|
|
NI
|
|
NiOptions() const {
|
|
return niOptions;
|
|
}
|
|
|
|
NI
|
|
NiRelated() const {
|
|
assert ( dwStatus & (fsmHasTarget | fsmIsTarget) );
|
|
return niRelated;
|
|
}
|
|
|
|
void
|
|
SetNiRelated ( NI niRel ) {
|
|
niRelated = niRel;
|
|
}
|
|
|
|
void
|
|
SetNiOptions ( NI niOpt ) {
|
|
assert ( FHasTarget() );
|
|
niOptions = niOpt;
|
|
}
|
|
};
|
|
|
|
typedef FI * PFI;
|
|
|
|
//
|
|
// per-file info kept in one stream.
|
|
//
|
|
struct MRFI { // per-file info kept in "/mr/files/{itoa(ni, 16, buf)}"
|
|
STRMHDR strmhdr;
|
|
NI niFile; // which file this pertains to
|
|
NI niTarg; // if there is a direct target
|
|
OFF offClassdeps; // offset from base of struct to classes
|
|
OFF offFiledeps; // offset from base of struct to filedeps
|
|
OFF offBoringClasses; // offset from base to boring class list
|
|
DWORD dwReserved;
|
|
};
|
|
|
|
struct CLASSDEP {
|
|
NI ni; // name of class
|
|
STI ti; // type index
|
|
DWORD depon; // how the container depends on class
|
|
BITVECT bvNames; // depends on "name" in this class scope
|
|
CLASSDEP(NI _ni =niNil, TI _ti =tiNil, DWORD _depon =0) :
|
|
ni(_ni), ti(_ti), depon(_depon) {}
|
|
|
|
TI
|
|
Ti() const {
|
|
return TI(ti);
|
|
}
|
|
|
|
NI
|
|
Ni() const {
|
|
return ni;
|
|
}
|
|
|
|
BOOL
|
|
FAnyBitsSet() const {
|
|
return depon || int(bvNames);
|
|
}
|
|
|
|
BOOL
|
|
FAnyBitsInCommon ( const CLASSDEP & cd ) const {
|
|
if ( ni == cd.ni ) {
|
|
return (depon & cd.depon) || bvNames.FAnyBitsInCommon ( cd.bvNames );
|
|
}
|
|
else {
|
|
return fFalse;
|
|
}
|
|
}
|
|
|
|
void
|
|
SetAllDeps() {
|
|
depon = deponAll;
|
|
bvNames.SetAll ( fTrue );
|
|
}
|
|
|
|
CLASSDEP &
|
|
operator &= ( const CLASSDEP & cd ) {
|
|
assert ( ni == cd.ni );
|
|
if ( ni == cd.ni ) {
|
|
depon &= cd.ni;
|
|
bvNames &= cd.bvNames;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
CLASSDEP &
|
|
operator |= ( const CLASSDEP & cd ) {
|
|
assert ( ni == cd.ni );
|
|
if ( ni == cd.ni ) {
|
|
depon |= cd.ni;
|
|
bvNames |= cd.bvNames;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
int
|
|
operator == ( const CLASSDEP & cd ) const {
|
|
return memcmp ( this, &cd, sizeof CLASSDEP ) == 0;
|
|
}
|
|
};
|
|
|
|
|
|
struct TagClsDep : public CLASSDEP {
|
|
BldId bldid;
|
|
TagClsDep ( BldId _bldid =0, NI _ni =niNil, TI _ti =tiNil, DWORD _depon =0) :
|
|
CLASSDEP(_ni, _ti, _depon ),
|
|
bldid(_bldid)
|
|
{
|
|
}
|
|
BldId
|
|
BuildId() const {
|
|
return bldid;
|
|
}
|
|
|
|
int
|
|
operator == ( const TagClsDep & tcd ) const {
|
|
return memcmp ( this, &tcd, sizeof(*this) ) == 0;
|
|
}
|
|
};
|
|
|
|
|
|
#define cbExtra 12
|
|
|
|
typedef SetVer<NI,HcNi,cbExtra> SetofNi;
|
|
typedef MapVer<NI,CLASSDEP,HcNi,cbExtra> MapNiClassdep;
|
|
typedef EnumSet<NI,HcNi> EnumSetNi;
|
|
typedef EnumMap<NI,CLASSDEP,HcNi> EnumMapNiClassdep;
|
|
|
|
class MRFIBuf {
|
|
enum {
|
|
verFile = -1,
|
|
verClassdep = -1,
|
|
verBoringClass = -1,
|
|
};
|
|
|
|
Buffer m_buf;
|
|
MRFI m_mrfi;
|
|
PMRE m_pmre;
|
|
|
|
SetofNi m_setniFile;
|
|
SetofNi m_setniBoringClass;
|
|
MapNiClassdep m_mpniclassdep;
|
|
|
|
void
|
|
SetOffsets () {
|
|
m_mrfi.offFiledeps = sizeof MRFI;
|
|
m_mrfi.offClassdeps = m_mrfi.offFiledeps + m_setniFile.cbSave();
|
|
m_mrfi.offBoringClasses = m_mrfi.offClassdeps + m_mpniclassdep.cbSave();
|
|
m_mrfi.strmhdr.cb = m_mrfi.offBoringClasses + m_setniBoringClass.cbSave();
|
|
}
|
|
|
|
BOOL
|
|
FInitFromPb ( PB );
|
|
|
|
BOOL
|
|
FStoreIntoBuf ( Buffer & );
|
|
|
|
BOOL
|
|
FTiIsClass ( TI ti );
|
|
|
|
BOOL
|
|
FNotFwdRef ( TI ti );
|
|
|
|
public:
|
|
MRFIBuf() :
|
|
m_setniFile(verFile),
|
|
m_setniBoringClass(verBoringClass),
|
|
m_mpniclassdep(verClassdep)
|
|
{
|
|
m_pmre = NULL;
|
|
memset ( &m_mrfi, 0, sizeof MRFI );
|
|
}
|
|
|
|
~MRFIBuf() {
|
|
}
|
|
|
|
void
|
|
SetPmre ( PMRE pmre ) {
|
|
precondition ( pmre );
|
|
m_pmre = pmre;
|
|
}
|
|
|
|
MRFI *
|
|
Pmrfi() {
|
|
return &m_mrfi;
|
|
}
|
|
|
|
BOOL
|
|
FInitEmpty();
|
|
|
|
BOOL
|
|
FInitFromStream ( Stream * );
|
|
|
|
BOOL
|
|
FInitFromDepData ( PDepData );
|
|
|
|
BOOL
|
|
FStoreIntoDepData ( PDepData );
|
|
|
|
CB
|
|
CbDepData() {
|
|
return
|
|
sizeof MRFI +
|
|
m_setniFile.cbSave() +
|
|
m_mpniclassdep.cbSave() +
|
|
m_setniBoringClass.cbSave();
|
|
}
|
|
|
|
void
|
|
SetNiFile ( NI niFile, NI niTarg = niNil ) {
|
|
assert ( niFile != niNil );
|
|
m_mrfi.niFile = niFile;
|
|
m_mrfi.niTarg = niTarg;
|
|
}
|
|
|
|
BOOL
|
|
FAddFileDep ( NI niFile ) {
|
|
assert ( niFile != niNil );
|
|
return niFile == m_mrfi.niFile || m_setniFile.add ( niFile );
|
|
}
|
|
|
|
BOOL
|
|
FAddClassDep (
|
|
NI niClass,
|
|
TI tiClass,
|
|
SZC szMemberName,
|
|
DEPON deponHow,
|
|
DWORD dwLine =0
|
|
);
|
|
|
|
// use FAppend... to write to an empty stream (has grow semantics)
|
|
BOOL
|
|
FAppendToStream ( Stream * );
|
|
|
|
// use FReplace... to replace the existing stream (no growth!)
|
|
BOOL
|
|
FReplaceStream ( Stream * );
|
|
|
|
BOOL
|
|
FDependsOnFile ( NI niSrc, NI niDep ) {
|
|
assert ( m_mrfi.niFile == niSrc );
|
|
return m_setniFile.contains ( niDep );
|
|
}
|
|
|
|
BOOL
|
|
FUsesClass ( NI niSrc, NI niClass, const CLASSDEP ** ppcd ) {
|
|
// return whether this file uses the said class. returns a ptr to
|
|
// a CLASSDEP record if it is not a boring class, in which case
|
|
// it will return fTrue with *pcd == NULL
|
|
assert ( m_mrfi.niFile == niSrc );
|
|
assert ( ppcd != NULL );
|
|
|
|
*ppcd = NULL;
|
|
return m_mpniclassdep.map ( niClass, (CLASSDEP **)ppcd );
|
|
}
|
|
|
|
SetofNi &
|
|
SetofNiFile() {
|
|
return m_setniFile;
|
|
}
|
|
|
|
SetofNi &
|
|
SetofNiBoringClass() {
|
|
return m_setniBoringClass;
|
|
}
|
|
|
|
MapNiClassdep &
|
|
MapNiClassdep() {
|
|
return m_mpniclassdep;
|
|
}
|
|
|
|
DWORD
|
|
CClassesUsed() const {
|
|
return m_mpniclassdep.count();
|
|
}
|
|
|
|
DWORD
|
|
CBoringClassesUsed() const {
|
|
return m_setniBoringClass.count();
|
|
}
|
|
|
|
DWORD
|
|
CDepFiles() const {
|
|
return m_setniFile.count();
|
|
}
|
|
BOOL
|
|
FmergeClassDeps ( const MRFIBuf & );
|
|
|
|
};
|
|
|
|
inline size_t
|
|
CbFileInfoBuffer ( DWORD cEntries ) {
|
|
return sizeof(STRMHDR) + sizeof(FI) * cEntries;
|
|
}
|
|
|
|
//
|
|
// operators for comparing filetimes and sizes
|
|
//
|
|
/*
|
|
inline
|
|
operator== ( const FI & fi1, const FI & fi2 ) {
|
|
return
|
|
fi1.fiTime.qwft == fi2.fiTime.qwft &&
|
|
fi1.fiSize == fi2.fiSize
|
|
;
|
|
}
|
|
|
|
inline
|
|
operator!= ( const FI & fi1, const FI & fi2 ) {
|
|
return !(fi1 == fi2);
|
|
}
|
|
*/
|
|
inline
|
|
operator== ( const FILEINFO & fi1, const FILEINFO & fi2 ) {
|
|
return
|
|
fi1.fiTime.qwft == fi2.fiTime.qwft &&
|
|
fi1.fiSize == fi2.fiSize
|
|
;
|
|
}
|
|
|
|
inline
|
|
operator!= ( const FILEINFO & fi1, const FILEINFO & fi2 ) {
|
|
return !(fi1 == fi2);
|
|
}
|
|
|
|
inline
|
|
operator< ( MREFT ft1, MREFT ft2 ) {
|
|
return ft1.qwft < ft2.qwft;
|
|
}
|
|
|
|
inline
|
|
operator== ( MREFT ft1, MREFT ft2 ) {
|
|
return ft1.qwft == ft2.qwft;
|
|
}
|
|
|
|
inline
|
|
operator!= ( MREFT ft1, MREFT ft2 ) {
|
|
return !(ft1 == ft2);
|
|
}
|
|
|
|
inline
|
|
operator== ( MREFT ft1, unsigned ft2 ) {
|
|
return ft1.qwft == ft2;
|
|
}
|
|
|
|
inline
|
|
operator!= ( MREFT ft1, unsigned ft2 ) {
|
|
return !(ft1 == ft2);
|
|
}
|
|
|
|
|
|
|
|
#endif
|