in cpp-ch/local-engine/IO/SplittableBzip2ReadBuffer.cpp [623:790]
void SplittableBzip2ReadBuffer::getAndMoveToFrontDecode()
{
origPtr = static_cast<Int32>(bsR(24));
recvDecodingTables();
ReadBuffer * inShadow = in.get();
Data * dataShadow = data.get();
auto & ll8 = dataShadow->ll8;
Int32 * unzftab = dataShadow->unzftab;
char * selector = dataShadow->selector;
auto * seqToUnseq = dataShadow->seqToUnseq;
auto * yy = dataShadow->getAndMoveToFrontDecode_yy;
Int32 * minLens = dataShadow->minLens;
auto * limit = dataShadow->limit;
auto * base = dataShadow->base;
auto * perm = dataShadow->perm;
Int32 limitLast = blockSize100k * 100000;
for (Int32 i = 256; --i >= 0;)
{
yy[i] = i;
unzftab[i] = 0;
}
Int32 groupNo = 0;
Int32 groupPos = BZip2Constants::G_SIZE - 1;
Int32 eob = nInUse + 1;
Int32 nextSym = getAndMoveToFrontDecode0(0);
Int32 bsBuffShadow = static_cast<Int32>(bsBuff);
Int32 bsLiveShadow = static_cast<Int32>(bsLive);
Int32 lastShadow = -1;
Int32 zt = selector[groupNo] & 0xff;
Int32 * base_zt = base[zt];
Int32 * limit_zt = limit[zt];
Int32 * perm_zt = perm[zt];
Int32 minLens_zt = minLens[zt];
while (nextSym != eob)
{
if ((nextSym == BZip2Constants::RUNA) || (nextSym == BZip2Constants::RUNB))
{
Int32 s = -1;
for (Int32 n = 1; true; n <<= 1)
{
if (nextSym == BZip2Constants::RUNA)
s += n;
else if (nextSym == BZip2Constants::RUNB)
s += n << 1;
else
break;
if (groupPos == 0)
{
groupPos = BZip2Constants::G_SIZE - 1;
zt = selector[++groupNo] & 0xff;
base_zt = base[zt];
limit_zt = limit[zt];
perm_zt = perm[zt];
minLens_zt = minLens[zt];
}
else
{
groupPos--;
}
Int32 zn = minLens_zt;
while (bsLiveShadow < zn)
{
Int32 thech = readAByte(*inShadow);
if (thech < 0)
DB::throwReadAfterEOF();
bsBuffShadow = (bsBuffShadow << 8) | thech;
bsLiveShadow += 8;
}
Int64 zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1);
bsLiveShadow -= zn;
while (zvec > limit_zt[zn])
{
zn++;
while (bsLiveShadow < 1)
{
Int32 thech = readAByte(*inShadow);
if (thech < 0)
DB::throwReadAfterEOF();
bsBuffShadow = (bsBuffShadow << 8) | thech;
bsLiveShadow += 8;
}
bsLiveShadow--;
zvec = (zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1);
}
nextSym = perm_zt[static_cast<Int32>(zvec - base_zt[zn])];
}
char ch = seqToUnseq[yy[0]];
unzftab[ch & 0xff] += s + 1;
while (s-- >= 0)
ll8[++lastShadow] = ch;
if (lastShadow >= limitLast)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Block overrun");
}
else
{
if (++lastShadow >= limitLast)
throw Exception(ErrorCodes::LOGICAL_ERROR, "Block overrun");
auto tmp = yy[nextSym - 1];
unzftab[seqToUnseq[tmp] & 0xff]++;
ll8[lastShadow] = seqToUnseq[tmp];
if (nextSym <= 16)
for (Int32 j = nextSym - 1; j > 0; --j)
yy[j] = yy[j - 1];
else
memmove(&yy[1], &yy[0], (nextSym - 1) * sizeof(yy[0]));
yy[0] = tmp;
if (groupPos == 0)
{
groupPos = BZip2Constants::G_SIZE - 1;
zt = selector[++groupNo] & 0xff;
base_zt = base[zt];
limit_zt = limit[zt];
perm_zt = perm[zt];
minLens_zt = minLens[zt];
}
else
{
groupPos--;
}
Int32 zn = minLens_zt;
while (bsLiveShadow < zn)
{
Int32 thech = readAByte(*inShadow);
if (thech < 0)
DB::throwReadAfterEOF();
bsBuffShadow = (bsBuffShadow << 8) | thech;
bsLiveShadow += 8;
}
Int32 zvec = (bsBuffShadow >> (bsLiveShadow - zn)) & ((1 << zn) - 1);
bsLiveShadow -= zn;
while (zvec > limit_zt[zn])
{
zn++;
while (bsLiveShadow < 1)
{
Int32 thech = readAByte(*inShadow);
if (thech < 0)
DB::throwReadAfterEOF();
bsBuffShadow = (bsBuffShadow << 8) | thech;
bsLiveShadow += 8;
}
bsLiveShadow--;
zvec = ((zvec << 1) | ((bsBuffShadow >> bsLiveShadow) & 1));
}
nextSym = perm_zt[zvec - base_zt[zn]];
}
}
last = lastShadow;
bsLive = bsLiveShadow;
bsBuff = bsBuffShadow;
}