FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const { if (this == pOther) return TRUE; if (!pOther) return FALSE; if (pOther->m_Type != m_Type) { if (IsReference() && GetDirect()) return GetDirect()->IsIdentical(pOther); if (pOther->IsReference()) return IsIdentical(pOther->GetDirect()); return FALSE; } switch (m_Type) { case PDFOBJ_BOOLEAN: return AsBoolean()->Identical(pOther->AsBoolean()); case PDFOBJ_NUMBER: return AsNumber()->Identical(pOther->AsNumber()); case PDFOBJ_STRING: return AsString()->Identical(pOther->AsString()); case PDFOBJ_NAME: return AsName()->Identical(pOther->AsName()); case PDFOBJ_ARRAY: return AsArray()->Identical(pOther->AsArray()); case PDFOBJ_DICTIONARY: return AsDictionary()->Identical(pOther->AsDictionary()); case PDFOBJ_NULL: return TRUE; case PDFOBJ_STREAM: return AsStream()->Identical(pOther->AsStream()); case PDFOBJ_REFERENCE: return AsReference()->Identical(pOther->AsReference()); } return FALSE; }
void Compare(const po::variables_map& variables, int& retcode) { retcode = 1; std::vector<std::wstring> inputs; if (variables.count("input")) inputs = variables["input"].as<std::vector<std::wstring>>(); if (inputs.size() != 2) { std::wcerr << L"Error parsing options: must have 2 input files." << std::endl; return; } auto out = OpenOutput<wchar_t>(variables); if (!out) return; bool fast = variables["fast"].as<bool>(); bool noHeuristics = variables["no-heuristics"].as<bool>(); bool verbose = variables["verbose"].as<bool>(); bool tlbTimestamp = variables["tlb-timestamp"].as<bool>(); BlockList ignoredRanges = boost::lexical_cast<BlockList>(variables["r"].as<std::wstring>()); BlockList ignoredRanges1 = boost::lexical_cast<BlockList>(variables["r1"].as<std::wstring>()); BlockList ignoredRanges2 = boost::lexical_cast<BlockList>(variables["r2"].as<std::wstring>()); PEParser pe1(inputs[0]); PEParser pe2(inputs[1]); pe1.AddIgnoredRange(ignoredRanges1); pe1.AddIgnoredRange(ignoredRanges); pe2.AddIgnoredRange(ignoredRanges2); pe2.AddIgnoredRange(ignoredRanges); pe1.Open(); pe2.Open(); *out << inputs[0] << L":\n\n" << pe1 << inputs[1] << L":\n\n" << pe2 << std::endl; auto result = PEParser::Compare(pe1, pe2, fast, noHeuristics, verbose, tlbTimestamp); *out << result << std::endl; bool success = false; bool identical = variables["identical"].as<bool>(); if (identical) success = result.IsIdentical(); else success = result.IsEquivalent(); retcode = (success) ? 0 : 1; }
FX_BOOL CPDF_Object::IsIdentical(CPDF_Object* pOther) const { if (this == pOther) { return TRUE; } if (pOther == NULL) { return FALSE; } if (pOther->m_Type != m_Type) { if (m_Type == PDFOBJ_REFERENCE && GetDirect()) { return GetDirect()->IsIdentical(pOther); } if (pOther->m_Type == PDFOBJ_REFERENCE) { return IsIdentical(pOther->GetDirect()); } return FALSE; } switch (m_Type) { case PDFOBJ_BOOLEAN: return (((CPDF_Boolean*)this)->Identical((CPDF_Boolean*)pOther)); case PDFOBJ_NUMBER: return (((CPDF_Number*)this)->Identical((CPDF_Number*)pOther)); case PDFOBJ_STRING: return (((CPDF_String*)this)->Identical((CPDF_String*)pOther)); case PDFOBJ_NAME: return (((CPDF_Name*)this)->Identical((CPDF_Name*)pOther)); case PDFOBJ_ARRAY: return (((CPDF_Array*)this)->Identical((CPDF_Array*)pOther)); case PDFOBJ_DICTIONARY: return (((CPDF_Dictionary*)this)->Identical((CPDF_Dictionary*)pOther)); case PDFOBJ_NULL: return TRUE; case PDFOBJ_STREAM: return (((CPDF_Stream*)this)->Identical((CPDF_Stream*)pOther)); case PDFOBJ_REFERENCE: return (((CPDF_Reference*)this)->Identical((CPDF_Reference*)pOther)); } return FALSE; }
bool IdenticalTo(Rule const & rhs) const override { auto const * r = dynamic_cast<OrRule const *>(&rhs); return r && IsIdentical(m_lhs, r->m_lhs) && IsIdentical(m_rhs, r->m_rhs); }