@Override public void visitContainedRecords(RecordVisitor rv) { PositionTrackingVisitor stv = new PositionTrackingVisitor(rv, 0); // DBCells are serialized before row records. final int blockCount = getRowBlockCount(); for (int blockIndex = 0; blockIndex < blockCount; blockIndex++) { // Serialize a block of rows. // Hold onto the position of the first row in the block int pos = 0; // Hold onto the size of this block that was serialized final int rowBlockSize = visitRowRecordsForBlock(blockIndex, rv); pos += rowBlockSize; // Serialize a block of cells for those rows final int startRowNumber = getStartRowNumberForBlock(blockIndex); final int endRowNumber = getEndRowNumberForBlock(blockIndex); DBCellRecord.Builder dbcrBuilder = new DBCellRecord.Builder(); // Note: Cell references start from the second row... int cellRefOffset = (rowBlockSize - RowRecord.ENCODED_SIZE); for (int row = startRowNumber; row <= endRowNumber; row++) { if (_valuesAgg.rowHasCells(row)) { stv.setPosition(0); _valuesAgg.visitCellsForRow(row, stv); int rowCellSize = stv.getPosition(); pos += rowCellSize; // Add the offset to the first cell for the row into the // DBCellRecord. dbcrBuilder.addCellOffset(cellRefOffset); cellRefOffset = rowCellSize; } } // Calculate Offset from the start of a DBCellRecord to the first Row rv.visitRecord(dbcrBuilder.build(pos)); } for (int i = 0; i < _unknownRecords.size(); i++) { // Potentially breaking the file here since we don't know exactly where to write these records rv.visitRecord(_unknownRecords.get(i)); } }
public void visitContainedRecords(RecordVisitor rv) { int nItems = records.size(); if (nItems < 1) { return; } ColumnInfoRecord cirPrev = null; for (int i = 0; i < nItems; i++) { ColumnInfoRecord cir = records.get(i); rv.visitRecord(cir); if (cirPrev != null && CIRComparator.compareColInfos(cirPrev, cir) > 0) { // Excel probably wouldn't mind, but there is much logic in this class // that assumes the column info records are kept in order throw new RuntimeException("Column info records are out of order"); } cirPrev = cir; } }
private int visitRowRecordsForBlock(int blockIndex, RecordVisitor rv) { final int startIndex = blockIndex * DBCellRecord.BLOCK_SIZE; final int endIndex = startIndex + DBCellRecord.BLOCK_SIZE; Iterator<RowRecord> rowIterator = _rowRecords.values().iterator(); // Given that we basically iterate through the rows in order, // For a performance improvement, it would be better to return an instance of // an iterator and use that instance throughout, rather than recreating one and // having to move it to the right position. int i = 0; for (; i < startIndex; i++) rowIterator.next(); int result = 0; while (rowIterator.hasNext() && (i++ < endIndex)) { Record rec = rowIterator.next(); result += rec.getRecordSize(); rv.visitRecord(rec); } return result; }