/* Copyright (c) Microsoft Corporation. Licensed under the MIT License. */ /*************************************************************************** Author: ****** Project: Kauai Reviewed: Copyright (c) Microsoft Corporation Chunky source emitter class implementation. ***************************************************************************/ #include "util.h" ASSERTNAME RTCLASS(CHSE) /*************************************************************************** Constructor for a chunky source emitter. ***************************************************************************/ CHSE::CHSE(void) { AssertBaseThis(0); _pmsnkError = pvNil; _pmsnkDump = pvNil; AssertThis(0); } /*************************************************************************** Destructor for a chunky source emitter. ***************************************************************************/ CHSE::~CHSE(void) { Uninit(); } /*************************************************************************** Initialize the chunky source emitter. ***************************************************************************/ void CHSE::Init(PMSNK pmsnkDump, PMSNK pmsnkError) { AssertThis(0); AssertPo(pmsnkDump, 0); AssertNilOrPo(pmsnkError, 0); Uninit(); _pmsnkDump = pmsnkDump; _pmsnkDump->AddRef(); _pmsnkError = pmsnkError; if (_pmsnkError != pvNil) _pmsnkError->AddRef(); AssertThis(fchseDump); } /*************************************************************************** Clean up and return the chse to an inactive state. ***************************************************************************/ void CHSE::Uninit(void) { AssertThis(0); ReleasePpo(&_pmsnkDump); ReleasePpo(&_pmsnkError); if (_bsf.IbMac() > 0) _bsf.FReplace(pvNil, 0, 0, _bsf.IbMac()); } #ifdef DEBUG /*************************************************************************** Assert the validity of a CHSE. ***************************************************************************/ void CHSE::AssertValid(ulong grfchse) { CHSE_PAR::AssertValid(0); AssertPo(&_bsf, 0); if (grfchse & fchseDump) AssertPo(_pmsnkDump, 0); AssertNilOrPo(_pmsnkError, 0); } /*************************************************************************** Mark memory for the CHSE. ***************************************************************************/ void CHSE::MarkMem(void) { AssertValid(0); CHSE_PAR::MarkMem(); MarkMemObj(_pmsnkError); MarkMemObj(_pmsnkDump); MarkMemObj(&_bsf); } #endif //DEBUG /*************************************************************************** Dumps chunk header. ***************************************************************************/ void CHSE::DumpHeader(CTG ctg, CNO cno, PSTN pstnName, bool fPack) { AssertThis(fchseDump); AssertNilOrPo(pstnName, 0); STN stnT; if (pstnName != pvNil) { STN stnName; stnName = *pstnName; stnName.FExpandControls(); stnT.FFormatSz(PszLit("CHUNK('%f', %d, \"%s\")"), ctg, cno, &stnName); } else stnT.FFormatSz(PszLit("CHUNK('%f', %d)"), ctg, cno); DumpSz(stnT.Psz()); if (fPack) DumpSz(PszLit("\tPACK")); } /*************************************************************************** Dump a raw data chunk ***************************************************************************/ void CHSE::DumpBlck(PBLCK pblck) { AssertThis(fchseDump); AssertPo(pblck, 0); FLO flo; if (pblck->FPacked()) DumpSz(PszLit("PREPACKED")); if (!pblck->FGetFlo(&flo, fTrue)) { Error(PszLit("Dumping chunk failed")); return; } _bsf.FReplaceFlo(&flo, fFalse, 0, _bsf.IbMac()); ReleasePpo(&flo.pfil); _DumpBsf(1); } /*************************************************************************** Dump raw data from memory. ***************************************************************************/ void CHSE::DumpRgb(void *prgb, long cb, long cactTab) { AssertThis(fchseDump); AssertIn(cb, 0, kcbMax); AssertPvCb(prgb, cb); if (cb > 0) { _bsf.FReplace(prgb, cb, 0, _bsf.IbMac()); _DumpBsf(cactTab); } } /*************************************************************************** Dump a parent directive ***************************************************************************/ void CHSE::DumpParentCmd(CTG ctgPar, CNO cnoPar, CHID chid) { AssertThis(fchseDump); STN stn; stn.FFormatSz(PszLit("PARENT('%f', %d, %d)"), ctgPar, cnoPar, chid); DumpSz(stn.Psz()); } /*************************************************************************** Dump a bitmap directive ***************************************************************************/ void CHSE::DumpBitmapCmd(byte bTransparent, long dxp, long dyp, PSTN pstnFile) { AssertThis(fchseDump); AssertPo(pstnFile, 0); STN stn; stn.FFormatSz(PszLit("BITMAP(%d, %d, %d) \"%s\""), (long)bTransparent, dxp, dyp, pstnFile); DumpSz(stn.Psz()); } /*************************************************************************** Dump a file directive ***************************************************************************/ void CHSE::DumpFileCmd(PSTN pstnFile, bool fPacked) { AssertThis(fchseDump); AssertPo(pstnFile, 0); STN stn; if (fPacked) stn.FFormatSz(PszLit("PACKEDFILE \"%s\""), pstnFile); else stn.FFormatSz(PszLit("FILE \"%s\""), pstnFile); DumpSz(stn.Psz()); } /*************************************************************************** Dump an adopt directive ***************************************************************************/ void CHSE::DumpAdoptCmd(CKI *pcki, KID *pkid) { AssertThis(fchseDump); AssertVarMem(pcki); AssertVarMem(pkid); STN stn; stn.FFormatSz(PszLit("ADOPT('%f', %d, '%f', %d, %d)"), pcki->ctg, pcki->cno, pkid->cki.ctg, pkid->cki.cno, pkid->chid); DumpSz(stn.Psz()); } /*************************************************************************** Dump the data in the _bsf ***************************************************************************/ void CHSE::_DumpBsf(long cactTab) { AssertThis(fchseDump); AssertIn(cactTab, 0, kcchMaxStn + 1); byte rgb[8], bT; STN stn1; STN stn2; long cact; long ib, ibMac; long cb, ibT; stn1.SetNil(); for (cact = cactTab; cact-- > 0; ) stn1.FAppendCh(kchTab); stn1.FAppendSz(PszLit("BYTE")); DumpSz(stn1.Psz()); ibMac = _bsf.IbMac(); for (ib = 0; ib < ibMac; ) { stn1.SetNil(); for (cact = cactTab; cact-- > 0; ) stn1.FAppendCh(kchTab); cb = LwMin(ibMac - ib, size(rgb)); _bsf.FetchRgb(ib, cb, rgb); //append the hex for (ibT = 0; ibT < size(rgb); ibT++) { if (ibT >= cb) stn1.FAppendSz(PszLit(" ")); else { stn2.FFormatSz(PszLit("0x%02x "), rgb[ibT]); stn1.FAppendStn(&stn2); } } stn1.FAppendSz(PszLit(" // '")); //append the ascii for (ibT = 0; ibT < cb; ibT++) { bT = rgb[ibT]; if (bT < 0x20 || bT == 0x7F) bT = '?'; stn1.FAppendCh((achar)bT); } stn1.FAppendSz(PszLit("' ")); DumpSz(stn1.Psz()); ib += cb; } } /****************************************************************************** Disassembles a script (pscpt) using the given script compiler (psccb) and dumps the result (including a "SCRIPTPF" directive). ******************************************************************************/ bool CHSE::FDumpScript(PSCPT pscpt, PSCCB psccb) { AssertThis(fchseDump); AssertPo(pscpt, 0); AssertPo(psccb, 0); DumpSz(PszLit("SCRIPTPF")); if (!psccb->FDisassemble(pscpt, _pmsnkDump, _pmsnkError)) { Error(PszLit("Dumping script failed")); return fFalse; } return fTrue; } /****************************************************************************** Dumps a GL or AL, including the GL or AL directive. pglb is the GL or AL to dump. ******************************************************************************/ void CHSE::DumpList(PGLB pglb) { AssertThis(fchseDump); AssertPo(pglb, 0); long cbEntry; long iv, ivMac; STN stn; bool fAl = pglb->FIs(kclsAL); Assert(fAl || pglb->FIs(kclsGL), "neither a GL or AL!"); // have a valid GL or AL -- print it out in readable format cbEntry = pglb->CbEntry(); AssertIn(cbEntry, 0, kcbMax); ivMac = pglb->IvMac(); stn.FFormatSz(fAl ? PszLit("\tAL(%d)") : PszLit("\tGL(%d)"), cbEntry); DumpSz(stn.Psz()); // print out the entries for (iv = 0; iv < ivMac; iv++) { if (pglb->FFree(iv)) DumpSz(PszLit("\tFREE")); else { DumpSz(PszLit("\tITEM")); _bsf.FReplace(pglb->PvLock(iv), cbEntry, 0, _bsf.IbMac()); pglb->Unlock(); _DumpBsf(2); } } } /****************************************************************************** Dumps a GG or AG, including the GG or AG directive. pggb is the GG or AG to dump. ******************************************************************************/ void CHSE::DumpGroup(PGGB pggb) { AssertThis(fchseDump); AssertPo(pggb, 0); long cbFixed, cb; long iv, ivMac; STN stnT; bool fAg = pggb->FIs(kclsAG); Assert(fAg || pggb->FIs(kclsGG), "neither a GG or AG!"); // have a valid GG or AG -- print it out in readable format cbFixed = pggb->CbFixed(); AssertIn(cbFixed, 0, kcbMax); ivMac = pggb->IvMac(); stnT.FFormatSz(fAg ? PszLit("\tAG(%d)") : PszLit("\tGG(%d)"), cbFixed); DumpSz(stnT.Psz()); // print out the entries for (iv = 0; iv < ivMac; iv++) { if (pggb->FFree(iv)) { DumpSz(PszLit("\tFREE")); continue; } DumpSz(PszLit("\tITEM")); if (cbFixed > 0) { _bsf.FReplace(pggb->PvFixedLock(iv), cbFixed, 0, _bsf.IbMac()); pggb->Unlock(); _DumpBsf(2); } if (0 < (cb = pggb->Cb(iv))) { DumpSz(PszLit("\tVAR")); _bsf.FReplace(pggb->PvLock(iv), cb, 0, _bsf.IbMac()); pggb->Unlock(); _DumpBsf(2); } } } /****************************************************************************** Dumps a GST or AST, including the GST or AST directive. pggb is the GST or AST to dump. ******************************************************************************/ bool CHSE::FDumpStringTable(PGSTB pgstb) { AssertThis(fchseDump); AssertPo(pgstb, 0); long cbExtra; long iv, ivMac; STN stn1; STN stn2; void *pvExtra = pvNil; bool fAst = pgstb->FIs(kclsAST); Assert(fAst || pgstb->FIs(kclsGST), "neither a GST or AST!"); // have a valid GST or AST -- print it out in readable format cbExtra = pgstb->CbExtra(); AssertIn(cbExtra, 0, kcbMax); ivMac = pgstb->IvMac(); if (cbExtra > 0 && !FAllocPv(&pvExtra, cbExtra, fmemNil, mprNormal)) return fFalse; stn1.FFormatSz(fAst ? PszLit("\tAST(%d)") : PszLit("\tGST(%d)"), cbExtra); DumpSz(stn1.Psz()); // print out the entries for (iv = 0; iv < ivMac; iv++) { if (pgstb->FFree(iv)) { DumpSz(PszLit("\tFREE")); continue; } DumpSz(PszLit("\tITEM")); pgstb->GetStn(iv, &stn2); stn2.FExpandControls(); stn1.FFormatSz(PszLit("\t\t\"%s\""), &stn2); DumpSz(stn1.Psz()); if (cbExtra > 0) { pgstb->GetExtra(iv, pvExtra); _bsf.FReplace(pvExtra, cbExtra, 0, _bsf.IbMac()); _DumpBsf(2); } } FreePpv(&pvExtra); return fTrue; }