/* Web Polygraph http://www.web-polygraph.org/ * (C) 2003-2006 The Measurement Factory * Licensed under the Apache License, Version 2.0 */ #include "base/polygraph.h" #include "xstd/ZLib.h" #include "base/RndPermut.h" #include "runtime/LogComment.h" #include "runtime/IOBuf.h" #include "csm/ContentDbase.h" #include "csm/ContentCfg.h" #include "csm/InjectIter.h" #include "csm/cdbEntries.h" #include "csm/GzipEncoder.h" #include "xstd/gadgets.h" GzipEncoder::GzipEncoder(int aLevel, BodyIter *aProducer): theLevel(aLevel), theProducer(aProducer), theEncoder(0) { theOid = theProducer->oid(); theContentCfg = theProducer->contentCfg(); theContentHash = theProducer->contentHash(); theContentSize = Size(); // unknown } GzipEncoder::~GzipEncoder() { delete theEncoder; } void GzipEncoder::reset() { Assert(!theProducer); BodyIter::reset(); theLevel = -1; theProducerBuf.reset(); if (theEncoder) theEncoder->reset(); } void GzipEncoder::start(WrBuf *aBuf) { BodyIter::start(aBuf); Assert(theLevel >= 0); Assert(theProducer); theProducer->start(&theProducerBuf); if (theEncoder) theEncoder->init(theLevel); else theEncoder = new Deflator(theLevel); } void GzipEncoder::stop() { if (theProducer) { theContentCfg->putBodyIter(theProducer); // assumes same theContentCfg theProducer = 0; } } void GzipEncoder::abandonProducer() { theProducer = 0; } bool GzipEncoder::pourBody() { while ((theProducer->canPour() || !theProducerBuf.empty()) && this->canPour()) { if (theProducer->canPour()) theProducer->pour(); if (Should(!theProducerBuf.empty())) { theEncoder->data(theProducerBuf.content(), theProducerBuf.contSize()); theEncoder->space(theBuf->space(), theBuf->spaceSize()); // compress Size dataDelta, spaceDelta; const bool finish = theProducer->pouredAll(); if (theEncoder->deflate(spaceDelta, dataDelta, finish)) { theProducerBuf.consumed(dataDelta); theBuf->appended(spaceDelta); theBuiltSize += spaceDelta; if (!theContentSize.known() && finish && theProducerBuf.empty()) theContentSize = theBuiltSize; } else { Comment << "error: a called to zlib::deflate failed: " << theEncoder->error() << endc; return false; } } } return true; }