/** * Standard constructor * @param index the index * @param source the source * @param offset the offset of the source in the GroupedRandomAccessSource */ internal SourceEntry(int index, IRandomAccessSource source, long offset) { this.index = index; this.source = source; this.firstByte = offset; this.lastByte = offset + source.Length - 1; }
public IRandomAccessSource CreateRanged(IRandomAccessSource source, IList<long> ranges) { IRandomAccessSource[] sources = new IRandomAccessSource[ranges.Count/2]; for(int i = 0; i < ranges.Count; i+=2){ sources[i/2] = new WindowRandomAccessSource(source, ranges[i], ranges[i+1]); } return new GroupedRandomAccessSource(sources); }
virtual public void TestGetArray() { ArrayRandomAccessSource source1 = new ArrayRandomAccessSource(data); // 0 - 99 ArrayRandomAccessSource source2 = new ArrayRandomAccessSource(data); // 100 - 199 ArrayRandomAccessSource source3 = new ArrayRandomAccessSource(data); // 200 - 299 IRandomAccessSource[] inputs = new IRandomAccessSource[] { source1, source2, source3 }; GroupedRandomAccessSource grouped = new GroupedRandomAccessSource(inputs); byte[] output = new byte[500]; Assert.AreEqual(300, grouped.Get(0, output, 0, 300)); AssertArrayEqual(RangeArray(0, 100), 0, output, 0, 100); AssertArrayEqual(RangeArray(0, 100), 0, output, 100, 100); AssertArrayEqual(RangeArray(0, 100), 0, output, 200, 100); Assert.AreEqual(300, grouped.Get(0, output, 0, 301)); AssertArrayEqual(RangeArray(0, 100), 0, output, 0, 100); AssertArrayEqual(RangeArray(0, 100), 0, output, 100, 100); AssertArrayEqual(RangeArray(0, 100), 0, output, 200, 100); Assert.AreEqual(100, grouped.Get(150, output, 0, 100)); AssertArrayEqual(RangeArray(50, 50), 0, output, 0, 50); AssertArrayEqual(RangeArray(0, 50), 0, output, 50, 50); }
private void EnsureByteSourceIsThreadSafe() { if (!(byteSource is ThreadSafeRandomAccessSource)) { byteSource = new ThreadSafeRandomAccessSource(byteSource); } }
/// <summary>Constructs a new OffsetRandomAccessSource</summary> /// <param name="source">the source</param> public GetBufferedRandomAccessSource(IRandomAccessSource source) { this.source = source; this.getBuffer = new byte[(int)Math.Min(Math.Max(source.Length() / 4, 1), 4096)]; this.getBufferStart = -1; this.getBufferEnd = -1; }
virtual public void TestRelease() { ArrayRandomAccessSource source1 = new ArrayRandomAccessSource(data); // 0 - 99 ArrayRandomAccessSource source2 = new ArrayRandomAccessSource(data); // 100 - 199 ArrayRandomAccessSource source3 = new ArrayRandomAccessSource(data); // 200 - 299 IRandomAccessSource[] sources = new IRandomAccessSource[] { source1, source2, source3 }; GroupedRandomAccessSourceTestClass grouped = new GroupedRandomAccessSourceTestClass(sources); grouped.Get(250); grouped.Get(251); Assert.AreEqual(1, grouped.openCount[0]); grouped.Get(150); grouped.Get(151); Assert.AreEqual(1, grouped.openCount[0]); grouped.Get(50); grouped.Get(51); Assert.AreEqual(1, grouped.openCount[0]); grouped.Get(150); grouped.Get(151); Assert.AreEqual(1, grouped.openCount[0]); grouped.Get(250); grouped.Get(251); Assert.AreEqual(1, grouped.openCount[0]); grouped.Close(); }
/** * Constructs a new OffsetRandomAccessSource * @param source the source */ public GetBufferedRandomAccessSource(IRandomAccessSource source) { this.source = source; this.getBuffer = new byte[(int)Math.Min(Math.Max(source.Length/4, 1), (long)4096)]; this.getBufferStart = -1; this.getBufferEnd = -1; }
/// <exception cref="System.IO.IOException"/> public IRandomAccessSource CreateRanged(IRandomAccessSource source, long[] ranges) { IRandomAccessSource[] sources = new IRandomAccessSource[ranges.Length / 2]; for (int i = 0; i < ranges.Length; i += 2) { sources[i / 2] = new WindowRandomAccessSource(source, ranges[i], ranges[i + 1]); } return(new GroupedRandomAccessSource(sources)); }
protected internal override void SourceReleased(IRandomAccessSource source) { openCount[0]--; if (current[0] != source) { throw new AssertionException("Released source isn't the current source"); } current[0] = null; }
protected internal override void SourceInUse(IRandomAccessSource source) { if (current[0] != null) { throw new AssertionException("Current source wasn't released properly"); } openCount[0]++; current[0] = source; }
/// <summary>Signs a PDF where space was already reserved.</summary> /// <param name="document">the original PDF</param> /// <param name="fieldName">the field to sign. It must be the last field</param> /// <param name="outs">the output PDF</param> /// <param name="externalSignatureContainer"> /// the signature container doing the actual signing. Only the /// method ExternalSignatureContainer.sign is used /// </param> /// <exception cref="System.IO.IOException"/> /// <exception cref="Org.BouncyCastle.Security.GeneralSecurityException"/> public static void SignDeferred(PdfDocument document, String fieldName, Stream outs, IExternalSignatureContainer externalSignatureContainer) { SignatureUtil signatureUtil = new SignatureUtil(document); PdfDictionary v = signatureUtil.GetSignatureDictionary(fieldName); if (v == null) { throw new PdfException(PdfException.ThereIsNoFieldInTheDocumentWithSuchName1).SetMessageParams(fieldName); } if (!signatureUtil.SignatureCoversWholeDocument(fieldName)) { new PdfException(PdfException.SignatureWithName1IsNotTheLastItDoesntCoverWholeDocument).SetMessageParams(fieldName ); } PdfArray b = v.GetAsArray(PdfName.ByteRange); long[] gaps = SignatureUtil.AsLongArray(b); // TODO: refactor if (b.Size() != 4 || gaps[0] != 0) { throw new ArgumentException("Single exclusion space supported"); } IRandomAccessSource readerSource = document.GetReader().GetSafeFile().CreateSourceView(); Stream rg = new RASInputStream(new RandomAccessSourceFactory().CreateRanged(readerSource, gaps)); byte[] signedContent = externalSignatureContainer.Sign(rg); int spaceAvailable = (int)(gaps[2] - gaps[1]) - 2; if ((spaceAvailable & 1) != 0) { throw new ArgumentException("Gap is not a multiple of 2"); } spaceAvailable /= 2; if (spaceAvailable < signedContent.Length) { throw new PdfException(PdfException.AvailableSpaceIsNotEnoughForSignature); } StreamUtil.CopyBytes(readerSource, 0, gaps[1] + 1, outs); ByteBuffer bb = new ByteBuffer(spaceAvailable * 2); foreach (byte bi in signedContent) { bb.AppendHex(bi); } int remain = (spaceAvailable - signedContent.Length) * 2; for (int k = 0; k < remain; ++k) { bb.Append((byte)48); } byte[] bbArr = bb.ToByteArray(); outs.Write(bbArr); StreamUtil.CopyBytes(readerSource, gaps[2] - 1, gaps[3] + 1, outs); }
/** * Signs a PDF where space was already reserved. * @param reader the original PDF * @param fieldName the field to sign. It must be the last field * @param outs the output PDF * @param externalSignatureContainer the signature container doing the actual signing. Only the * method ExternalSignatureContainer.sign is used * @throws DocumentException * @throws IOException * @throws GeneralSecurityException */ public static void SignDeferred(PdfReader reader, String fieldName, Stream outs, IExternalSignatureContainer externalSignatureContainer) { AcroFields af = reader.AcroFields; PdfDictionary v = af.GetSignatureDictionary(fieldName); if (v == null) { throw new DocumentException("No field"); } if (!af.SignatureCoversWholeDocument(fieldName)) { throw new DocumentException("Not the last signature"); } PdfArray b = v.GetAsArray(PdfName.BYTERANGE); long[] gaps = b.AsLongArray(); if (b.Size != 4 || gaps[0] != 0) { throw new DocumentException("Single exclusion space supported"); } IRandomAccessSource readerSource = reader.SafeFile.CreateSourceView(); Stream rg = new RASInputStream(new RandomAccessSourceFactory().CreateRanged(readerSource, gaps)); byte[] signedContent = externalSignatureContainer.Sign(rg); int spaceAvailable = (int)(gaps[2] - gaps[1]) - 2; if ((spaceAvailable & 1) != 0) { throw new DocumentException("Gap is not a multiple of 2"); } spaceAvailable /= 2; if (spaceAvailable < signedContent.Length) { throw new DocumentException("Not enough space"); } StreamUtil.CopyBytes(readerSource, 0, gaps[1] + 1, outs); ByteBuffer bb = new ByteBuffer(spaceAvailable * 2); foreach (byte bi in signedContent) { bb.AppendHex(bi); } int remain = (spaceAvailable - signedContent.Length) * 2; for (int k = 0; k < remain; ++k) { bb.Append((byte)48); } bb.WriteTo(outs); StreamUtil.CopyBytes(readerSource, gaps[2] - 1, gaps[3] + 1, outs); }
public static void CopyBytes(IRandomAccessSource source, long start, long length, Stream outs) { if (length <= 0) return; long idx = start; byte[] buf = new byte[8192]; while (length > 0) { long n = source.Get(idx, buf,0, (int)Math.Min((long)buf.Length, length)); if (n <= 0) throw new EndOfStreamException(); outs.Write(buf, 0, (int)n); idx += n; length -= n; } }
public static void CopyBytes(IRandomAccessSource source, long start, long length, Stream outs) { if (length <= 0) { return; } long idx = start; byte[] buf = new byte[8192]; while (length > 0) { long n = source.Get(idx, buf, 0, (int)Math.Min((long)buf.Length, length)); if (n <= 0) { throw new EndOfStreamException(); } outs.Write(buf, 0, (int)n); idx += n; length -= n; } }
/** * Constructs a new OffsetRandomAccessSource that extends to the end of the underlying source * @param source the source * @param offset the amount of the offset to use */ public WindowRandomAccessSource(IRandomAccessSource source, long offset) : this(source, offset, source.Length - offset) { }
/// <summary>Constructs a new OffsetRandomAccessSource</summary> /// <param name="source">the source</param> public IndependentRandomAccessSource(IRandomAccessSource source) { this.source = source; }
// by default, do nothing /// <summary>Called when a given source is about to become the active source.</summary> /// <remarks>Called when a given source is about to become the active source. This gives subclasses the abilty to retrieve resources, if appropriate. /// </remarks> /// <param name="source">the source that is about to become the active source</param> protected internal virtual void SourceInUse(IRandomAccessSource source) { }
/** * Constructs a new PdfReader. This is the master constructor. */ private PdfReader(IRandomAccessSource byteSource, bool partialRead, byte[] ownerPassword, X509Certificate certificate, ICipherParameters certificateKey) { this.certificate = certificate; this.certificateKey = certificateKey; this.password = ownerPassword; this.partial = partialRead; tokens = GetOffsetTokeniser(byteSource); if (partialRead){ ReadPdfPartial(); } else { ReadPdf(); } }
/** * Called when a given source is about to become the active source. This gives subclasses the abilty to retrieve resources, if appropriate. * @param source the source that is about to become the active source * @throws IOException if there are any problems */ protected internal virtual void SourceInUse(IRandomAccessSource source) { // by default, do nothing }
/// <summary>Called when a given source is no longer the active source.</summary> /// <remarks>Called when a given source is no longer the active source. This gives subclasses the abilty to release resources, if appropriate. /// </remarks> /// <param name="source">the source that is no longer the active source</param> protected internal virtual void SourceReleased(IRandomAccessSource source) { }
virtual public void TestRelease() { ArrayRandomAccessSource source1 = new ArrayRandomAccessSource(data); // 0 - 99 ArrayRandomAccessSource source2 = new ArrayRandomAccessSource(data); // 100 - 199 ArrayRandomAccessSource source3 = new ArrayRandomAccessSource(data); // 200 - 299 IRandomAccessSource[] sources = new IRandomAccessSource[]{ source1, source2, source3 }; GroupedRandomAccessSourceTestClass grouped = new GroupedRandomAccessSourceTestClass(sources); grouped.Get(250); grouped.Get(251); Assert.AreEqual(1, grouped.openCount[0]); grouped.Get(150); grouped.Get(151); Assert.AreEqual(1, grouped.openCount[0]); grouped.Get(50); grouped.Get(51); Assert.AreEqual(1, grouped.openCount[0]); grouped.Get(150); grouped.Get(151); Assert.AreEqual(1, grouped.openCount[0]); grouped.Get(250); grouped.Get(251); Assert.AreEqual(1, grouped.openCount[0]); grouped.Close(); }
/** * Constructs a new OffsetRandomAccessSource * @param source the source */ public IndependentRandomAccessSource(IRandomAccessSource source) { this.source = source; }
public ThreadSafeRandomAccessSource(IRandomAccessSource source) { this.source = source; }
/// <summary>Creates an input stream based on the source.</summary> /// <param name="source">The source.</param> public RASInputStream(IRandomAccessSource source) { this.source = source; }
/** * Constructs a new PdfReader. This is the master constructor. * @param byteSource source of bytes for the reader * @param partialRead if true, the reader is opened in partial mode (PDF is parsed on demand), if false, the entire PDF is parsed into memory as the reader opens * @param ownerPassword the password or null if no password is required * @param certificate the certificate or null if no certificate is required * @param certificateKey the key or null if no certificate key is required * @param certificateKeyProvider the name of the key provider, or null if no key is required * @param closeSourceOnConstructorError if true, the byteSource will be closed if there is an error during construction of this reader */ private PdfReader(IRandomAccessSource byteSource, bool partialRead, byte[] ownerPassword, X509Certificate certificate, ICipherParameters certificateKey, bool closeSourceOnConstructorError) { this.certificate = certificate; this.certificateKey = certificateKey; this.password = ownerPassword; this.partial = partialRead; try { tokens = GetOffsetTokeniser(byteSource); if (partialRead) ReadPdfPartial(); else ReadPdf(); } catch (IOException e) { if (closeSourceOnConstructorError) byteSource.Close(); throw e; } GetCounter().Read(fileLength); }
/** * Utility method that checks the provided byte source to see if it has junk bytes at the beginning. If junk bytes * are found, construct a tokeniser that ignores the junk. Otherwise, construct a tokeniser for the byte source as it is * @param byteSource the source to check * @return a tokeniser that is guaranteed to start at the PDF header * @throws IOException if there is a problem reading the byte source */ private static PRTokeniser GetOffsetTokeniser(IRandomAccessSource byteSource) { PRTokeniser tok = new PRTokeniser(new RandomAccessFileOrArray(byteSource)); int offset = tok.GetHeaderOffset(); if (offset != 0){ IRandomAccessSource offsetSource = new WindowRandomAccessSource(byteSource, offset); tok = new PRTokeniser(new RandomAccessFileOrArray(offsetSource)); } return tok; }
/** * Constructs a new OffsetRandomAccessSource with an explicit length * @param source the source * @param offset the amount of the offset to use * @param length the number of bytes to be included in this RAS */ public WindowRandomAccessSource(IRandomAccessSource source, long offset, long length) { this.source = source; this.offset = offset; this.length = length; }
/** * Creates a RandomAccessFileOrArray that wraps the specified byte source. The byte source will be closed when * this RandomAccessFileOrArray is closed. * @param byteSource the byte source to wrap */ public RandomAccessFileOrArray(IRandomAccessSource byteSource){ this.byteSource = byteSource; }
/// <summary>Constructs a new OffsetRandomAccessSource with an explicit length</summary> /// <param name="source">the source</param> /// <param name="offset">the amount of the offset to use</param> /// <param name="length">the number of bytes to be included in this RAS</param> public WindowRandomAccessSource(IRandomAccessSource source, long offset, long length) { this.source = source; this.offset = offset; this.length = length; }
/// <exception cref="System.IO.IOException"/> public ContentsChecker(IRandomAccessSource byteSource) : base(byteSource, null) { }
/** * Creates an input stream based on the source * @param source the source */ public RASInputStream(IRandomAccessSource source) { this.source = source; }
/// <summary>Constructs a new OffsetRandomAccessSource that extends to the end of the underlying source</summary> /// <param name="source">the source</param> /// <param name="offset">the amount of the offset to use</param> public WindowRandomAccessSource(IRandomAccessSource source, long offset) : this(source, offset, source.Length() - offset) { }
protected internal override void SourceReleased(IRandomAccessSource source) { openCount[0]--; if (current[0] != source) throw new AssertionException("Released source isn't the current source"); current[0] = null; }
/** * Creates a RandomAccessFileOrArray that wraps the specified byte source. The byte source will be closed when * this RandomAccessFileOrArray is closed. * @param byteSource the byte source to wrap */ public RandomAccessFileOrArray(IRandomAccessSource byteSource) { this.byteSource = byteSource; }
protected internal override void SourceInUse(IRandomAccessSource source) { if (current[0] != null) throw new AssertionException("Current source wasn't released properly"); openCount[0]++; current[0] = source; }