/// <summary>
 /// Gets a cross reference entry from an object identifier.
 /// Returns null if no object with the specified ID exists in the object table.
 /// </summary>
 public PdfReference this[PdfObjectID objectID]
 {
     get
     {
         PdfReference iref;
         ObjectTable.TryGetValue(objectID, out iref);
         return(iref);
     }
 }
Example #2
0
 /// <summary>
 /// Indicates whether this instance and a specified object are equal.
 /// </summary>
 public override bool Equals(object obj)
 {
     if (obj is PdfObjectID)
     {
         PdfObjectID id = (PdfObjectID)obj;
         if (_objectNumber == id._objectNumber)
             return _generationNumber == id._generationNumber;
     }
     return false;
 }
Example #3
0
 /// <summary>
 /// Compares the current object id with another object.
 /// </summary>
 public int CompareTo(object obj)
 {
     if (obj is PdfObjectID)
     {
         PdfObjectID id = (PdfObjectID)obj;
         if (_objectNumber == id._objectNumber)
             return _generationNumber - id._generationNumber;
         return _objectNumber - id._objectNumber;
     }
     return 1;
 }
Example #4
0
 /// <summary>
 /// Indicates whether this instance and a specified object are equal.
 /// </summary>
 public override bool Equals(object obj)
 {
     if (obj is PdfObjectID)
     {
         PdfObjectID id = (PdfObjectID)obj;
         if (_objectNumber == id._objectNumber)
         {
             return(_generationNumber == id._generationNumber);
         }
     }
     return(false);
 }
Example #5
0
 /// <summary>
 /// Compares the current object id with another object.
 /// </summary>
 public int CompareTo(object obj)
 {
     if (obj is PdfObjectID)
     {
         PdfObjectID id = (PdfObjectID)obj;
         if (this.objectNumber == id.objectNumber)
         {
             return(this.generationNumber - id.generationNumber);
         }
         return(this.objectNumber - id.objectNumber);
     }
     return(1);
 }
Example #6
0
        /// <summary>
        /// Sets the object and generation number
        /// Setting the object identifier makes this object an indirect object, i.e. the object gets
        /// a PdfReference entry in the PdfReferenceTable.
        /// </summary>
        internal void SetObjectID(int objectNumber, int generationNumber)
        {
            PdfObjectID objectID = new PdfObjectID(objectNumber, generationNumber);

            // TODO: check imported
            if (iref == null)
            {
                iref = document.irefTable[objectID];
            }
            if (iref == null)
            {
                iref          = new PdfReference(this);
                iref.ObjectID = objectID;
            }
            iref.Value    = this;
            iref.Document = document;
        }
Example #7
0
        /// <summary>
        /// Finds a page by its id. Transforms it to PdfPage if necessary.
        /// </summary>
        internal PdfPage FindPage(PdfObjectID id)  // TODO: public?
        {
            PdfPage page = null;

            foreach (PdfItem item in PagesArray)
            {
                PdfReference reference = item as PdfReference;
                if (reference != null)
                {
                    PdfDictionary dictionary = reference.Value as PdfDictionary;
                    if (dictionary != null && dictionary.ObjectID == id)
                    {
                        page = dictionary as PdfPage ?? new PdfPage(dictionary);
                        break;
                    }
                }
            }
            return(page);
        }
Example #8
0
        /// <summary>
        /// Sets the object and generation number.
        /// Setting the object identifier makes this object an indirect object, i.e. the object gets
        /// a PdfReference entry in the PdfReferenceTable.
        /// </summary>
        internal void SetObjectID(int objectNumber, int generationNumber)
        {
            PdfObjectID objectID = new PdfObjectID(objectNumber, generationNumber);

            // TODO: check imported
            if (_iref == null)
            {
                _iref = _document._irefTable[objectID];
            }
            if (_iref == null)
            {
                // ReSharper disable once ObjectCreationAsStatement because the new object is set to this object
                // in the constructor of PdfReference.
                new PdfReference(this);
                Debug.Assert(_iref != null);
                _iref.ObjectID = objectID;
            }
            _iref.Value    = this;
            _iref.Document = _document;
        }
 /// <summary>
 /// Indicates whether the specified object identifier is in the table.
 /// </summary>
 public bool Contains(PdfObjectID objectID)
 {
   return this.objectTable.ContainsKey(objectID);
 }
