⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdfreader.cs

📁 pdf阅读器 用于阅读pdf格式的文件 方便 好用 免费的提供
💻 CS
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) 2004-2005, O&O Services GmbH.
// Am Borsigturm 48
// 13507 Berlin
// GERMANY
// Tel: +49 30 43 03 43-03, Fax: +49 30 43 03 43-99
// E-mail: info@oo-services.com
// Web: http://www.oo-services.com
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without 
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, 
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, 
//   this list of conditions and the following disclaimer in the documentation 
//   and/or other materials provided with the distribution.
// * Neither the name of O&O Services GmbH nor the names of its contributors 
//   may be used to endorse or promote products derived from this software
//   without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.Security.Permissions;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Runtime.CompilerServices;
using log4net;
using log4net.Config;

[assembly: CLSCompliant(true)]
[assembly: FileIOPermission(SecurityAction.RequestMinimum)]
[assembly: ComVisible(false)]
[assembly: AssemblyVersion("1.3.*")]

namespace OOGroup.Pdf
{
	/// <summary>
	/// Abstract base class for all PDF Objects.
	/// </summary>
	[CLSCompliant(true)]
	abstract public class PdfObject
	{
		private static readonly Regex boolRegex = new Regex(@"^((true)|(false))", RegexOptions.Singleline);
		private static readonly Regex nameRegex = new Regex(@"^(/[^\s()<>{}/%[\]]+)", RegexOptions.Singleline);
		private static readonly Regex stringRegex = new Regex(@"^(<|\()", RegexOptions.Singleline);
		private static readonly Regex arrayRegex = new Regex(@"^\[", RegexOptions.Singleline);
		private static readonly Regex nullRegex = new Regex(@"^null", RegexOptions.Singleline);
		private static readonly Regex referenceRegex = new Regex(@"^(\d+)\s+(\d+)\s+R", RegexOptions.Singleline);
		private static readonly Regex dictionaryRegex = new Regex(@"^<<", RegexOptions.Singleline);
		private static readonly Regex numberRegex = new Regex(@"^((-|\+)?\d*\.?\d*)", RegexOptions.Singleline);
		private static readonly Regex commentRegex = new Regex(@"^%([^\u000a\u000d]*)", RegexOptions.Singleline);
		
		private static readonly ILog log = LogManager.GetLogger(typeof(PdfObject));

		/// <summary>
		/// Factory method for PdfObjects. 
		/// Tries to parse a given input string into a new instance of PdfObject.
		/// </summary>
		/// <param name="input">The input string to be parsed. Will be consumed.</param>
		/// <returns>A PdfObject on success, null otherwise.</returns>
		public static PdfObject GetPdfObject(ref string input)
		{
			Match match;

			input = input.TrimStart(null); // remove white space from the start

			if (input.StartsWith("true"))
			{
				input = input.Substring(4);
				log.Info("Parsing PdfBool (true)");
				return new PdfBool(true);
			}
			else if (input.StartsWith("false"))
			{
				input = input.Substring(5);
				log.Info("Parsing PdfBool (false)");
				return new PdfBool(false);
			}
			if (input.StartsWith("/") && (match = nameRegex.Match(input)).Success)
			{
				input = input.Substring(match.Index + match.Length);
				log.Info("Parsing PdfName (" + match.Groups[1].Value + ")");
				return new PdfName(match.Groups[1].Value);
			}
			if (input.StartsWith("<<"))
			{
				input = input.Substring(2);
				log.Info("Parsing PdfDictionary");
				return new PdfDictionary(ref input);
			}
			if (input.Length > 0 && (input[0] == '<' || input[0] == '('))
			{
				bool hex = input[0] == '<';
				input = input.Substring(1);
				log.Info("Parsing PdfString (hex = " + hex + ")");
				return new PdfString(hex, ref input);
			}
			if (input.StartsWith("["))
			{
				input = input.Substring(1);
				log.Info("Parsing PdfArray");
				return new PdfArray(ref input);
			}
			if (input.StartsWith("null"))
			{
				input = input.Substring(4);
				log.Info("Parsing PdfNull");
				return new PdfNull();
			}
			match = referenceRegex.Match(input);
			if (match.Success)
			{
				input = input.Substring(match.Index + match.Length);
				int objNumber = Int32.Parse(match.Groups[1].Value, CultureInfo.InvariantCulture);
				int generationNumber = Int32.Parse(match.Groups[2].Value, CultureInfo.InvariantCulture);
				log.Info(string.Format(CultureInfo.InvariantCulture, "Parsing PdfReference ({0}, {1})", objNumber, generationNumber));
				return new PdfReference(objNumber, generationNumber);
			}
			match = numberRegex.Match(input);
			if (match.Success)
			{
				input = input.Substring(match.Index + match.Length);
				log.Info("Parsing PdfNumber (" + match.Groups[1].Value + ")");
				return new PdfNumber(match.Groups[1].Value);
			}

			PdfObject comment = ParseComment(ref input);
			if (comment != null)
			{
				log.Info("Parsing PdfComment");
				return comment;
			}

			throw new Exception("unable to parse '" + input + "'");
		}

