Linter Demo Errors: 0Warnings: 7File: /home/fstrocco/Dart/dart/benchmark/bzip2/lib/src/compressor.dart part of bzip2; class _Bzip2Compressor implements _Bzip2Coder { int _blockSizeFactor; /* input state */ List _input = new List(_MAX_BYTES_REQUIRED); int _inputSize = 0; bool _noMoreData = false; /* file state */ bool _isFirstBlock = true; bool _isDone = false; _Bzip2CombinedCrc _fileCrc = new _Bzip2CombinedCrc(); /* block compression information */ List _compressedBlock; int _blockCrc; int _originPointer; List _inUse; List _inUse16; List> _huffmanTables; List _selectors; /* output state */ _BitBuffer _outputBuffer = new _BitBuffer(_MAX_BYTES_REQUIRED); _Bzip2Compressor(this._blockSizeFactor) { if (this._blockSizeFactor < 1 || this._blockSizeFactor > 9) { throw new ArgumentError("invalid block size factor"); } } void writeByte(int byte) { _input[_inputSize] = byte; _inputSize++; } bool canProcess() { return !_isDone && (_noMoreData || _inputSize >= _blockSizeFactor * _BLOCK_SIZE_STEP); } void process() { if (_isFirstBlock) { _writeHeader(); _isFirstBlock = false; } if (_inputSize != 0) { List block = _readBlock(); _blockCrc = _calculateBlockCrc(block); _fileCrc.update(_blockCrc); _compressBlock(block); _writeCompressedBlock(); } if (_noMoreData && _inputSize == 0) { _writeFooter(); _isDone = true; } } List readOutput() { List output = new List(_MAX_BYTES_REQUIRED); int outputSize = 0; while (_outputBuffer.usedBitCount() >= 8) { output[outputSize++] = _outputBuffer.readByte(); } int remainingBits = _outputBuffer.usedBitCount(); if (_isDone && remainingBits > 0) { int padding = 8 - remainingBits; output[outputSize++] = _outputBuffer.readBits(remainingBits) << padding; } output = output.sublist(0, outputSize); return output; } void setEndOfData() { _noMoreData = true; } void _compressBlock(List block) { List blockRleEncoded = _rleEncode1(block); _BWTEncoder bwtEncoder = new _BWTEncoder(); _BWTResult bwtResult = bwtEncoder.encode(blockRleEncoded); List blockBwtEncoded = bwtResult.lastColumn; _originPointer = bwtResult.originPointer; _inUse = _calculateInUse(bwtResult.lastColumn); _inUse16 = _calculateInUse16(_inUse); List symbols = _calculateSymbols(_inUse); int alphaSize = _getAlphaSize(_inUse); List blockMtfEncoded = _mtfEncode(blockBwtEncoded, symbols); List blockRleEncoded2 = _rleEncode2(blockMtfEncoded, alphaSize); _huffmanTables = _calculateHuffmanTables(blockRleEncoded2, alphaSize); _selectors = _calculateSelectors(blockRleEncoded2, _huffmanTables); _compressedBlock = blockRleEncoded2; } void _writeCompressedBlock() { _outputBuffer.writeBits(_BLOCK_SIGNATURE_HIGH, 24); _outputBuffer.writeBits(_BLOCK_SIGNATURE_LOW, 24); _outputBuffer.writeBits(_blockCrc, 32); _outputBuffer.writeBit(0); /* not randomized */ /* write inUse information */ _outputBuffer.writeBits(_originPointer, _ORIGIN_BIT_COUNT); for (int i = 0; i < 16; i++) { _outputBuffer.writeBit(_inUse16[i] ? 1 : 0); } for (int i = 0; i < 256; i++) { if (_inUse16[i >> 4]) { _outputBuffer.writeBit(_inUse[i] ? 1 : 0); } } _outputBuffer.writeBits(_huffmanTables.length, _TABLE_COUNT_BITS); _outputBuffer.writeBits(_selectors.length, _SELECTOR_COUNT_BITS); /* write table selectors */ List selectorsSymbols = new List.generate(_TABLE_COUNT_MAX, (x)=>x); List selectorsEncoded = _mtfEncode(_selectors, selectorsSymbols); for (int selectorCode in selectorsEncoded) { for (int i = 0; i < selectorCode; i++) { _outputBuffer.writeBit(1); } _outputBuffer.writeBit(0); } /* write huffman tables */ for (List<_HuffmanCode> huffmanTable in _huffmanTables) { int currentLevel = huffmanTable[0].len; _outputBuffer.writeBits(currentLevel, _LEVEL_BITS); for (_HuffmanCode huffmanCode in huffmanTable) { while (currentLevel < huffmanCode.len) { _outputBuffer.writeBits(2, 2); currentLevel++; } while (currentLevel > huffmanCode.len) { _outputBuffer.writeBits(3, 2); currentLevel--; } _outputBuffer.writeBit(0); } } /* write symbols */ for (int group = 0, bufferIndex = 0; group < _selectors.length; group++) { int table = _selectors[group]; int groupSize = min(_GROUP_SIZE, _compressedBlock.length - bufferIndex); for (int groupIndex = 0; groupIndex < groupSize; groupIndex++) { int symbol = _compressedBlock[bufferIndex++]; _HuffmanCode huffmanCode = _huffmanTables[table][symbol]; _outputBuffer.writeBits(huffmanCode.code, huffmanCode.len); } } } void _writeFooter() { _outputBuffer.writeBits(_FINISH_SIGNATURE_HIGH, 24); _outputBuffer.writeBits(_FINISH_SIGNATURE_LOW, 24); _outputBuffer.writeBits(_fileCrc.getDigest(), 32); } void _writeHeader() { _outputBuffer.writeBits(_BZIP_SIGNATURE, 24); _outputBuffer.writeByte('0'.codeUnitAt(0) + _blockSizeFactor); } List _readBlock() { int blockSizeLimit = (_blockSizeFactor * _BLOCK_SIZE_STEP * 4) ~/ 5; int blockSize = min(_inputSize, blockSizeLimit); List result = _input.sublist(0, blockSize); for (int i = 0; i < _inputSize - blockSize; i++) { _input[i] = _input[blockSize + i]; } _inputSize -= blockSize; return result; } List _rleEncode1(List block) { List result = new List(_MAX_BYTES_REQUIRED); int resultIndex = 0; int blockIndex = 0; while (blockIndex < block.length) { int runLength = 0; int currentByte = block[blockIndex]; int maxRunLength = min(block.length - blockIndex, _RLE_MODE_REP_SIZE + 255); while (runLength < maxRunLength && block[blockIndex] == currentByte) { runLength++; blockIndex++; } for (int i = 0; i < min(runLength, _RLE_MODE_REP_SIZE); i++) { result[resultIndex++] = currentByte; } if (runLength >= _RLE_MODE_REP_SIZE) { result[resultIndex++] = runLength - _RLE_MODE_REP_SIZE; } } result = result.sublist(0, resultIndex); return result; } List _calculateInUse(List _buffer) { List inUse = new List.filled(256, false); for (int value in _buffer) { inUse[value] = true; } return inUse; } List _calculateInUse16(List inUse) { List inUse16 = new List.filled(16, false); for (int i = 0; i < 256; i++) { if (inUse[i]) { inUse16[i >> 4] = true; } } return inUse16; } int _getAlphaSize(List inUse) { int alphaSize = inUse.where((v) => v).length + 2; return alphaSize; } List _calculateSymbols(List inUse) { List symbols = new List(256); int symbolIndex = 0; for (int i = 0; i < 256; i++) { if (inUse[i]) { symbols[symbolIndex++] = i; } } symbols = symbols.sublist(0, symbolIndex); return symbols; } List _mtfEncode(List buffer, List symbols) { List result = new List(buffer.length); List mtf = new List.from(symbols); for (int index = 0; index < buffer.length; index++) { int symbolIndex = mtf.indexOf(buffer[index]); for (int index = symbolIndex; index > 0; index--) { mtf[index] = mtf[index - 1]; } mtf[0] = buffer[index]; result[index] = symbolIndex; } return result; } List _rleEncode2(List buffer, int alphaSize) { List result = new List(_MAX_BLOCK_SIZE + 2); int resultIndex = 0; int bufferIndex = 0; while (bufferIndex < buffer.length) { int runLength = 0; while (bufferIndex < buffer.length && buffer[bufferIndex] == 0) { runLength++; bufferIndex++; } if (runLength != 0) { while (runLength != 0) { runLength--; result[resultIndex++] = (runLength & 1); runLength >>= 1; } } else { int value = buffer[bufferIndex++] + 1; result[resultIndex++] = value; } } result[resultIndex++] = alphaSize - 1; result = result.sublist(0, resultIndex); return result; } List _calculateHuffmanTables(List block, int alphaSize) { /* initialize */ List> huffmanTables = _initialHuffmanTables(block, alphaSize); int tableCount = huffmanTables.length; for (int pass = 0; pass < _HUFFMAN_PASSES; pass++) { List> frequencyTables = new List>.generate(tableCount, (_) => new List.filled(alphaSize, 0)); List selectors = _calculateSelectors(block, huffmanTables); /* update frequency table */ for (int group = 0; group < selectors.length; group++) { int groupStart = _getGroupStart(group); int groupEnd = _getGroupEnd(group, block.length); int table = selectors[group]; for (int i = groupStart; i < groupEnd; i++) { int symbol = block[i]; frequencyTables[table][symbol]++; } } /* generate new tables */ for (int table = 0; table < tableCount; table++) { _HuffmanEncoder encoder = new _HuffmanEncoder(_MAX_HUFFMAN_LEN_FOR_ENCODING); huffmanTables[table] = encoder.generate(frequencyTables[table]); } } return huffmanTables; } List _calculateSelectors(List block, List> huffmanTables) { int selectorCount = (block.length + _GROUP_SIZE - 1) ~/ _GROUP_SIZE; List selectors = new List(selectorCount); for (int group = 0; group < selectorCount; group++) { int groupStart = _getGroupStart(group); int groupEnd = _getGroupEnd(group, block.length); selectors[group] = _selectHuffmanTable(block, groupStart, groupEnd, huffmanTables); } return selectors; } List> _initialHuffmanTables(List _buffer, int alphaSize) { List> huffmanTables; int tableCount = _TABLE_COUNT_MAX; int totalSymbolCount = 0; List symbolCounts = new List.filled(_MAX_ALPHA_SIZE, 0); for (int value in _buffer) { symbolCounts[value]++; totalSymbolCount++; } huffmanTables = new List>(tableCount); int remainingSymbols = totalSymbolCount; int groupStart = 0; for (int table = tableCount - 1; table >= 0; table--) { int targetCount = remainingSymbols ~/ (table + 1); int groupEnd = groupStart; int currentCount = 0; while (currentCount < targetCount) { currentCount += symbolCounts[groupEnd++]; } huffmanTables[table] = new List<_HuffmanCode>.generate(alphaSize, (i) => new _HuffmanCode(0, (groupStart <= i && i < groupEnd) ? 0 : 1)); groupStart = groupEnd; remainingSymbols -= currentCount; } return huffmanTables; } int _getGroupStart(int group) { return group * _GROUP_SIZE; } int _getGroupEnd(int group, int blockLength) { return min((group + 1) * _GROUP_SIZE, blockLength).toInt(); } int _selectHuffmanTable(List block, int groupStart, int groupEnd, List> huffmanTables) { int bestTable = 0; int bestCost = 0xFFFFFFFF; for (int table = 0; table < huffmanTables.length; table++) { List<_HuffmanCode> huffmanTable = huffmanTables[table]; int tableCost = 0; for (int i = groupStart; i < groupEnd; i++) { int symbol = block[i]; tableCost += huffmanTable[symbol].len; } if (tableCost < bestCost) { bestTable = table; bestCost = tableCost; } } return bestTable; } }