Example #10
0
        /// <summary>
        /// Sets the object and generation number.
        /// Setting the object identifier makes this object an indirect object, i.e. the object gets
        /// a PdfReference entry in the PdfReferenceTable.
        /// </summary>
        internal void SetObjectID(int objectNumber, int generationNumber)
        {
            PdfObjectID objectID = new PdfObjectID(objectNumber, generationNumber);

            // TODO: check imported
            if (_iref == null)
                _iref = _document._irefTable[objectID];
            if (_iref == null)
            {
                // ReSharper disable once ObjectCreationAsStatement because the new object is set to this object
                // in the constructor of PdfReference.
                new PdfReference(this);
                Debug.Assert(_iref != null);
                _iref.ObjectID = objectID;
            }
            _iref.Value = this;
            _iref.Document = _document;
        }
Example #11
0
 /// <summary>
 /// Returns the object with the specified Identifier, or null, if no such object exists.
 /// </summary>
 public PdfObject GetObject(PdfObjectID objectID)
 {
   return document.irefTable[objectID].Value;
 }
 /// <summary>
 /// Gets a cross reference entry from an object identifier.
 /// Returns null if no object with the specified ID exists in the object table.
 /// </summary>
 public PdfReference this[PdfObjectID objectID]
 {
   get
   {
     PdfReference iref;
     this.objectTable.TryGetValue(objectID, out iref);
     return iref;
   }
 }
Example #13
0
    /// <summary>
    /// 
    /// </summary>
    PdfTrailer ReadXRefTableAndTrailer(PdfReferenceTable xrefTable)
    {
      Debug.Assert(xrefTable != null);

      Symbol symbol = ScanNextToken();
      // Is it an xref stream?
      if (symbol == Symbol.Integer)
        throw new PdfReaderException(PSSR.CannotHandleXRefStreams);
      // TODO: We have all code to handle them -> just do it
      Debug.Assert(symbol == Symbol.XRef);
      while (true)
      {
        symbol = ScanNextToken();
        if (symbol == Symbol.Integer)
        {
          int start = this.lexer.TokenToInteger;
          int length = ReadInteger();
          for (int id = start; id < start + length; id++)
          {
            int position = ReadInteger();
            int generation = ReadInteger();
            ReadSymbol(Symbol.Keyword);
            string token = lexer.Token;
            // Skip start entry
            if (id == 0)
              continue;
            // Skip unused entries.
            if (token != "n")
              continue;
            // Even it is restricted, an object can exists in more than one subsection.
            // (PDF Reference Implementation Notes 15).
            PdfObjectID objectID = new PdfObjectID(id, generation);
            // Ignore the latter one
            if (xrefTable.Contains(objectID))
              continue;
            xrefTable.Add(new PdfReference(objectID, position));
          }
        }
        else if (symbol == Symbol.Trailer)
        {
          ReadSymbol(Symbol.BeginDictionary);
          PdfTrailer trailer = new PdfTrailer(this.document);
          this.ReadDictionary(trailer, false);
          return trailer;
        }
        else
          throw new PdfReaderException(PSSR.UnexpectedToken(this.lexer.Token));
      }
    }
Example #14
0
 /// <summary>
 /// Sets PDF input stream position the the specified object.
 /// </summary>
 public int MoveToObject(PdfObjectID objectID)
 {
   int position = this.document.irefTable[objectID].Position;
   return this.lexer.Position = position;
 }
