Back to index

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

#include <Parser.h>

Collaboration diagram for Parser:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 Parser (XRef *xrefA, Lexer *lexerA)
 ~Parser ()
ObjectgetObj (Object *obj, Guchar *fileKey=NULL, int keyLength=0, int objNum=0, int objGen=0)
StreamgetStream ()
int getPos ()

Private Member Functions

StreammakeStream (Object *dict)
void shift ()

Private Attributes

XRefxref
Lexerlexer
Object buf1
Object buf2
int inlineImg

Detailed Description

Definition at line 24 of file Parser.h.


Constructor & Destructor Documentation

Parser::Parser ( XRef xrefA,
Lexer lexerA 
)

Definition at line 26 of file Parser.cc.

                                         {
  xref = xrefA;
  lexer = lexerA;
  inlineImg = 0;
  lexer->getObj(&buf1);
  lexer->getObj(&buf2);
}

Here is the call graph for this function:

Definition at line 34 of file Parser.cc.

                {
  buf1.free();
  buf2.free();
  delete lexer;
}

Here is the call graph for this function:


Member Function Documentation

Object * Parser::getObj ( Object obj,
Guchar fileKey = NULL,
int  keyLength = 0,
int  objNum = 0,
int  objGen = 0 
)

Definition at line 41 of file Parser.cc.

                                             {
#else
Object *Parser::getObj(Object *obj) {
#endif
  char *key;
  Stream *str;
  Object obj2;
  int num;
#ifndef NO_DECRYPTION
  Decrypt *decrypt;
  GString *s;
  char *p;
  int i;
#endif

  // refill buffer after inline image data
  if (inlineImg == 2) {
    buf1.free();
    buf2.free();
    lexer->getObj(&buf1);
    lexer->getObj(&buf2);
    inlineImg = 0;
  }

  // array
  if (buf1.isCmd("[")) {
    shift();
    obj->initArray(xref);
    while (!buf1.isCmd("]") && !buf1.isEOF())
#ifndef NO_DECRYPTION
      obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
#else
      obj->arrayAdd(getObj(&obj2));
#endif
    if (buf1.isEOF())
      error(getPos(), "End of file inside array");
    shift();

  // dictionary or stream
  } else if (buf1.isCmd("<<")) {
    shift();
    obj->initDict(xref);
    while (!buf1.isCmd(">>") && !buf1.isEOF()) {
      if (!buf1.isName()) {
       error(getPos(), "Dictionary key must be a name object");
       shift();
      } else {
       key = copyString(buf1.getName());
       shift();
       if (buf1.isEOF() || buf1.isError()) {
         gfree(key);
         break;
       }
#ifndef NO_DECRYPTION
       obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
#else
       obj->dictAdd(key, getObj(&obj2));
#endif
      }
    }
    if (buf1.isEOF())
      error(getPos(), "End of file inside dictionary");
    if (buf2.isCmd("stream")) {
      if ((str = makeStream(obj))) {
       obj->initStream(str);
#ifndef NO_DECRYPTION
       if (fileKey) {
         str->getBaseStream()->doDecryption(fileKey, keyLength,
                                        objNum, objGen);
       }
#endif
      } else {
       obj->free();
       obj->initError();
      }
    } else {
      shift();
    }

  // indirect reference or integer
  } else if (buf1.isInt()) {
    num = buf1.getInt();
    shift();
    if (buf1.isInt() && buf2.isCmd("R")) {
      obj->initRef(num, buf1.getInt());
      shift();
      shift();
    } else {
      obj->initInt(num);
    }

#ifndef NO_DECRYPTION
  // string
  } else if (buf1.isString() && fileKey) {
    buf1.copy(obj);
    s = obj->getString();
    decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
    for (i = 0, p = obj->getString()->getCString();
        i < s->getLength();
        ++i, ++p) {
      *p = decrypt->decryptByte(*p);
    }
    delete decrypt;
    shift();
#endif

  // simple object
  } else {
    buf1.copy(obj);
    shift();
  }

  return obj;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Parser::getPos ( ) [inline]

Definition at line 46 of file Parser.h.

{ return lexer->getPos(); }

Here is the call graph for this function:

Here is the caller graph for this function:

Stream* Parser::getStream ( ) [inline]

Definition at line 43 of file Parser.h.

{ return lexer->getStream(); }

Here is the call graph for this function:

Here is the caller graph for this function:

Stream * Parser::makeStream ( Object dict) [private]

Definition at line 158 of file Parser.cc.

                                       {
  Object obj;
  Stream *str;
  Guint pos, endPos, length;

  // get stream start position
  lexer->skipToNextLine();
  pos = lexer->getPos();

  // get length
  dict->dictLookup("Length", &obj);
  if (obj.isInt()) {
    length = (Guint)obj.getInt();
    obj.free();
  } else {
    error(getPos(), "Bad 'Length' attribute in stream");
    obj.free();
    return NULL;
  }

  // check for length in damaged file
  if (xref && xref->getStreamEnd(pos, &endPos)) {
    length = endPos - pos;
  }

  // in badly damaged PDF files, we can run off the end of the input
  // stream immediately after the "stream" token
  if (!lexer->getStream()) {
    return NULL;
  }

  // make base stream
  str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
                                                    length, dict);

  // get filters
  str = str->addFilters(dict);

  // skip over stream data
  lexer->setPos(pos + length);

  // refill token buffers and check for 'endstream'
  shift();  // kill '>>'
  shift();  // kill 'stream'
  if (buf1.isCmd("endstream")) {
    shift();
  } else {
    error(getPos(), "Missing 'endstream'");
    str->ignoreLength();
  }

  return str;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void Parser::shift ( ) [private]

Definition at line 212 of file Parser.cc.

                   {
  if (inlineImg > 0) {
    if (inlineImg < 2) {
      ++inlineImg;
    } else {
      // in a damaged content stream, if 'ID' shows up in the middle
      // of a dictionary, we need to reset
      inlineImg = 0;
    }
  } else if (buf2.isCmd("ID")) {
    lexer->skipChar();             // skip char after 'ID' command
    inlineImg = 1;
  }
  buf1.free();
  buf1 = buf2;
  if (inlineImg > 0)        // don't buffer inline image data
    buf2.initNull();
  else
    lexer->getObj(&buf2);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Object Parser::buf1 [private]

Definition at line 52 of file Parser.h.

Object Parser::buf2 [private]

Definition at line 52 of file Parser.h.

Definition at line 53 of file Parser.h.

Lexer* Parser::lexer [private]

Definition at line 51 of file Parser.h.

XRef* Parser::xref [private]

Definition at line 50 of file Parser.h.


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