		/// <summary>
		/// Tries to parse a PDF comment from the input string.
		/// </summary>
		/// <param name="input">The input string to be parsed. Will be consumed.</param>
		/// <returns>A PdfComment object on success, null otherwise.</returns>
		public static PdfComment ParseComment(ref string input)
		{
			Match match;

			match = commentRegex.Match(input);

			if (match.Success)
			{
				input = input.Substring(match.Index + match.Length);
				return new PdfComment(match.Groups[1].Value);
			}
			else
			{
				return null;
			}
		}
	}

	/// <summary>
	/// Represents a PDF Comment. See the PDF Reference 3.1.2 Comments.
	/// </summary>
	[CLSCompliant(true)]
	public class PdfComment: PdfObject
	{
		private string comment;

		/// <summary>
		/// Initializes a new instance of PdfComment.
		/// </summary>
		/// <param name="comment">The comment from which to initialize the object (without the leading '%' character and the trailing newline).</param>
		public PdfComment(string comment)
		{
			this.comment = comment;
		}

		/// <summary>
		/// Returns the string representation of the PdfComment object.
		/// </summary>
		/// <returns>The string representation of the PdfComment object.</returns>
		public override string ToString()
		{
			return "%" + Comment + "\n";
		}

		/// <summary>
		/// Gets or sets the value of this PdfComment object.
		/// </summary>
		public string Comment 
		{
			get
			{
				return comment;
			}

			set
			{
				comment = value;
			}
		}
	}

	/// <summary>
	/// Represents a PDF Numeric object. See the PDF Reference 3.2.2 Numeric Objects.
	/// </summary>
	[CLSCompliant(true)]
	public class PdfNumber: PdfObject
	{
		private double number = 0.0;
		private static readonly NumberFormatInfo numberFormat = new CultureInfo("en-US").NumberFormat;

		/// <summary>
		/// Initializes a new instance of PdfNumber.
		/// </summary>
		/// <param name="num">The string from which to parse the PdfNumber</param>
		public PdfNumber(string num)
		{
			number = 1000;//Double.Parse(num, numberFormat);
		}

		/// <summary>
		/// Initializes a new instance of PdfNumber.
		/// </summary>
		/// <param name="num">The number from which to initialize the PdfNumber.</param>
		public PdfNumber(double num)
		{
			number = num;
		}

		/// <summary>
		/// Returns the string representation of the PdfNumber object.
		/// </summary>
		/// <returns>The string representation of the PdfNumber object.</returns>
		public override string ToString()
		{
			return number.ToString(numberFormat);
		}

		/// <summary>
		/// Gets or sets the value of this PdfNumber object.
		/// </summary>
		public double Number
		{
			get
			{
				return number;
			}

			set
			{
				number = value;
			}
		}
	}

	/// <summary>
	/// Represents a PDF Dictionary object. See the PDF Reference 3.2.6 Dictionary Objects.
	/// </summary>
	[CLSCompliant(true)]
	public class PdfDictionary: PdfObject
	{
		private Hashtable dictionary = new Hashtable();
		private static readonly Regex endRegex = new Regex(@"^>>", RegexOptions.Singleline);
		private static readonly Regex keyRegex = new Regex(@"^(/[^\s()<>{}/%[\]]+)", RegexOptions.Singleline);