Example #15
0
    /// <summary>
    /// Parses whatever comes until the specified stop symbol is reached.
    /// </summary>
    void ParseObject(Symbol stop)
    {
#if DEBUG_
      ParseObjectCounter++;
      Debug.WriteLine(ParseObjectCounter.ToString());
      if (ParseObjectCounter == 178)
        GetType();
#endif
      Symbol symbol;
      while ((symbol = ScanNextToken()) != Symbol.Eof)
      {
        if (symbol == stop)
          return;

        switch (symbol)
        {
          case Symbol.Comment:
            // ignore comments
            break;

          case Symbol.Null:
            this.stack.Shift(PdfNull.Value);
            break;

          case Symbol.Boolean:
            this.stack.Shift(new PdfBoolean(this.lexer.TokenToBoolean));
            break;

          case Symbol.Integer:
            this.stack.Shift(new PdfInteger(this.lexer.TokenToInteger));
            break;

          case Symbol.UInteger:
            this.stack.Shift(new PdfUInteger(this.lexer.TokenToUInteger));
            break;

          case Symbol.Real:
            this.stack.Shift(new PdfReal(this.lexer.TokenToReal));
            break;

          case Symbol.String:
            //this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.PDFDocEncoding));
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.RawEncoding));
            break;

          case Symbol.UnicodeString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.Unicode));
            break;

          case Symbol.HexString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.HexLiteral));
            break;

          case Symbol.UnicodeHexString:
            this.stack.Shift(new PdfString(this.lexer.Token, PdfStringFlags.Unicode | PdfStringFlags.HexLiteral));
            break;

          case Symbol.Name:
            this.stack.Shift(new PdfName(this.lexer.Token));
            break;

          case Symbol.R:
            {
              Debug.Assert(this.stack.GetItem(-1) is PdfInteger && this.stack.GetItem(-2) is PdfInteger);
              PdfObjectID objectID = new PdfObjectID(this.stack.GetInteger(-2), this.stack.GetInteger(-1));

              PdfReference iref = this.document.irefTable[objectID];
              if (iref == null)
              {
                // If a document has more than one PdfXRefTable it is possible that the first trailer has
                // indirect references to objects whos iref entry is not yet read in.
                if (this.document.irefTable.IsUnderConstruction)
                {
                  // XRefTable not complete when trailer is read. Create temporary irefs that are
                  // removed later in PdfTrailer.FixXRefs.
                  iref = new PdfReference(objectID, 0);
                  this.stack.Reduce(iref, 2);
                  break;
                }
                // PDF Reference section 3.2.9:
                // An indirect reference to an undefined object is not an error;
                // it is simply treated as a reference to the null object.
                this.stack.Reduce(PdfNull.Value, 2);
                // Let's see what null objects are good for...
                //Debug.Assert(false, "Null object detected!");
                //this.stack.Reduce(PdfNull.Value, 2);
              }
              else
                this.stack.Reduce(iref, 2);
              break;
            }

          case Symbol.BeginArray:
            PdfArray array = new PdfArray(this.document);
            ReadArray(array, false);
            this.stack.Shift(array);
            break;

          case Symbol.BeginDictionary:
            PdfDictionary dict = new PdfDictionary(this.document);
            ReadDictionary(dict, false);
            this.stack.Shift(dict);
            break;

          case Symbol.BeginStream:
            throw new NotImplementedException();

          default:
            string error = this.lexer.Token;
            Debug.Assert(false, "Unexpected: " + error);
            break;
        }
      }
      throw new PdfReaderException("Unexpected end of file.");
    }
Example #16
0
    //    /// <summary>
    //    /// Reads a real value directly or (optionally) indirectly from the PDF data stream.
    //    /// </summary>
    //    double ReadReal(bool canBeIndirect)
    //    {
    //      Symbol symbol = this.lexer.ScanNextToken(canBeIndirect);
    //      if (symbol == Symbol.Real || symbol == Symbol.Integer)
    //        return this.lexer.TokenToReal;
    //      else if (symbol == Symbol.R)
    //      {
    //        int position = this.lexer.Position;
    ////        MoveToObject(this.lexer.Token);
    //        ReadObjectID(null);
    //        double f = ReadReal();
    //        ReadSymbol(Symbol.EndObj);
    //        this.lexer.Position = position;
    //        return f;
    //      }
    //      throw new PdfReaderException(PSSR.UnexpectedToken(this.lexer.Token));
    //    }
    //
    //    double ReadReal()
    //    {
    //      return ReadReal(false);
    //    }

    //    /// <summary>
    //    /// Reads an object from the PDF input stream. If the object has a specialized parser, it it used.
    //    /// </summary>
    //    public static PdfObject ReadObject(PdfObject pdfObject, PdfObjectID objectID)
    //    {
    //      if (pdfObject == null)
    //        throw new ArgumentNullException("pdfObject");
    //      if (pdfObject.Document == null)
    //        throw new ArgumentException(PSSR.OwningDocumentRequired, "pdfObject");
    //
    //      Type type = pdfObject.GetType();
    //      PdfParser parser = CreateParser(pdfObject.Document, type);
    //      return parser.ReadObject(pdfObject, objectID, false);
    //    }

    /// <summary>
    /// Reads an object from the PDF input stream using the default parser.
    /// </summary>
    public static PdfObject ReadObject(PdfDocument owner, PdfObjectID objectID)
    {
      if (owner == null)
        throw new ArgumentNullException("owner");

      Parser parser = new Parser(owner);
      return parser.ReadObject(null, objectID, false);
    }
