Back to index

tetex-bin  3.0
Public Member Functions | Private Member Functions | Private Attributes
XRef Class Reference

#include <XRef.h>

Collaboration diagram for XRef:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 XRef (BaseStream *strA, GString *ownerPassword, GString *userPassword)
 ~XRef ()
GBool isOk ()
int getErrorCode ()
GBool isEncrypted ()
GBool okToPrint (GBool ignoreOwnerPW=gFalse)
GBool okToChange (GBool ignoreOwnerPW=gFalse)
GBool okToCopy (GBool ignoreOwnerPW=gFalse)
GBool okToAddNotes (GBool ignoreOwnerPW=gFalse)
ObjectgetCatalog (Object *obj)
Objectfetch (int num, int gen, Object *obj)
ObjectgetDocInfo (Object *obj)
ObjectgetDocInfoNF (Object *obj)
int getNumObjects ()
Guint getLastXRefPos ()
int getRootNum ()
int getRootGen ()
GBool getStreamEnd (Guint streamStart, Guint *streamEnd)
int getSize ()
XRefEntrygetEntry (int i)
ObjectgetTrailerDict ()

Private Member Functions

Guint getStartXref ()
GBool readXRef (Guint *pos)
GBool readXRefTable (Parser *parser, Guint *pos)
GBool readXRefStreamSection (Stream *xrefStr, int *w, int first, int n)
GBool readXRefStream (Stream *xrefStr, Guint *pos)
GBool constructXRef ()
GBool checkEncrypted (GString *ownerPassword, GString *userPassword)
Guint strToUnsigned (char *s)

Private Attributes

BaseStreamstr
Guint start
XRefEntryentries
int size
int rootNum
int rootGen
GBool ok
int errCode
Object trailerDict
Guint lastXRefPos
GuintstreamEnds
int streamEndsLen
ObjectStreamobjStr
GBool encrypted
int encVersion
int encRevision
int keyLength
int permFlags
Guchar fileKey [16]
GBool ownerPasswordOk

Detailed Description

Definition at line 42 of file XRef.h.


Constructor & Destructor Documentation

XRef::XRef ( BaseStream strA,
GString ownerPassword,
GString userPassword 
)

Definition at line 198 of file XRef.cc.

                                                                          {
  Guint pos;
  Object obj;

  ok = gTrue;
  errCode = errNone;
  size = 0;
  entries = NULL;
  streamEnds = NULL;
  streamEndsLen = 0;
  objStr = NULL;

  // read the trailer
  str = strA;
  start = str->getStart();
  pos = getStartXref();

  // if there was a problem with the 'startxref' position, try to
  // reconstruct the xref table
  if (pos == 0) {
    if (!(ok = constructXRef())) {
      errCode = errDamaged;
      return;
    }

  // read the xref table
  } else {
    while (readXRef(&pos)) ;

    // if there was a problem with the xref table,
    // try to reconstruct it
    if (!ok) {
      if (!(ok = constructXRef())) {
       errCode = errDamaged;
       return;
      }
    }
  }

  // get the root dictionary (catalog) object
  trailerDict.dictLookupNF("Root", &obj);
  if (obj.isRef()) {
    rootNum = obj.getRefNum();
    rootGen = obj.getRefGen();
    obj.free();
  } else {
    obj.free();
    if (!(ok = constructXRef())) {
      errCode = errDamaged;
      return;
    }
  }

  // now set the trailer dictionary's xref pointer so we can fetch
  // indirect objects from it
  trailerDict.getDict()->setXRef(this);

  // check for encryption
#ifndef NO_DECRYPTION
  encrypted = gFalse;
#endif
  if (checkEncrypted(ownerPassword, userPassword)) {
    ok = gFalse;
    errCode = errEncrypted;
    return;
  }
}

Here is the call graph for this function:

Definition at line 266 of file XRef.cc.

            {
  gfree(entries);
  trailerDict.free();
  if (streamEnds) {
    gfree(streamEnds);
  }
  if (objStr) {
    delete objStr;
  }
}

Here is the call graph for this function:


Member Function Documentation

GBool XRef::checkEncrypted ( GString ownerPassword,
GString userPassword 
) [private]

