/// <summary>This is the last method to be called when using external signatures.</summary> /// <remarks> /// This is the last method to be called when using external signatures. The general sequence is: /// preClose(), getDocumentBytes() and close(). /// <p> /// update is a PdfDictionary that must have exactly the /// same keys as the ones provided in /// <see cref="PreClose(System.Collections.Generic.IDictionary{K, V})"/> /// . /// </remarks> /// <param name="update"> /// a PdfDictionary with the key/value that will fill the holes defined /// in /// <see cref="PreClose(System.Collections.Generic.IDictionary{K, V})"/> /// </param> /// <exception cref="System.IO.IOException">on error</exception> protected internal virtual void Close(PdfDictionary update) { try { if (!preClosed) { throw new PdfException(PdfException.DocumentMustBePreClosed); } MemoryStream bous = new MemoryStream(); PdfOutputStream os = new PdfOutputStream(bous); foreach (PdfName key in update.KeySet()) { PdfObject obj = update.Get(key); PdfLiteral lit = exclusionLocations.Get(key); if (lit == null) { throw new ArgumentException("The key didn't reserve space in preclose"); } bous.JReset(); os.Write(obj); if (bous.Length > lit.GetBytesCount()) { throw new ArgumentException("The key is too big"); } if (tempFile == null) { System.Array.Copy(bous.ToArray(), 0, bout, (int)lit.GetPosition(), bous.Length); } else { raf.Seek(lit.GetPosition()); raf.Write(bous.ToArray(), 0, (int)bous.Length); } } if (update.Size() != exclusionLocations.Count) { throw new ArgumentException("The update dictionary has less keys than required"); } if (tempFile == null) { originalOS.Write(bout, 0, bout.Length); } else { if (originalOS != null) { raf.Seek(0); long length = raf.Length; byte[] buf = new byte[8192]; while (length > 0) { int r = raf.JRead(buf, 0, (int)Math.Min((long)buf.Length, length)); if (r < 0) { throw new EndOfStreamException("unexpected eof"); } originalOS.Write(buf, 0, r); length -= r; } } } } finally { if (tempFile != null) { raf.Close(); if (originalOS != null) { tempFile.Delete(); } } if (originalOS != null) { try { originalOS.Close(); } catch (Exception) { } } } }