Example #17
0
    /// <summary>
    /// Reads PDF object from input stream.
    /// </summary>
    /// <param name="pdfObject">Either the instance of a derived type or null. If it is null
    /// an appropriate object is created.</param>
    /// <param name="objectID">The address of the object.</param>
    /// <param name="includeReferences">If true, specifies that all indirect objects
    /// are included recursively.</param>
    public PdfObject ReadObject(PdfObject pdfObject, PdfObjectID objectID, bool includeReferences)
    {
      MoveToObject(objectID);
      int objectNumber = ReadInteger();
      int generationNumber = ReadInteger();
#if DEBUG
      // The following assertion sometime failed (see below)
      //Debug.Assert(objectID == new PdfObjectID(objectNumber, generationNumber));
      if (objectID != new PdfObjectID(objectNumber, generationNumber))
      {
        // A special kind of bug? Or is this an undocumented PDF feature?
        // PDF4NET 2.6 provides a sample called 'Unicode', which produces a file 'unicode.pdf'
        // The iref table of this file contains the following entries:
        //    iref
        //    0 148
        //    0000000000 65535 f 
        //    0000000015 00000 n 
        //    0000000346 00000 n 
        //    ....
        //    0000083236 00000 n 
        //    0000083045 00000 n 
        //    0000083045 00000 n 
        //    0000083045 00000 n 
        //    0000083045 00000 n 
        //    0000080334 00000 n 
        //    ....
        // Object 84, 85, 86, and 87 maps to the same dictionary, but all PDF readers I tested
        // ignores this mismatch! The following assertion failed about 50 times with this file.
#if true_
        string message = String.Format("xref entry {0} {1} maps to object {2} {3}.",
          objectID.ObjectNumber, objectID.GenerationNumber, objectNumber, generationNumber);
        Debug.Assert(false, message);
#endif
      }
#endif
      // Always use object ID from iref table (see above)
      objectNumber = objectID.ObjectNumber;
      generationNumber = objectID.GenerationNumber;
#if true_
      Debug.WriteLine(String.Format("obj: {0} {1}", objectNumber, generationNumber));
#endif
      ReadSymbol(Symbol.Obj);

      bool checkForStream = false;
      Symbol symbol = ScanNextToken();
      switch (symbol)
      {
        case Symbol.BeginArray:
          PdfArray array;
          if (pdfObject == null)
            array = new PdfArray(this.document);
          else
            array = (PdfArray)pdfObject;
          //PdfObject.RegisterObject(array, objectID, generation);
          pdfObject = ReadArray(array, includeReferences);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          break;

        case Symbol.BeginDictionary:
          PdfDictionary dict;
          if (pdfObject == null)
            dict = new PdfDictionary(this.document);
          else
            dict = (PdfDictionary)pdfObject;
          //PdfObject.RegisterObject(dict, objectID, generation);
          checkForStream = true;
          pdfObject = ReadDictionary(dict, includeReferences);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          break;

        // Acrobat 6 Professional proudly presents: The Null object!
        // Even with a one-digit object number an indirect reference «x 0 R» to this object is
        // one character larger than the direct use of «null». Probable this is the reason why
        // it is true that Acrobat Web Capture 6.0 creates this object, but obviously never 
        // creates a reference to it!
        case Symbol.Null:
          pdfObject = new PdfNullObject(this.document);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Boolean:
          pdfObject = new PdfBooleanObject(this.document, this.lexer.Token == Boolean.TrueString);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Integer:
          pdfObject = new PdfIntegerObject(this.document, this.lexer.TokenToInteger);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.UInteger:
          pdfObject = new PdfUIntegerObject(this.document, this.lexer.TokenToUInteger);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Real:
          pdfObject = new PdfRealObject(this.document, this.lexer.TokenToReal);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.String:
          pdfObject = new PdfStringObject(this.document, this.lexer.Token);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Name:
          pdfObject = new PdfNameObject(this.document, this.lexer.Token);
          pdfObject.SetObjectID(objectNumber, generationNumber);
          ReadSymbol(Symbol.EndObj);
          return pdfObject;

        case Symbol.Keyword:
          // Should not come here anymore
          throw new NotImplementedException("Keyword");

        default:
          // Should not come here anymore
          throw new NotImplementedException("unknown token");
      }
      symbol = ScanNextToken();
      if (symbol == Symbol.BeginStream)
      {
        PdfDictionary dict = (PdfDictionary)pdfObject;
        Debug.Assert(checkForStream, "Unexpected stream...");
        int length = GetStreamLength(dict);
        byte[] bytes = this.lexer.ReadStream(length);
#if true_
        if (dict.Elements.GetString("/Filter") == "/FlateDecode")
        {
          if (dict.Elements["/Subtype"] == null)
          {
            try
            {
              byte[] decoded = Filtering.FlateDecode.Decode(bytes);
              if (decoded.Length == 0)
                goto End;
              string pageContent = Filtering.FlateDecode.DecodeToString(bytes);
              if (pageContent.Length > 100)
                pageContent = pageContent.Substring(pageContent.Length - 100);
              pageContent.GetType();
              bytes = decoded;
              dict.Elements.Remove("/Filter");
              dict.Elements.SetInteger("/Length", bytes.Length);
            }
            catch
            {
            }
          }
        End:;
        }
#endif
        PdfDictionary.PdfStream stream = new PdfDictionary.PdfStream(bytes, dict);
        dict.Stream = stream;
        ReadSymbol(Symbol.EndStream);
        symbol = ScanNextToken();
      }
      if (symbol != Symbol.EndObj)
        throw new PdfReaderException(PSSR.UnexpectedToken(this.lexer.Token));
      return pdfObject;
    }
 /// <summary>
 /// Indicates whether the specified object identifier is in the table.
 /// </summary>
 public bool Contains(PdfObjectID objectID)
 {
     return(ObjectTable.ContainsKey(objectID));
 }
 /// <summary>
 /// Gets a cross reference entry from an object identifier.
 /// </summary>
 public PdfReference this[PdfObjectID objectID]
 {
   get { return (PdfReference)this.objectTable[objectID]; }
 }
    /// <summary>
    /// Set the hash key for the specified object.
    /// </summary>
    internal void SetHashKey(PdfObjectID id)
    {
#if !SILVERLIGHT
      byte[] objectId = new byte[5];
      this.md5.Initialize();
      // Split the object number and generation
      objectId[0] = (byte)id.ObjectNumber;
      objectId[1] = (byte)(id.ObjectNumber >> 8);
      objectId[2] = (byte)(id.ObjectNumber >> 16);
      objectId[3] = (byte)id.GenerationNumber;
      objectId[4] = (byte)(id.GenerationNumber >> 8);
      this.md5.TransformBlock(this.encryptionKey, 0, this.encryptionKey.Length, this.encryptionKey, 0);
      this.md5.TransformFinalBlock(objectId, 0, objectId.Length);
      this.key = this.md5.Hash;
      this.md5.Initialize();
      this.keySize = this.encryptionKey.Length + 5;
      if (this.keySize > 16)
        this.keySize = 16;
#endif
    }
Example #21
0
    /// <summary>
    /// Sets the object and generation number
    /// Setting the object identifier makes this object an indirect object, i.e. the object gets
    /// a PdfReference entry in the PdfReferenceTable.
    /// </summary>
    internal void SetObjectID(int objectNumber, int generationNumber)
    {
      PdfObjectID objectID = new PdfObjectID(objectNumber, generationNumber);

      // TODO: check imported
      if (this.iref == null)
        this.iref = this.document.irefTable[objectID];
      if (this.iref == null)
      {
        this.iref = new PdfReference(this);
        this.iref.ObjectID = objectID;
      }
      this.iref.Value = this;
      this.iref.Document = this.document;
    }