Я использую PoDoFo для извлечения некоторых данных подписи из поля подписи.
Я искал много руководства, и я нашел этот кусок кода (не могу вспомнить статью, или я бы связал ее).
int getNumberOfSignatures(const PdfMemDocument &doc)
{
/// Find the document catalog dictionary
const PdfObject *const trailer = doc.GetTrailer();
if (!trailer->IsDictionary())
throw std::invalid_argument("Document invalid, non-dictionary trailer!");
const PdfObject *const catalogRef = trailer->GetDictionary().GetKey(PdfName("Root"));
if (catalogRef == 0 || !catalogRef->IsReference())
throw std::invalid_argument("Invalid /Root entry");
const PdfObject *const catalog = doc.GetObjects().GetObject(catalogRef->GetReference());
if (catalog == 0 || !catalog->IsDictionary())
throw std::invalid_argument("Invalid or non-dictionary referenced by / Root entry");
/// Find the Fields array in catalog dictionary
const PdfObject *acroFormValue = catalog->GetDictionary().GetKey(PdfName("AcroForm"));
if (acroFormValue == 0) return 0;
if (acroFormValue->IsReference())
acroFormValue = doc.GetObjects().GetObject(acroFormValue->GetReference());
if (!acroFormValue->IsDictionary()) return 0;
const PdfObject *fieldsValue =
acroFormValue->GetDictionary().GetKey(PdfName("Fields"));
if (fieldsValue == 0) return 0;
if (fieldsValue->IsReference())
fieldsValue = doc.GetObjects().GetObject(acroFormValue->GetReference());
if (!fieldsValue->IsArray()) return 0;
/// Verify if each object of the array is a signature field
int n = 0;
const PdfArray &array = fieldsValue->GetArray();
for (unsigned int i = 0; i < array.size(); i++) {
const PdfObject *const obj = doc.GetObjects().GetObject(array[i].GetReference());
if (isCustomSignatureField(doc, obj)) {
n++;
}
}
И функция, которая проверяет поле подписи, это
bool isSignatureField(const PdfMemDocument &doc, const PdfObject *const pObj)
{
if (pObj == 0) return false;
if (!pObj->IsDictionary()) return false;
const PdfObject *const keyFTValue = pObj->GetDictionary().GetKey(PdfName("FT"));
if (keyFTValue == 0) return false;
string value;
keyFTValue->ToString(value);
if (value != "/Sig") return false;
const PdfObject *const keyVValue = pObj->GetDictionary().GetKey(PdfName("V"));
if (keyVValue == 0) return false;
const PdfObject *const signature = doc.GetObjects().GetObject(keyVValue->GetReference());
if (signature->IsDictionary()) return true;
else return false;
}
Этот код работает правильно, но я должен улучшить его.
Когда я подписываю, я добавляю собственный словарь (я буду называть ilt Custom_Dic) в Словаре подписи (/ Sig dic), и теперь я должен восстановить его. Как я могу сделать? Я думаю, что мне не хватает логики.
bool isCustomSignatureField(const PdfMemDocument &doc, const PdfObject *const pObj)
{
if (pObj == 0) return false;
if (!pObj->IsDictionary()) return false;
const PdfObject *const keyFTValue = pObj->GetDictionary().GetKey(PdfName("FT"));
if (keyFTValue == 0) return false;
string value;
keyFTValue->ToString(value);
if (value != "/Sig") return false;
const PdfObject *const keyVValue = pObj->GetDictionary().GetKey(PdfName("V"));
if (keyVValue == 0) return false;
const PdfObject *const signature = doc.GetObjects().GetObject(keyVValue->GetReference());
if (!signature->IsDictionary()) return false;
const PdfObject *const keyAaValue = signature->GetDictionary().GetKey(PdfName("Custom_Dic"));
if (keyAValue == 0) return false;
cout << keyAValue;
const PdfObject *const signatureMetadata = doc.GetObjects().GetObject(keyAValue->GetReference());
if (signatureMetadata->IsDictionary()) return true;
else return false;
}
Эта функция возвращает мне исключение:
Необработанное исключение в 0x75154598 в TestLayer.exe: Microsoft C ++ исключение: PoDoFo :: PdfError в ячейке памяти 0x008BDCD4.
эта строка кода выводит мне значение, так что я думаю, что это не ноль
cout << keyValue;
Спасибо за совет.
Задача ещё не решена.