internal static String GetStreamWithValue(PdfObject @object) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfOutputStream stream = new PdfOutputStream(baos); stream.Write(@object); return("q\n" + "BT\n" + "/F1 12 Tf\n" + "36 787.96 Td\n" + iText.IO.Util.JavaUtil.GetStringForBytes(baos.ToArray ()) + " Tj\n" + "ET\n" + "Q"); }
/// <summary> /// Returns the resources needed for the object that was used to create /// this PdfResourceCounter. /// </summary> /// <remarks> /// Returns the resources needed for the object that was used to create /// this PdfResourceCounter. If you pass a Map with resources that were /// already used by other objects, these objects will not be taken into /// account. /// </remarks> /// <param name="res">The resources that can be excluded when counting the bytes.</param> /// <returns>The number of bytes needed for an object.</returns> public virtual long GetLength(IDictionary <int, PdfObject> res) { long length = 0; foreach (int @ref in resources.Keys) { if (res != null && res.ContainsKey(@ref)) { continue; } PdfOutputStream os = new PdfOutputStream(new IdelOutputStream()); os.Write(resources.Get(@ref).Clone()); length += os.GetCurrentPos(); } return(length); }
/// <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) { } } } }
/// <summary>This is the first method to be called when using external signatures.</summary> /// <remarks> /// This is the first method to be called when using external signatures. The general sequence is: /// preClose(), getDocumentBytes() and close(). /// <p> /// <CODE>exclusionSizes</CODE> must contain at least /// the <CODE>PdfName.CONTENTS</CODE> key with the size that it will take in the /// document. Note that due to the hex string coding this size should be byte_size*2+2. /// </remarks> /// <param name="exclusionSizes"> /// Map with names and sizes to be excluded in the signature /// calculation. The key is a PdfName and the value an Integer. At least the /Contents must be present /// </param> /// <exception cref="System.IO.IOException">on error</exception> protected internal virtual void PreClose(IDictionary <PdfName, int?> exclusionSizes) { if (preClosed) { throw new PdfException(PdfException.DocumentAlreadyPreClosed); } // TODO: add mergeVerification functionality preClosed = true; PdfAcroForm acroForm = PdfAcroForm.GetAcroForm(document, true); SignatureUtil sgnUtil = new SignatureUtil(document); String name = GetFieldName(); bool fieldExist = sgnUtil.DoesSignatureFieldExist(name); acroForm.SetSignatureFlags(PdfAcroForm.SIGNATURE_EXIST | PdfAcroForm.APPEND_ONLY); PdfSigFieldLockDictionary fieldLock = null; if (cryptoDictionary == null) { throw new PdfException(PdfException.NoCryptoDictionaryDefined); } cryptoDictionary.GetPdfObject().MakeIndirect(document); if (fieldExist) { PdfSignatureFormField sigField = (PdfSignatureFormField)acroForm.GetField(fieldName); sigField.Put(PdfName.V, cryptoDictionary.GetPdfObject()); fieldLock = sigField.GetSigFieldLockDictionary(); if (fieldLock == null && this.fieldLock != null) { this.fieldLock.GetPdfObject().MakeIndirect(document); sigField.Put(PdfName.Lock, this.fieldLock.GetPdfObject()); fieldLock = this.fieldLock; } sigField.Put(PdfName.P, document.GetPage(appearance.GetPageNumber()).GetPdfObject()); sigField.Put(PdfName.V, cryptoDictionary.GetPdfObject()); PdfObject obj = sigField.GetPdfObject().Get(PdfName.F); int flags = 0; if (obj != null && obj.IsNumber()) { flags = ((PdfNumber)obj).IntValue(); } flags |= PdfAnnotation.LOCKED; sigField.Put(PdfName.F, new PdfNumber(flags)); PdfDictionary ap = new PdfDictionary(); ap.Put(PdfName.N, appearance.GetAppearance().GetPdfObject()); sigField.Put(PdfName.AP, ap); sigField.SetModified(); } else { PdfWidgetAnnotation widget = new PdfWidgetAnnotation(appearance.GetPageRect()); widget.SetFlags(PdfAnnotation.PRINT | PdfAnnotation.LOCKED); PdfSignatureFormField sigField = PdfFormField.CreateSignature(document); sigField.SetFieldName(name); sigField.Put(PdfName.V, cryptoDictionary.GetPdfObject()); sigField.AddKid(widget); if (this.fieldLock != null) { this.fieldLock.GetPdfObject().MakeIndirect(document); sigField.Put(PdfName.Lock, this.fieldLock.GetPdfObject()); fieldLock = this.fieldLock; } int pagen = appearance.GetPageNumber(); widget.SetPage(document.GetPage(pagen)); PdfDictionary ap = widget.GetAppearanceDictionary(); if (ap == null) { ap = new PdfDictionary(); widget.Put(PdfName.AP, ap); } ap.Put(PdfName.N, appearance.GetAppearance().GetPdfObject()); acroForm.AddField(sigField, document.GetPage(pagen)); if (acroForm.GetPdfObject().IsIndirect()) { acroForm.SetModified(); } else { //Acroform dictionary is a Direct dictionary, //for proper flushing, catalog needs to be marked as modified document.GetCatalog().SetModified(); } } exclusionLocations = new Dictionary <PdfName, PdfLiteral>(); PdfLiteral lit = new PdfLiteral(80); exclusionLocations[PdfName.ByteRange] = lit; cryptoDictionary.Put(PdfName.ByteRange, lit); foreach (KeyValuePair <PdfName, int?> entry in exclusionSizes) { PdfName key = entry.Key; lit = new PdfLiteral((int)entry.Value); exclusionLocations[key] = lit; cryptoDictionary.Put(key, lit); } if (certificationLevel > 0) { AddDocMDP(cryptoDictionary); } if (fieldLock != null) { AddFieldMDP(cryptoDictionary, fieldLock); } if (signatureEvent != null) { signatureEvent.GetSignatureDictionary(cryptoDictionary); } if (certificationLevel > 0) { // add DocMDP entry to root PdfDictionary docmdp = new PdfDictionary(); docmdp.Put(PdfName.DocMDP, cryptoDictionary.GetPdfObject()); document.GetCatalog().Put(PdfName.Perms, docmdp); document.GetCatalog().SetModified(); } cryptoDictionary.GetPdfObject().Flush(false); document.Close(); range = new long[exclusionLocations.Count * 2]; long byteRangePosition = exclusionLocations.Get(PdfName.ByteRange).GetPosition(); exclusionLocations.JRemove(PdfName.ByteRange); int idx = 1; foreach (PdfLiteral lit1 in exclusionLocations.Values) { long n = lit1.GetPosition(); range[idx++] = n; range[idx++] = lit1.GetBytesCount() + n; } iText.IO.Util.JavaUtil.Sort(range, 1, range.Length - 1); for (int k = 3; k < range.Length - 2; k += 2) { range[k] -= range[k - 1]; } if (tempFile == null) { bout = temporaryOS.ToArray(); range[range.Length - 1] = bout.Length - range[range.Length - 2]; MemoryStream bos = new MemoryStream(); PdfOutputStream os = new PdfOutputStream(bos); os.Write('['); for (int k_1 = 0; k_1 < range.Length; ++k_1) { os.WriteLong(range[k_1]).Write(' '); } os.Write(']'); System.Array.Copy(bos.ToArray(), 0, bout, (int)byteRangePosition, bos.Length); } else { try { raf = FileUtil.GetRandomAccessFile(tempFile); long len = raf.Length; range[range.Length - 1] = len - range[range.Length - 2]; MemoryStream bos = new MemoryStream(); PdfOutputStream os = new PdfOutputStream(bos); os.Write('['); for (int k_1 = 0; k_1 < range.Length; ++k_1) { os.WriteLong(range[k_1]).Write(' '); } os.Write(']'); raf.Seek(byteRangePosition); raf.Write(bos.ToArray(), 0, (int)bos.Length); } catch (System.IO.IOException e) { try { raf.Close(); } catch (Exception) { } try { tempFile.Delete(); } catch (Exception) { } throw; } } }