Definition at line 759 of file XRef.cc.

                                                                        {
  Object encrypt, filterObj, versionObj, revisionObj, lengthObj;
  Object ownerKey, userKey, permissions, fileID, fileID1;
  GBool encrypted1;
  GBool ret;

  keyLength = 0;
  encVersion = encRevision = 0;
  ret = gFalse;

  permFlags = defPermFlags;
  ownerPasswordOk = gFalse;
  trailerDict.dictLookup("Encrypt", &encrypt);
  if ((encrypted1 = encrypt.isDict())) {
    ret = gTrue;
    encrypt.dictLookup("Filter", &filterObj);
    if (filterObj.isName("Standard")) {
      encrypt.dictLookup("V", &versionObj);
      encrypt.dictLookup("R", &revisionObj);
      encrypt.dictLookup("Length", &lengthObj);
      encrypt.dictLookup("O", &ownerKey);
      encrypt.dictLookup("U", &userKey);
      encrypt.dictLookup("P", &permissions);
      trailerDict.dictLookup("ID", &fileID);
      if (versionObj.isInt() &&
         revisionObj.isInt() &&
         ownerKey.isString() && ownerKey.getString()->getLength() == 32 &&
         userKey.isString() && userKey.getString()->getLength() == 32 &&
         permissions.isInt() &&
         fileID.isArray()) {
       encVersion = versionObj.getInt();
       encRevision = revisionObj.getInt();
       if (lengthObj.isInt()) {
         keyLength = lengthObj.getInt() / 8;
       } else {
         keyLength = 5;
       }
        if (keyLength > 16) {
          keyLength = 16;
        }
       permFlags = permissions.getInt();
       if (encVersion >= 1 && encVersion <= 2 &&
           encRevision >= 2 && encRevision <= 3) {
         fileID.arrayGet(0, &fileID1);
         if (fileID1.isString()) {
           if (Decrypt::makeFileKey(encVersion, encRevision, keyLength,
                                 ownerKey.getString(), userKey.getString(),
                                 permFlags, fileID1.getString(),
                                 ownerPassword, userPassword, fileKey,
                                 &ownerPasswordOk)) {
             if (ownerPassword && !ownerPasswordOk) {
              error(-1, "Incorrect owner password");
             }
             ret = gFalse;
           } else {
             error(-1, "Incorrect password");
           }
         } else {
           error(-1, "Weird encryption info");
         }
         fileID1.free();
       } else {
         error(-1, "Unsupported version/revision (%d/%d) of Standard security handler",
              encVersion, encRevision);
       }
      } else {
       error(-1, "Weird encryption info");
      }
      fileID.free();
      permissions.free();
      userKey.free();
      ownerKey.free();
      lengthObj.free();
      revisionObj.free();
      versionObj.free();
    } else {
      error(-1, "Unknown security handler '%s'",
           filterObj.isName() ? filterObj.getName() : "???");
    }
    filterObj.free();
  }
  encrypt.free();

  // this flag has to be set *after* we read the O/U/P strings
  encrypted = encrypted1;

  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool XRef::constructXRef ( ) [private]

Definition at line 643 of file XRef.cc.

                          {
  Parser *parser;
  Object newTrailerDict, obj;
  char buf[256];
  Guint pos;
  int num, gen;
  int newSize;
  int streamEndsSize;
  char *p;
  int i;
  GBool gotRoot;

  gfree(entries);
  size = 0;
  entries = NULL;

  error(0, "PDF file is damaged - attempting to reconstruct xref table...");
  gotRoot = gFalse;
  streamEndsLen = streamEndsSize = 0;

  str->reset();
  while (1) {
    pos = str->getPos();
    if (!str->getLine(buf, 256)) {
      break;
    }
    p = buf;

    // got trailer dictionary
    if (!strncmp(p, "trailer", 7)) {
      obj.initNull();
      parser = new Parser(NULL,
               new Lexer(NULL,
                 str->makeSubStream(start + pos + 7, gFalse, 0, &obj)));
      parser->getObj(&newTrailerDict);
      if (newTrailerDict.isDict()) {
       newTrailerDict.dictLookupNF("Root", &obj);
       if (obj.isRef()) {
         rootNum = obj.getRefNum();
         rootGen = obj.getRefGen();
         if (!trailerDict.isNone()) {
           trailerDict.free();
         }
         newTrailerDict.copy(&trailerDict);
         gotRoot = gTrue;
       }
       obj.free();
      }
      newTrailerDict.free();
      delete parser;

    // look for object
    } else if (isdigit(*p)) {
      num = atoi(p);
      if (num > 0) {
       do {
         ++p;
       } while (*p && isdigit(*p));
       if (isspace(*p)) {
         do {
           ++p;
         } while (*p && isspace(*p));
         if (isdigit(*p)) {
           gen = atoi(p);
           do {
             ++p;
           } while (*p && isdigit(*p));
           if (isspace(*p)) {
             do {
              ++p;
             } while (*p && isspace(*p));
             if (!strncmp(p, "obj", 3)) {
              if (num >= size) {
                newSize = (num + 1 + 255) & ~255;
                if (newSize < 0) {
                  error(-1, "Bad object number");
                  return gFalse;
                }
                entries = (XRefEntry *)
                    grealloc(entries, newSize * sizeof(XRefEntry));
                for (i = size; i < newSize; ++i) {
                  entries[i].offset = 0xffffffff;
                  entries[i].type = xrefEntryFree;
                }
                size = newSize;
              }
              if (entries[num].type == xrefEntryFree ||
                  gen >= entries[num].gen) {
                entries[num].offset = pos - start;
                entries[num].gen = gen;
                entries[num].type = xrefEntryUncompressed;
              }
             }
           }
         }
       }
      }

    } else if (!strncmp(p, "endstream", 9)) {
      if (streamEndsLen == streamEndsSize) {
       streamEndsSize += 64;
       streamEnds = (Guint *)grealloc(streamEnds,
                                   streamEndsSize * sizeof(int));
      }
      streamEnds[streamEndsLen++] = pos;
    }
  }

  if (gotRoot)
    return gTrue;

  error(-1, "Couldn't find trailer dictionary");
  return gFalse;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Object * XRef::fetch ( int  num,
int  gen,
Object obj 
)

Definition at line 894 of file XRef.cc.

                                                 {
  XRefEntry *e;
  Parser *parser;
  Object obj1, obj2, obj3;

  // check for bogus ref - this can happen in corrupted PDF files
  if (num < 0 || num >= size) {
    goto err;
  }

  e = &entries[num];
  switch (e->type) {

  case xrefEntryUncompressed:
    if (e->gen != gen) {
      goto err;
    }
    obj1.initNull();
    parser = new Parser(this,
              new Lexer(this,
               str->makeSubStream(start + e->offset, gFalse, 0, &obj1)));
    parser->getObj(&obj1);
    parser->getObj(&obj2);
    parser->getObj(&obj3);
    if (!obj1.isInt() || obj1.getInt() != num ||
       !obj2.isInt() || obj2.getInt() != gen ||
       !obj3.isCmd("obj")) {
      goto err;
    }
#ifndef NO_DECRYPTION
    parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength,
                 num, gen);
#else
    parser->getObj(obj);
#endif
    obj1.free();
    obj2.free();
    obj3.free();
    delete parser;
    break;

  case xrefEntryCompressed:
    if (gen != 0) {
      goto err;
    }
    if (!objStr || objStr->getObjStrNum() != (int)e->offset) {
      if (objStr) {
       delete objStr;
      }
      objStr = new ObjectStream(this, e->offset);
    }
    objStr->getObject(e->gen, num, obj);
    break;

  default:
    goto err;
  }

  return obj;

 err:
  return obj->initNull();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Object* XRef::getCatalog ( Object obj) [inline]

Definition at line 71 of file XRef.h.

{ return fetch(rootNum, rootGen, obj); }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 958 of file XRef.cc.

                                    {
  return trailerDict.dictLookup("Info", obj);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 963 of file XRef.cc.

                                      {
  return trailerDict.dictLookupNF("Info", obj);
}

Here is the call graph for this function:

Here is the caller graph for this function:

XRefEntry* XRef::getEntry ( int  i) [inline]

Definition at line 96 of file XRef.h.

{ return &entries[i]; }
int XRef::getErrorCode ( ) [inline]

Definition at line 55 of file XRef.h.

{ return errCode; }

Here is the caller graph for this function:

Definition at line 84 of file XRef.h.

{ return lastXRefPos; }
int XRef::getNumObjects ( ) [inline]

Definition at line 81 of file XRef.h.

{ return size; }
int XRef::getRootGen ( ) [inline]

Definition at line 88 of file XRef.h.

{ return rootGen; }
int XRef::getRootNum ( ) [inline]

Definition at line 87 of file XRef.h.

{ return rootNum; }
int XRef::getSize ( ) [inline]

Definition at line 95 of file XRef.h.

{ return size; }
Guint XRef::getStartXref ( ) [private]

Definition at line 278 of file XRef.cc.

                         {
  char buf[xrefSearchSize+1];
  char *p;
  int c, n, i;

  // read last xrefSearchSize bytes
  str->setPos(xrefSearchSize, -1);
  for (n = 0; n < xrefSearchSize; ++n) {
    if ((c = str->getChar()) == EOF) {
      break;
    }
    buf[n] = c;
  }
  buf[n] = '\0';

  // find startxref
  for (i = n - 9; i >= 0; --i) {
    if (!strncmp(&buf[i], "startxref", 9)) {
      break;
    }
  }
  if (i < 0) {
    return 0;
  }
  for (p = &buf[i+9]; isspace(*p); ++p) ;
  lastXRefPos = strToUnsigned(p);

  return lastXRefPos;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool XRef::getStreamEnd ( Guint  streamStart,
Guint streamEnd 
)

Definition at line 967 of file XRef.cc.

                                                            {
  int a, b, m;

  if (streamEndsLen == 0 ||
      streamStart > streamEnds[streamEndsLen - 1]) {
    return gFalse;
  }

  a = -1;
  b = streamEndsLen - 1;
  // invariant: streamEnds[a] < streamStart <= streamEnds[b]
  while (b - a > 1) {
    m = (a + b) / 2;
    if (streamStart <= streamEnds[m]) {
      b = m;
    } else {
      a = m;
    }
  }
  *streamEnd = streamEnds[b];
  return gTrue;
}

Here is the caller graph for this function:

Definition at line 97 of file XRef.h.

{ return &trailerDict; }
GBool XRef::isEncrypted ( ) [inline]

Definition at line 59 of file XRef.h.

{ return encrypted; }

Here is the caller graph for this function:

GBool XRef::isOk ( ) [inline]

Definition at line 52 of file XRef.h.

{ return ok; }

Here is the caller graph for this function:

GBool XRef::okToAddNotes ( GBool  ignoreOwnerPW = gFalse)

Definition at line 886 of file XRef.cc.

                                            {
#ifndef NO_DECRYPTION
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permNotes);
#else
  return gTrue;
#endif
}

Here is the caller graph for this function:

GBool XRef::okToChange ( GBool  ignoreOwnerPW = gFalse)

Definition at line 870 of file XRef.cc.

                                          {
#ifndef NO_DECRYPTION
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permChange);
#else
  return gTrue;
#endif
}

Here is the caller graph for this function:

GBool XRef::okToCopy ( GBool  ignoreOwnerPW = gFalse)

Definition at line 878 of file XRef.cc.

                                        {
#ifndef NO_DECRYPTION
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permCopy);
#else
  return gTrue;
#endif
}

Here is the caller graph for this function:

GBool XRef::okToPrint ( GBool  ignoreOwnerPW = gFalse)

Definition at line 862 of file XRef.cc.

                                         {
#ifndef NO_DECRYPTION
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint);
#else
  return gTrue;
#endif
}

