/**
* Returns the CrossReferenceTable of the <CODE>Body</CODE>.
* @param os
* @param root
* @param info
* @param encryption
* @param fileID
* @param prevxref
* @throws IOException
*/
virtual public void WriteCrossReferenceTable(Stream os, PdfIndirectReference root, PdfIndirectReference info, PdfIndirectReference encryption, PdfObject fileID, long prevxref) {
int refNumber = 0;
if (writer.FullCompression) {
FlushObjStm();
refNumber = IndirectReferenceNumber;
xrefs[new PdfCrossReference(refNumber, position)] = null;
}
int first = ((PdfCrossReference)xrefs.GetMinKey()).Refnum;
int len = 0;
List<int> sections = new List<int>();
foreach (PdfCrossReference entry in xrefs.Keys) {
if (first + len == entry.Refnum)
++len;
else {
sections.Add(first);
sections.Add(len);
first = entry.Refnum;
len = 1;
}
}
sections.Add(first);
sections.Add(len);
if (writer.FullCompression) {
int mid = 5;
long mask = 0xff00000000L;
for (; mid > 1; --mid) {
if ((mask & position) != 0)
break;
mask >>= 8;
}
ByteBuffer buf = new ByteBuffer();
foreach (PdfCrossReference entry in xrefs.Keys) {
entry.ToPdf(mid, buf);
}
PdfStream xr = new PdfStream(buf.ToByteArray());
buf = null;
xr.FlateCompress(writer.CompressionLevel);
xr.Put(PdfName.SIZE, new PdfNumber(Size));
xr.Put(PdfName.ROOT, root);
if (info != null) {
xr.Put(PdfName.INFO, info);
}
if (encryption != null)
xr.Put(PdfName.ENCRYPT, encryption);
if (fileID != null)
xr.Put(PdfName.ID, fileID);
xr.Put(PdfName.W, new PdfArray(new int[]{1, mid, 2}));
xr.Put(PdfName.TYPE, PdfName.XREF);
PdfArray idx = new PdfArray();
for (int k = 0; k < sections.Count; ++k)
idx.Add(new PdfNumber(sections[k]));
xr.Put(PdfName.INDEX, idx);
if (prevxref > 0)
xr.Put(PdfName.PREV, new PdfNumber(prevxref));
PdfEncryption enc = writer.crypto;
writer.crypto = null;
PdfIndirectObject indirect = new PdfIndirectObject(refNumber, xr, writer);
indirect.WriteTo(writer.Os);
writer.crypto = enc;
}
else {
byte[] tmp = GetISOBytes("xref\n");
os.Write(tmp, 0, tmp.Length);
System.Collections.IEnumerator i = xrefs.Keys;
i.MoveNext();
for (int k = 0; k < sections.Count; k += 2) {
first = sections[k];
len = sections[k + 1];
tmp = GetISOBytes(first.ToString());
os.Write(tmp, 0, tmp.Length);
os.WriteByte((byte)' ');
tmp = GetISOBytes(len.ToString());
os.Write(tmp, 0, tmp.Length);
os.WriteByte((byte)'\n');
while (len-- > 0) {
((PdfCrossReference)i.Current).ToPdf(os);
i.MoveNext();
}
}
}
}