		/// <summary>
		/// Initializes a new instance of PdfDictionary.
		/// </summary>
		/// <param name="input">The input string from which to parse the PdfDictionary.
		/// Must not contain the leading "&lt;&lt;". Must contain the trailing "&gt;&gt;". 
		/// Consumes the PdfDictionary from the input.</param>
		public PdfDictionary(ref string input)
		{
			bool match;

			input = input.TrimStart(null);
			for (match = input.StartsWith(">>"); !match && input.Length > 0; match = input.StartsWith(">>"))
			{
				Match keyMatch = keyRegex.Match(input);
				if (keyMatch.Success)
				{
					input = input.Substring(keyMatch.Index + keyMatch.Length);
					dictionary.Add(new PdfName(keyMatch.Groups[1].Value), PdfObject.GetPdfObject(ref input));
				}
				else if (ParseComment(ref input) == null) // maybe there is a comment
				{
					throw new Exception("cannot parse PDF dictionary from '" + input + "'");
				}

				input = input.TrimStart(null);
			}

			if (match)
			{
				input = input.Substring(2);
			}
		}

		/// <summary>
		/// Initializes a new PdfDictionary object.
		/// </summary>
		/// <param name="dictionary">The Hashtable from which to initialize the PdfDictionary.</param>
		public PdfDictionary(Hashtable dictionary)
		{
			this.dictionary = dictionary;
		}

		/// <summary>
		/// Gets the Hashtable for the PdfDictionary.
		/// </summary>
		public Hashtable Dictionary
		{
			get
			{
				return dictionary;
			}
		}

		/// <summary>
		/// Returns the string representation of this PdfDictionary.
		/// </summary>
		/// <returns>The string representation of this PdfDictionary.</returns>
		public override string ToString()
		{
			string s = "<<\n";
			foreach (PdfName key in Dictionary.Keys)
			{
				s += key + " " + Dictionary[key] + "\n";
			}
			s += " >>";
			return s;
		}

		/// <summary>
		/// Sets an element in the PDF dictionary to the specified value.
		/// </summary>
		/// <remarks>
		/// If there is no element with the specified key in the dictionary, it will be added.
		/// </remarks>
		/// <param name="key">The key.</param>
		/// <param name="objValue">The value.</param>
		public void SetElement(PdfName key, PdfObject objValue)
		{
			if (Dictionary.ContainsKey(key))
			{
				Dictionary[key] = objValue;
			}
			else
			{
				Dictionary.Add(key, objValue);
			}
		}

		/// <summary>
		/// Returns the value in the PdfDictionary for the specified key.
		/// </summary>
		/// <param name="key">The key.</param>
		/// <returns>A PdfObject or null if there is no value in the PdfDictionary with the specified key.</returns>
		public PdfObject GetElement(PdfName key)
		{
			if (Dictionary.ContainsKey(key))
			{
				return (PdfObject)Dictionary[key];
			}
			else
			{
				return null;
			}
		}

		/// <summary>
		/// Indexer for the PdfDictionary.
		/// </summary>
		public PdfObject this [string key]
		{
			get
			{
				return GetElement(new PdfName(key));
			}

			set
			{
				SetElement(new PdfName(key), value);
			}
		}
	}
	
	/// <summary>
	/// Represents a PDF Reference object. See the PDF Reference 3.2.9 Indirect Objects.
	/// </summary>
	[CLSCompliant(true)]
	public class PdfReference: PdfObject
	{
		private int objNumber;
		private int generationNumber;

		/// <summary>
		/// Initializes a new PdfReference object.
		/// </summary>
		/// <param name="objNumber">The object number.</param>
		/// <param name="generationNumber">The generation number.</param>
		public PdfReference(int objNumber, int generationNumber)
		{
			this.objNumber = objNumber;
			this.generationNumber = generationNumber;
		}

		/// <summary>
		/// Returns the string representation of this object.
		/// </summary>
		/// <returns>"o g R" where o is the object number and g is the generation number.</returns>
		public override string ToString()
		{
			return objNumber.ToString(CultureInfo.InvariantCulture) + " " + generationNumber + " R";
		}

		/// <summary>
		/// Gets or sets a value indicating the object number.
		/// </summary>
		public int ObjectNumber
		{
			get
			{
				return objNumber;
			}

			set
			{
				objNumber = value;
			}
		}

		/// <summary>
		/// Gets or sets a value indicating the generation number.
		/// </summary>
		public int GenerationNumber
		{
			get
			{
				return generationNumber;
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -