private void flush(
IOutputStream stream
)
{
// 1. Body.
final PdfArray indexArray = new PdfArray();
final int[] entryFieldSizes = new int[]
{
EntryField0Size,
getFieldSize((int)stream.getLength()), // NOTE: We assume this xref stream is the last indirect object.
EntryField2Size
};
{
// Get the stream buffer!
final IBuffer body = getBody();
// Delete the old entries!
body.setLength(0);
// Serializing the entries into the stream buffer...
int prevObjectNumber = -2; // Previous-entry object number.
for(XRefEntry entry : entries.values())
{
int entryNumber = entry.getNumber();
if(entryNumber - prevObjectNumber != 1) // Current subsection terminated.
{
if(!indexArray.isEmpty())
{indexArray.add(new PdfInteger(prevObjectNumber-((PdfInteger)indexArray.get(indexArray.size()-1)).getValue()+1));} // Number of entries in the previous subsection.
indexArray.add(new PdfInteger(entryNumber)); // First object number in the next subsection.
}
prevObjectNumber = entryNumber;
switch(entry.getUsage())
{
case Free:
body.append((byte)FreeEntryType);
body.append(numberToByteArray(entry.getOffset(),entryFieldSizes[1]));
body.append(numberToByteArray(entry.getGeneration(),entryFieldSizes[2]));
break;
case InUse:
body.append((byte)InUseEntryType);
body.append(numberToByteArray(entry.getOffset(),entryFieldSizes[1]));
body.append(numberToByteArray(entry.getGeneration(),entryFieldSizes[2]));
break;
case InUseCompressed:
body.append((byte)InUseCompressedEntryType);
body.append(numberToByteArray(entry.getStreamNumber(),entryFieldSizes[1]));
body.append(numberToByteArray(entry.getOffset(),entryFieldSizes[2]));
break;
default:
throw new UnsupportedOperationException();
}
}
indexArray.add(new PdfInteger(prevObjectNumber-((PdfInteger)indexArray.get(indexArray.size()-1)).getValue()+1)); // Number of entries in the previous subsection.
}
// 2. Header.
{
final PdfDictionary header = getHeader();
header.put(
PdfName.Index,
indexArray
);
header.put(
PdfName.Size,
new PdfInteger(file.getIndirectObjects().size()+1)
);
header.put(
PdfName.W,
new PdfArray(
new PdfInteger(entryFieldSizes[0]),
new PdfInteger(entryFieldSizes[1]),
new PdfInteger(entryFieldSizes[2])
)
);