protected internal bool ReadXRefStream(int ptr) {
tokens.Seek(ptr);
int thisStream = 0;
if (!tokens.NextToken())
return false;
if (tokens.TokenType != PRTokeniser.TK_NUMBER)
return false;
thisStream = tokens.IntValue;
if (!tokens.NextToken() || tokens.TokenType != PRTokeniser.TK_NUMBER)
return false;
if (!tokens.NextToken() || !tokens.StringValue.Equals("obj"))
return false;
PdfObject objecto = ReadPRObject();
PRStream stm = null;
if (objecto.IsStream()) {
stm = (PRStream)objecto;
if (!PdfName.XREF.Equals(stm.Get(PdfName.TYPE)))
return false;
}
else
return false;
if (trailer == null) {
trailer = new PdfDictionary();
trailer.Merge(stm);
}
stm.Length = ((PdfNumber)stm.Get(PdfName.LENGTH)).IntValue;
int size = ((PdfNumber)stm.Get(PdfName.SIZE)).IntValue;
PdfArray index;
PdfObject obj = stm.Get(PdfName.INDEX);
if (obj == null) {
index = new PdfArray();
index.Add(new int[]{0, size});
}
else
index = (PdfArray)obj;
PdfArray w = (PdfArray)stm.Get(PdfName.W);
int prev = -1;
obj = stm.Get(PdfName.PREV);
if (obj != null)
prev = ((PdfNumber)obj).IntValue;
// Each xref pair is a position
// type 0 -> -1, 0
// type 1 -> offset, 0
// type 2 -> index, obj num
EnsureXrefSize(size * 2);
if (objStmMark == null && !partial)
objStmMark = new Hashtable();
if (objStmToOffset == null && partial)
objStmToOffset = new IntHashtable();
byte[] b = GetStreamBytes(stm, tokens.File);
int bptr = 0;
int[] wc = new int[3];
for (int k = 0; k < 3; ++k)
wc[k] = w.GetAsNumber(k).IntValue;
for (int idx = 0; idx < index.Size; idx += 2) {
int start = index.GetAsNumber(idx).IntValue;
int length = index.GetAsNumber(idx + 1).IntValue;
EnsureXrefSize((start + length) * 2);
while (length-- > 0) {
int type = 1;
if (wc[0] > 0) {
type = 0;
for (int k = 0; k < wc[0]; ++k)
type = (type << 8) + (b[bptr++] & 0xff);
}
int field2 = 0;
for (int k = 0; k < wc[1]; ++k)
field2 = (field2 << 8) + (b[bptr++] & 0xff);
int field3 = 0;
for (int k = 0; k < wc[2]; ++k)
field3 = (field3 << 8) + (b[bptr++] & 0xff);
int baseb = start * 2;
if (xref[baseb] == 0 && xref[baseb + 1] == 0) {
switch (type) {
case 0:
xref[baseb] = -1;
break;
case 1:
xref[baseb] = field2;
break;
case 2:
xref[baseb] = field3;
xref[baseb + 1] = field2;
if (partial) {
objStmToOffset[field2] = 0;
}
else {
IntHashtable seq = (IntHashtable)objStmMark[field2];
if (seq == null) {
seq = new IntHashtable();
seq[field3] = 1;
objStmMark[field2] = seq;
}
else
seq[field3] = 1;
}
break;
}
}
++start;
}
}
thisStream *= 2;
if (thisStream < xref.Length)
xref[thisStream] = -1;
if (prev == -1)
return true;
return ReadXRefStream(prev);
}