Here is the caller graph for this function:

GBool XRef::readXRef ( Guint pos) [private]

Definition at line 310 of file XRef.cc.

                               {
  Parser *parser;
  Object obj;
  GBool more;

  // start up a parser, parse one token
  obj.initNull();
  parser = new Parser(NULL,
            new Lexer(NULL,
              str->makeSubStream(start + *pos, gFalse, 0, &obj)));
  parser->getObj(&obj);

  // parse an old-style xref table
  if (obj.isCmd("xref")) {
    obj.free();
    more = readXRefTable(parser, pos);

  // parse an xref stream
  } else if (obj.isInt()) {
    obj.free();
    if (!parser->getObj(&obj)->isInt()) {
      goto err1;
    }
    obj.free();
    if (!parser->getObj(&obj)->isCmd("obj")) {
      goto err1;
    }
    obj.free();
    if (!parser->getObj(&obj)->isStream()) {
      goto err1;
    }
    more = readXRefStream(obj.getStream(), pos);
    obj.free();

  } else {
    goto err1;
  }

  delete parser;
  return more;

 err1:
  obj.free();
  delete parser;
  ok = gFalse;
  return gFalse;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool XRef::readXRefStream ( Stream xrefStr,
Guint pos 
) [private]

Definition at line 478 of file XRef.cc.

                                                      {
  Dict *dict;
  int w[3];
  GBool more;
  Object obj, obj2, idx;
  int newSize, first, n, i;

  dict = xrefStr->getDict();

  if (!dict->lookupNF("Size", &obj)->isInt()) {
    goto err1;
  }
  newSize = obj.getInt();
  obj.free();
  if (newSize < 0) {
    goto err1;
  }
  if (newSize > size) {
    entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
    for (i = size; i < newSize; ++i) {
      entries[i].offset = 0xffffffff;
      entries[i].type = xrefEntryFree;
    }
    size = newSize;
  }

  if (!dict->lookupNF("W", &obj)->isArray() ||
      obj.arrayGetLength() < 3) {
    goto err1;
  }
  for (i = 0; i < 3; ++i) {
    if (!obj.arrayGet(i, &obj2)->isInt()) {
      obj2.free();
      goto err1;
    }
    w[i] = obj2.getInt();
    obj2.free();
    if (w[i] < 0 || w[i] > 4) {
      goto err1;
    }
  }
  obj.free();

  xrefStr->reset();
  dict->lookupNF("Index", &idx);
  if (idx.isArray()) {
    for (i = 0; i+1 < idx.arrayGetLength(); i += 2) {
      if (!idx.arrayGet(i, &obj)->isInt()) {
       idx.free();
       goto err1;
      }
      first = obj.getInt();
      obj.free();
      if (!idx.arrayGet(i+1, &obj)->isInt()) {
       idx.free();
       goto err1;
      }
      n = obj.getInt();
      obj.free();
      if (first < 0 || n < 0 ||
         !readXRefStreamSection(xrefStr, w, first, n)) {
       idx.free();
       goto err0;
      }
    }
  } else {
    if (!readXRefStreamSection(xrefStr, w, 0, newSize)) {
      idx.free();
      goto err0;
    }
  }
  idx.free();

  dict->lookupNF("Prev", &obj);
  if (obj.isInt()) {
    *pos = (Guint)obj.getInt();
    more = gTrue;
  } else {
    more = gFalse;
  }
  obj.free();
  if (trailerDict.isNone()) {
    trailerDict.initDict(dict);
  }

  return more;

 err1:
  obj.free();
 err0:
  ok = gFalse;
  return gFalse;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool XRef::readXRefStreamSection ( Stream xrefStr,
int w,
int  first,
int  n 
) [private]

Definition at line 572 of file XRef.cc.

                                                                           {
  Guint offset;
  int type, gen, c, newSize, i, j;

  if (first + n < 0) {
    return gFalse;
  }
  if (first + n > size) {
    for (newSize = size ? 2 * size : 1024;
        first + n > newSize && newSize > 0;
        newSize <<= 1) ;
    if (newSize < 0) {
      return gFalse;
    }
    entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
    for (i = size; i < newSize; ++i) {
      entries[i].offset = 0xffffffff;
      entries[i].type = xrefEntryFree;
    }
    size = newSize;
  }
  for (i = first; i < first + n; ++i) {
    if (w[0] == 0) {
      type = 1;
    } else {
      for (type = 0, j = 0; j < w[0]; ++j) {
       if ((c = xrefStr->getChar()) == EOF) {
         return gFalse;
       }
       type = (type << 8) + c;
      }
    }
    for (offset = 0, j = 0; j < w[1]; ++j) {
      if ((c = xrefStr->getChar()) == EOF) {
       return gFalse;
      }
      offset = (offset << 8) + c;
    }
    for (gen = 0, j = 0; j < w[2]; ++j) {
      if ((c = xrefStr->getChar()) == EOF) {
       return gFalse;
      }
      gen = (gen << 8) + c;
    }
    if (entries[i].offset == 0xffffffff) {
      switch (type) {
      case 0:
       entries[i].offset = offset;
       entries[i].gen = gen;
       entries[i].type = xrefEntryFree;
       break;
      case 1:
       entries[i].offset = offset;
       entries[i].gen = gen;
       entries[i].type = xrefEntryUncompressed;
       break;
      case 2:
       entries[i].offset = offset;
       entries[i].gen = gen;
       entries[i].type = xrefEntryCompressed;
       break;
      default:
       return gFalse;
      }
    }
  }

  return gTrue;
}

Here is the call graph for this function:

Here is the caller graph for this function:

GBool XRef::readXRefTable ( Parser parser,
Guint pos 
) [private]

Definition at line 358 of file XRef.cc.

                                                    {
  XRefEntry entry;
  GBool more;
  Object obj, obj2;
  Guint pos2;
  int first, n, newSize, i;

  while (1) {
    parser->getObj(&obj);
    if (obj.isCmd("trailer")) {
      obj.free();
      break;
    }
    if (!obj.isInt()) {
      goto err1;
    }
    first = obj.getInt();
    obj.free();
    if (!parser->getObj(&obj)->isInt()) {
      goto err1;
    }
    n = obj.getInt();
    obj.free();
    if (first < 0 || n < 0 || first + n < 0) {
      goto err1;
    }
    if (first + n > size) {
      for (newSize = size ? 2 * size : 1024;
          first + n > newSize && newSize > 0;
          newSize <<= 1) ;
      if (newSize < 0) {
       goto err1;
      }
      entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry));
      for (i = size; i < newSize; ++i) {
       entries[i].offset = 0xffffffff;
       entries[i].type = xrefEntryFree;
      }
      size = newSize;
    }
    for (i = first; i < first + n; ++i) {
      if (!parser->getObj(&obj)->isInt()) {
       goto err1;
      }
      entry.offset = (Guint)obj.getInt();
      obj.free();
      if (!parser->getObj(&obj)->isInt()) {
       goto err1;
      }
      entry.gen = obj.getInt();
      obj.free();
      parser->getObj(&obj);
      if (obj.isCmd("n")) {
       entry.type = xrefEntryUncompressed;
      } else if (obj.isCmd("f")) {
       entry.type = xrefEntryFree;
      } else {
       goto err1;
      }
      obj.free();
      if (entries[i].offset == 0xffffffff) {
       entries[i] = entry;
       // PDF files of patents from the IBM Intellectual Property
       // Network have a bug: the xref table claims to start at 1
       // instead of 0.
       if (i == 1 && first == 1 &&
           entries[1].offset == 0 && entries[1].gen == 65535 &&
           entries[1].type == xrefEntryFree) {
         i = first = 0;
         entries[0] = entries[1];
         entries[1].offset = 0xffffffff;
       }
      }
    }
  }

  // read the trailer dictionary
  if (!parser->getObj(&obj)->isDict()) {
    goto err1;
  }

  // get the 'Prev' pointer
  obj.getDict()->lookupNF("Prev", &obj2);
  if (obj2.isInt()) {
    *pos = (Guint)obj2.getInt();
    more = gTrue;
  } else if (obj2.isRef()) {
    // certain buggy PDF generators generate "/Prev NNN 0 R" instead
    // of "/Prev NNN"
    *pos = (Guint)obj2.getRefNum();
    more = gTrue;
  } else {
    more = gFalse;
  }
  obj2.free();

  // save the first trailer dictionary
  if (trailerDict.isNone()) {
    obj.copy(&trailerDict);
  }

  // check for an 'XRefStm' key
  if (obj.getDict()->lookup("XRefStm", &obj2)->isInt()) {
    pos2 = (Guint)obj2.getInt();
    readXRef(&pos2);
    if (!ok) {
      goto err1;
    }
  }
  obj2.free();

  obj.free();
  return more;

 err1:
  obj.free();
  ok = gFalse;
  return gFalse;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Guint XRef::strToUnsigned ( char *  s) [private]

Definition at line 990 of file XRef.cc.

                                 {
  Guint x;
  char *p;
  int i;

  x = 0;
  for (p = s, i = 0; *p && isdigit(*p) && i < 10; ++p, ++i) {
    x = 10 * x + (*p - '0');
  }
  return x;
}

Here is the caller graph for this function:


Member Data Documentation

Definition at line 118 of file XRef.h.

Definition at line 116 of file XRef.h.

int XRef::encVersion [private]

Definition at line 117 of file XRef.h.

Definition at line 104 of file XRef.h.

int XRef::errCode [private]

Definition at line 108 of file XRef.h.

Guchar XRef::fileKey[16] [private]

Definition at line 121 of file XRef.h.

int XRef::keyLength [private]

Definition at line 119 of file XRef.h.

Definition at line 110 of file XRef.h.

Definition at line 114 of file XRef.h.

GBool XRef::ok [private]

Definition at line 107 of file XRef.h.

Definition at line 122 of file XRef.h.

int XRef::permFlags [private]

Definition at line 120 of file XRef.h.

int XRef::rootGen [private]

Definition at line 106 of file XRef.h.

int XRef::rootNum [private]

Definition at line 106 of file XRef.h.

int XRef::size [private]

Definition at line 105 of file XRef.h.

Guint XRef::start [private]

Definition at line 102 of file XRef.h.

BaseStream* XRef::str [private]

Definition at line 101 of file XRef.h.

Guint* XRef::streamEnds [private]

Definition at line 111 of file XRef.h.

Definition at line 113 of file XRef.h.

Definition at line 109 of file XRef.h.


The documentation for this class was generated from the following files: