Microsoft-3D-Movie-Maker/kauai/SRC/CHUNK.H

330 lines
9.0 KiB
C++

/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/***************************************************************************
Author: ShonK
Project: Kauai
Reviewed:
Copyright (c) Microsoft Corporation
Chunky file classes. See comments in chunk.cpp.
***************************************************************************/
#ifndef CHUNK_H
#define CHUNK_H
/***************************************************************************
These must be unsigned longs! We sort on them and assume in the code
that they are unsinged.
***************************************************************************/
typedef ulong CTG; // chunk tag/type
typedef ulong CNO; // chunk number
typedef ulong CHID; // child chunk id
enum
{
fcflNil = 0x0000,
fcflWriteEnable = 0x0001,
fcflTemp = 0x0002,
fcflMark = 0x0004,
fcflAddToExtra = 0x0008,
// This flag indicates that when data is read, it should first be
// copied to the extra file (if it's not already there). This is
// for chunky files that are on a CD for which we want to cache data
// to the hard drive.
fcflReadFromExtra = 0x0010,
#ifdef DEBUG
// for AssertValid
fcflGraph = 0x4000, // check the graph structure for cycles
fcflFull = fobjAssertFull,
#endif //DEBUG
};
// chunk identification
struct CKI
{
CTG ctg;
CNO cno;
};
const BOM kbomCki = 0xF0000000;
// child chunk identification
struct KID
{
CKI cki;
CHID chid;
};
const BOM kbomKid = 0xFC000000;
/***************************************************************************
Chunky file class.
***************************************************************************/
typedef class CFL *PCFL;
#define CFL_PAR BLL
#define kclsCFL 'CFL'
class CFL : public CFL_PAR
{
RTCLASS_DEC
BLL_DEC(CFL, PcflNext)
ASSERT
MARKMEM
private:
// chunk storage
struct CSTO
{
PFIL pfil; // the file
FP fpMac; // logical end of file (for writing new chunks)
PGL pglfsm; // free space map
};
PGG _pggcrp; //the index
CSTO _csto; //the main file
CSTO _cstoExtra; //the scratch file
bool _fAddToExtra: 1;
bool _fMark: 1;
bool _fFreeMapNotRead: 1;
bool _fReadFromExtra: 1;
bool _fInvalidMainFile: 1;
// for deferred reading of the free map
FP _fpFreeMap;
long _cbFreeMap;
#ifndef CHUNK_BIG_INDEX
struct RTIE
{
CTG ctg;
CNO cno;
long rti;
};
PGL _pglrtie;
bool _FFindRtie(CTG ctg, CNO cno, RTIE *prtie = pvNil,
long *pirtie = pvNil);
#endif //!CHUNK_BIG_INDEX
// static member variables
static long _rtiLast;
static PCFL _pcflFirst;
private:
// private methods
CFL(void);
~CFL(void);
static ulong CFL::_GrffilFromGrfcfl(ulong grfcfl);
bool _FReadIndex(void);
bool _TValidIndex(void);
bool _FWriteIndex(CTG ctgCreator);
bool _FCreateExtra(void);
bool _FAllocFlo(long cb, PFLO pflo, bool fForceOnExtra = fFalse);
bool _FFindCtgCno(CTG ctg, CNO cno, long *picrp);
void _GetUniqueCno(CTG ctg, long *picrp, CNO *pcno);
void _FreeFpCb(bool fOnExtra, FP fp, long cb);
bool _FAdd(long cb, CTG ctg, CNO cno, long icrp, PBLCK pblck);
bool _FPut(long cb, CTG ctg, CNO cno, PBLCK pblck, PBLCK pblckSrc,
void *pv);
bool _FCopy(CTG ctgSrc, CNO cnoSrc, PCFL pcflDst, CNO *pcnoDst,
bool fClone);
bool _FFindMatch(CTG ctgSrc, CNO cnoSrc, PCFL pcflDst, CNO *pcnoDst);
bool _FFindCtgRti(CTG ctg, long rti, CNO cnoMin, CNO *pcnoDst);
bool _FDecRefCount(long icrp);
void _DeleteCore(long icrp);
bool _FFindChild(long icrpPar, CTG ctgChild, CNO cnoChild, CHID chid,
long *pikid);
bool _FAdoptChild(long icrpPar, long ikid, CTG ctgChild, CNO cnoChild,
CHID chid, bool fClearLoner);
void _ReadFreeMap(void);
bool _FFindChidCtg(CTG ctgPar, CNO cnoPar, CHID chid, CTG ctg, KID *pkid);
bool _FSetName(long icrp, PSTN pstn);
bool _FGetName(long icrp, PSTN pstn);
void _GetFlo(long icrp, PFLO pflo);
void _GetBlck(long icrp, PBLCK pblck);
bool _FEnsureOnExtra(long icrp, FLO *pflo = pvNil);
long _Rti(CTG ctg, CNO cno);
bool _FSetRti(CTG ctg, CNO cno, long rti);
public:
// static methods
static PCFL PcflFirst(void)
{ return _pcflFirst; }
static PCFL PcflOpen(FNI *pfni, ulong grfcfl);
static PCFL PcflCreate(FNI *pfni, ulong grfcfl);
static PCFL PcflCreateTemp(FNI *pfni = pvNil);
static PCFL PcflFromFni(FNI *pfni);
static void ClearMarks(void);
static void CloseUnmarked(void);
#ifdef CHUNK_STATS
static void DumpStn(PSTN pstn, PFIL pfil = pvNil);
#endif //CHUNK_STATS
virtual void Release(void);
bool FSetGrfcfl(ulong grfcfl, ulong grfcflMask = (ulong)~0);
void Mark(void) { _fMark = fTrue; }
void SetTemp(bool f) { _csto.pfil->SetTemp(f); }
bool FTemp(void) { return _csto.pfil->FTemp(); }
void GetFni(FNI *pfni) { _csto.pfil->GetFni(pfni); }
bool FSetFni(FNI *pfni) { return _csto.pfil->FSetFni(pfni); }
long ElError(void);
void ResetEl(long el = elNil);
bool FReopen(void);
// finding and reading chunks
bool FOnExtra(CTG ctg, CNO cno);
bool FEnsureOnExtra(CTG ctg, CNO cno);
bool FFind(CTG ctg, CNO cno, BLCK *pblck = pvNil);
bool FFindFlo(CTG ctg, CNO cno, PFLO pflo);
bool FReadHq(CTG ctg, CNO cno, HQ *phq);
void SetPacked(CTG ctg, CNO cno, bool fPacked);
bool FPacked(CTG ctg, CNO cno);
bool FUnpackData(CTG ctg, CNO cno);
bool FPackData(CTG ctg, CNO cno);
// creating and replacing chunks
bool FAdd(long cb, CTG ctg, CNO *pcno, PBLCK pblck = pvNil);
bool FAddPv(void *pv, long cb, CTG ctg, CNO *pcno);
bool FAddHq(HQ hq, CTG ctg, CNO *pcno);
bool FAddBlck(PBLCK pblckSrc, CTG ctg, CNO *pcno);
bool FPut(long cb, CTG ctg, CNO cno, PBLCK pblck = pvNil);
bool FPutPv(void *pv, long cb, CTG ctg, CNO cno);
bool FPutHq(HQ hq, CTG ctg, CNO cno);
bool FPutBlck(PBLCK pblck, CTG ctg, CNO cno);
bool FCopy(CTG ctgSrc, CNO cnoSrc, PCFL pcflDst, CNO *pcnoDst);
bool FClone(CTG ctgSrc, CNO cnoSrc, PCFL pcflDst, CNO *pcnoDst);
void SwapData(CTG ctg1, CNO cno1, CTG ctg2, CNO cno2);
void SwapChildren(CTG ctg1, CNO cno1, CTG ctg2, CNO cno2);
void Move(CTG ctg, CNO cno, CTG ctgNew, CNO cnoNew);
//creating child chunks
bool FAddChild(CTG ctgPar, CNO cnoPar, CHID chid,
long cb, CTG ctg, CNO *pcno, PBLCK pblck = pvNil);
bool FAddChildPv(CTG ctgPar, CNO cnoPar, CHID chid,
void *pv, long cb, CTG ctg, CNO *pcno);
bool FAddChildHq(CTG ctgPar, CNO cnoPar, CHID chid,
HQ hq, CTG ctg, CNO *pcno);
// deleting chunks
void Delete(CTG ctg, CNO cno);
void SetLoner(CTG ctg, CNO cno, bool fLoner);
bool FLoner(CTG ctg, CNO cno);
// chunk naming
bool FSetName(CTG ctg, CNO cno, PSTN pstn);
bool FGetName(CTG ctg, CNO cno, PSTN pstn);
// graph structure
bool FAdoptChild(CTG ctgPar, CNO cnoPar,
CTG ctgChild, CNO cnoChild, CHID chid = 0, bool fClearLoner = fTrue);
void DeleteChild(CTG ctgPar, CNO cnoPar,
CTG ctgChild, CNO cnoChild, CHID chid = 0);
long CckiRef(CTG ctg, CNO cno);
bool TIsDescendent(CTG ctg, CNO cno, CTG ctgSub, CNO cnoSub);
void ChangeChid(CTG ctgPar, CNO cnoPar, CTG ctgChild, CNO cnoChild,
CHID chidOld, CHID chidNew);
// enumerating chunks
long Ccki(void);
bool FGetCki(long icki, CKI *pcki, long *pckid = pvNil, PBLCK pblck = pvNil);
bool FGetIcki(CTG ctg, CNO cno, long *picki);
long CckiCtg(CTG ctg);
bool FGetCkiCtg(CTG ctg, long icki, CKI *pcki, long *pckid = pvNil,
PBLCK pblck = pvNil);
// enumerating child chunks
long Ckid(CTG ctgPar, CNO cnoPar);
bool FGetKid(CTG ctgPar, CNO cnoPar, long ikid, KID *pkid);
bool FGetKidChid(CTG ctgPar, CNO cnoPar, CHID chid, KID *pkid);
bool FGetKidChidCtg(CTG ctgPar, CNO cnoPar, CHID chid, CTG ctg, KID *pkid);
bool FGetIkid(CTG ctgPar, CNO cnoPar, CTG ctg, CNO cno, CHID chid, long *pikid);
// Serialized chunk forests
bool FWriteChunkTree(CTG ctg, CNO cno, PFIL pfilDst, FP fpDst, long *pcb);
static PCFL PcflReadForestFromFlo(PFLO pflo, bool fCopyData);
bool FForest(CTG ctg, CNO cno);
void SetForest(CTG ctg, CNO cno, bool fForest = fTrue);
PCFL PcflReadForest(CTG ctg, CNO cno, bool fCopyData);
// writing
bool FSave(CTG ctgCreator, FNI *pfni = pvNil);
bool FSaveACopy(CTG ctgCreator, FNI *pfni);
};
/***************************************************************************
Chunk graph enumerator
***************************************************************************/
enum
{
// inputs
fcgeNil = 0x0000,
fcgeSkipToSib = 0x0001,
// outputs
fcgePre = 0x0010,
fcgePost = 0x0020,
fcgeRoot = 0x0040,
fcgeError = 0x0080
};
#define CGE_PAR BASE
#define kclsCGE 'CGE'
class CGE : public CGE_PAR
{
RTCLASS_DEC
ASSERT
MARKMEM
NOCOPY(CGE)
private:
//data enumeration push state
struct DPS
{
KID kid;
long ikid;
};
// enumeration states
enum
{
esStart, //waiting to start the enumeration
esGo, //go to the next node
esGoNoSkip, //there are no children to skip, so ignore fcgeSkipToSib
esDone //we're done with the enumeration
};
long _es; //current state
PCFL _pcfl; //the chunky file
PGL _pgldps; //our stack of DPSs
DPS _dps; //the current DPS
public:
CGE(void);
~CGE(void);
void Init(PCFL pcfl, CTG ctg, CNO cno);
bool FNextKid(KID *pkid, CKI *pckiPar, ulong *pgrfcgeOut, ulong grfcgeIn);
};
#ifdef CHUNK_STATS
extern bool vfDumpChunkRequests;
#endif //CHUNK_STATS
#endif //!CHUNK_H