mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 02:49:00 +00:00
Merge pull request #1179 from m-holger/null
In FUTURE, treat uninitialized object handles as null
This commit is contained in:
commit
8f54319f7a
@ -131,7 +131,7 @@ main(int argc, char* argv[])
|
||||
QPDFObjectHandle fileinfo;
|
||||
|
||||
for (auto const& it: Keys) {
|
||||
if (!fileinfo.isInitialized()) {
|
||||
if (!fileinfo) {
|
||||
if (filetrailer.hasKey("/Info")) {
|
||||
QTC::TC("examples", "pdf-mod-info has info");
|
||||
fileinfo = filetrailer.getKey("/Info");
|
||||
|
@ -295,8 +295,12 @@ class QPDFObjectHandle
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle& operator=(QPDFObjectHandle const&) = default;
|
||||
|
||||
// Return true if the QPDFObjectHandle is initialized. This allows object handles to be used in
|
||||
// if statements with initializer.
|
||||
QPDF_DLL
|
||||
inline bool isInitialized() const;
|
||||
explicit inline operator bool() const noexcept;
|
||||
|
||||
[[deprecated("use operator bool()")]] QPDF_DLL inline bool isInitialized() const;
|
||||
|
||||
// This method returns true if the QPDFObjectHandle objects point to exactly the same underlying
|
||||
// object, meaning that changes to one are reflected in the other, or "if you paint one, the
|
||||
@ -1634,5 +1638,10 @@ QPDFObjectHandle::isInitialized() const
|
||||
return obj != nullptr;
|
||||
}
|
||||
|
||||
inline QPDFObjectHandle::operator bool() const noexcept
|
||||
{
|
||||
return static_cast<bool>(obj);
|
||||
}
|
||||
|
||||
#endif // QPDF_FUTURE
|
||||
#endif // QPDFOBJECTHANDLE_HH
|
||||
|
@ -295,8 +295,12 @@ class QPDFObjectHandle
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle& operator=(QPDFObjectHandle&&) = default;
|
||||
|
||||
// Return true if the QPDFObjectHandle is initialized. This allows object handles to be used in
|
||||
// if statements with initializer.
|
||||
QPDF_DLL
|
||||
inline bool isInitialized() const noexcept;
|
||||
explicit inline operator bool() const noexcept;
|
||||
|
||||
[[deprecated("use operator bool()")]] QPDF_DLL inline bool isInitialized() const noexcept;
|
||||
|
||||
// This method returns true if the QPDFObjectHandle objects point to exactly the same underlying
|
||||
// object, meaning that changes to one are reflected in the other, or "if you paint one, the
|
||||
@ -1634,4 +1638,9 @@ QPDFObjectHandle::isInitialized() const noexcept
|
||||
return obj != nullptr;
|
||||
}
|
||||
|
||||
inline QPDFObjectHandle::operator bool() const noexcept
|
||||
{
|
||||
return static_cast<bool>(obj);
|
||||
}
|
||||
|
||||
#endif // QPDFOBJECTHANDLE_FUTURE_HH
|
||||
|
@ -188,7 +188,7 @@ NNTreeIterator::resetLimits(QPDFObjectHandle node, std::list<PathElement>::itera
|
||||
}
|
||||
}
|
||||
}
|
||||
if (first.isInitialized() && last.isInitialized()) {
|
||||
if (first && last) {
|
||||
auto limits = QPDFObjectHandle::newArray();
|
||||
limits.appendItem(first);
|
||||
limits.appendItem(last);
|
||||
|
@ -526,7 +526,7 @@ QPDF::warn(
|
||||
void
|
||||
QPDF::setTrailer(QPDFObjectHandle obj)
|
||||
{
|
||||
if (m->trailer.isInitialized()) {
|
||||
if (m->trailer) {
|
||||
return;
|
||||
}
|
||||
m->trailer = obj;
|
||||
@ -591,7 +591,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
|
||||
}
|
||||
}
|
||||
m->file->seek(pos, SEEK_SET);
|
||||
} else if (!m->trailer.isInitialized() && t1.isWord("trailer")) {
|
||||
} else if (!m->trailer && t1.isWord("trailer")) {
|
||||
auto pos = m->file->tell();
|
||||
QPDFObjectHandle t = readTrailer();
|
||||
if (!t.isDictionary()) {
|
||||
@ -606,7 +606,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
|
||||
}
|
||||
m->deleted_objects.clear();
|
||||
|
||||
if (!m->trailer.isInitialized()) {
|
||||
if (!m->trailer) {
|
||||
qpdf_offset_t max_offset{0};
|
||||
// If there are any xref streams, take the last one to appear.
|
||||
for (auto const& iter: m->xref_table) {
|
||||
@ -640,7 +640,7 @@ QPDF::reconstruct_xref(QPDFExc& e)
|
||||
}
|
||||
}
|
||||
|
||||
if (!m->trailer.isInitialized()) {
|
||||
if (!m->trailer) {
|
||||
// We could check the last encountered object to see if it was an xref stream. If so, we
|
||||
// could try to get the trailer from there. This may make it possible to recover files with
|
||||
// bad startxref pointers even when they have object streams.
|
||||
@ -730,7 +730,7 @@ QPDF::read_xref(qpdf_offset_t xref_offset)
|
||||
}
|
||||
}
|
||||
|
||||
if (!m->trailer.isInitialized()) {
|
||||
if (!m->trailer) {
|
||||
throw damagedPDF("", 0, "unable to find trailer while reading xref");
|
||||
}
|
||||
int size = m->trailer.getKey("/Size").getIntValueAsInt();
|
||||
@ -1000,7 +1000,7 @@ QPDF::read_xrefTable(qpdf_offset_t xref_offset)
|
||||
throw damagedPDF("", "expected trailer dictionary");
|
||||
}
|
||||
|
||||
if (!m->trailer.isInitialized()) {
|
||||
if (!m->trailer) {
|
||||
setTrailer(cur_trailer);
|
||||
|
||||
if (!m->trailer.hasKey("/Size")) {
|
||||
@ -1258,7 +1258,7 @@ QPDF::processXRefStream(qpdf_offset_t xref_offset, QPDFObjectHandle& xref_obj)
|
||||
}
|
||||
}
|
||||
|
||||
if (!m->trailer.isInitialized()) {
|
||||
if (!m->trailer) {
|
||||
setTrailer(dict);
|
||||
}
|
||||
|
||||
@ -2052,7 +2052,7 @@ QPDF::makeIndirectFromQPDFObject(std::shared_ptr<QPDFObject> const& obj)
|
||||
QPDFObjectHandle
|
||||
QPDF::makeIndirectObject(QPDFObjectHandle oh)
|
||||
{
|
||||
if (!oh.isInitialized()) {
|
||||
if (!oh) {
|
||||
throw std::logic_error("attempted to make an uninitialized QPDFObjectHandle indirect");
|
||||
}
|
||||
return makeIndirectFromQPDFObject(oh.getObj());
|
||||
@ -2163,7 +2163,7 @@ QPDF::replaceObject(int objid, int generation, QPDFObjectHandle oh)
|
||||
void
|
||||
QPDF::replaceObject(QPDFObjGen const& og, QPDFObjectHandle oh)
|
||||
{
|
||||
if (!oh.isInitialized() || (oh.isIndirect() && !(oh.isStream() && oh.getObjGen() == og))) {
|
||||
if (!oh || (oh.isIndirect() && !(oh.isStream() && oh.getObjGen() == og))) {
|
||||
QTC::TC("qpdf", "QPDF replaceObject called with indirect object");
|
||||
throw std::logic_error("QPDF::replaceObject called with indirect object handle");
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ QPDFFormFieldObjectHelper::setRadioButtonValue(QPDFObjectHandle name)
|
||||
} else {
|
||||
annot = kid;
|
||||
}
|
||||
if (!annot.isInitialized()) {
|
||||
if (!annot) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle broken radio button");
|
||||
this->oh.warnIfPossible("unable to set the value of this radio button");
|
||||
continue;
|
||||
@ -459,7 +459,7 @@ QPDFFormFieldObjectHelper::setCheckBoxValue(bool value)
|
||||
// Set /AS to the on value or /Off in addition to setting /V.
|
||||
QPDFObjectHandle name = QPDFObjectHandle::newName(value ? on_value : "/Off");
|
||||
setFieldAttribute("/V", name);
|
||||
if (!annot.isInitialized()) {
|
||||
if (!annot) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle broken checkbox");
|
||||
this->oh.warnIfPossible("unable to set the value of this checkbox");
|
||||
return;
|
||||
@ -815,7 +815,7 @@ QPDFFormFieldObjectHelper::generateTextAppearance(QPDFAnnotationObjectHelper& ao
|
||||
QPDFObjectHandle resources = AS.getDict().getKey("/Resources");
|
||||
QPDFObjectHandle font = getFontFromResource(resources, font_name);
|
||||
bool found_font_in_dr = false;
|
||||
if (!font.isInitialized()) {
|
||||
if (!font) {
|
||||
QPDFObjectHandle dr = getDefaultResources();
|
||||
font = getFontFromResource(dr, font_name);
|
||||
found_font_in_dr = font.isDictionary();
|
||||
|
@ -1021,8 +1021,9 @@ QPDFObjectHandle::getArrayItem(int n) const
|
||||
#endif
|
||||
{
|
||||
if (auto array = asArray()) {
|
||||
if (auto result = array->at(n); result.obj != nullptr) {
|
||||
return result;
|
||||
auto result = array->at(n);
|
||||
if (result.first) {
|
||||
return result.second;
|
||||
} else {
|
||||
objectWarning("returning null for out of bounds array access");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle array bounds");
|
||||
@ -1045,7 +1046,7 @@ QPDFObjectHandle::isRectangle() const
|
||||
{
|
||||
if (auto array = asArray()) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (auto item = array->at(i); !(item.obj && item.isNumber())) {
|
||||
if (auto item = array->at(i).second; !item.isNumber()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1064,7 +1065,7 @@ QPDFObjectHandle::isMatrix() const
|
||||
{
|
||||
if (auto array = asArray()) {
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (auto item = array->at(i); !(item.obj && item.isNumber())) {
|
||||
if (auto item = array->at(i).second; !item.isNumber()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1087,7 +1088,7 @@ QPDFObjectHandle::getArrayAsRectangle() const
|
||||
}
|
||||
double items[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (!array->at(i).getValueAsNumber(items[i])) {
|
||||
if (auto item = array->at(i).second; !item.getValueAsNumber(items[i])) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@ -1114,7 +1115,7 @@ QPDFObjectHandle::getArrayAsMatrix() const
|
||||
}
|
||||
double items[6];
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (!array->at(i).getValueAsNumber(items[i])) {
|
||||
if (auto item = array->at(i).second; !item.getValueAsNumber(items[i])) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@ -1224,7 +1225,7 @@ QPDFObjectHandle
|
||||
QPDFObjectHandle::eraseItemAndGetOld(int at)
|
||||
{
|
||||
auto array = asArray();
|
||||
auto result = (array && at < array->size() && at >= 0) ? array->at(at) : newNull();
|
||||
auto result = (array && at < array->size() && at >= 0) ? array->at(at).second : newNull();
|
||||
eraseItem(at);
|
||||
return result;
|
||||
}
|
||||
@ -1764,7 +1765,7 @@ QPDFObjectHandle::arrayOrStreamToStreamArray(
|
||||
if (auto array = asArray()) {
|
||||
int n_items = array->size();
|
||||
for (int i = 0; i < n_items; ++i) {
|
||||
QPDFObjectHandle item = array->at(i);
|
||||
QPDFObjectHandle item = array->at(i).second;
|
||||
if (item.isStream()) {
|
||||
result.push_back(item);
|
||||
} else {
|
||||
@ -2165,7 +2166,7 @@ QPDFObjectHandle::parseContentStream_data(
|
||||
input->seek(offset, SEEK_SET);
|
||||
auto obj =
|
||||
QPDFParser(*input, "content", tokenizer, nullptr, context, false).parse(empty, true);
|
||||
if (!obj.isInitialized()) {
|
||||
if (!obj) {
|
||||
// EOF
|
||||
break;
|
||||
}
|
||||
@ -2465,7 +2466,7 @@ QPDFObjectHandle::makeDirect(QPDFObjGen::set& visited, bool stop_at_streams)
|
||||
auto array = asArray();
|
||||
int n = array->size();
|
||||
for (int i = 0; i < n; ++i) {
|
||||
items.push_back(array->at(i));
|
||||
items.push_back(array->at(i).second);
|
||||
items.back().makeDirect(visited, stop_at_streams);
|
||||
}
|
||||
this->obj = QPDF_Array::create(items);
|
||||
@ -2520,7 +2521,7 @@ QPDFObjectHandle::makeDirect(bool allow_streams)
|
||||
void
|
||||
QPDFObjectHandle::assertInitialized() const
|
||||
{
|
||||
if (!isInitialized()) {
|
||||
if (!obj) {
|
||||
throw std::logic_error("operation attempted on uninitialized QPDFObjectHandle");
|
||||
}
|
||||
}
|
||||
@ -3018,34 +3019,30 @@ QPDFObjectHandle::QPDFArrayItems::end()
|
||||
QPDFObjGen
|
||||
QPDFObjectHandle::getObjGen() const
|
||||
{
|
||||
return isInitialized() ? obj->getObjGen() : QPDFObjGen();
|
||||
return obj ? obj->getObjGen() : QPDFObjGen();
|
||||
}
|
||||
|
||||
// Indirect object accessors
|
||||
QPDF*
|
||||
QPDFObjectHandle::getOwningQPDF() const
|
||||
{
|
||||
return isInitialized() ? this->obj->getQPDF() : nullptr;
|
||||
return obj ? obj->getQPDF() : nullptr;
|
||||
}
|
||||
|
||||
QPDF&
|
||||
QPDFObjectHandle::getQPDF(std::string const& error_msg) const
|
||||
{
|
||||
auto result = isInitialized() ? this->obj->getQPDF() : nullptr;
|
||||
if (result == nullptr) {
|
||||
throw std::runtime_error(
|
||||
error_msg.empty() ? "attempt to use a null qpdf object" : error_msg);
|
||||
if (auto result = obj ? obj->getQPDF() : nullptr) {
|
||||
return *result;
|
||||
}
|
||||
return *result;
|
||||
throw std::runtime_error(error_msg.empty() ? "attempt to use a null qpdf object" : error_msg);
|
||||
}
|
||||
|
||||
void
|
||||
QPDFObjectHandle::setParsedOffset(qpdf_offset_t offset)
|
||||
{
|
||||
// This is called during parsing on newly created direct objects,
|
||||
// so we can't call dereference() here.
|
||||
if (isInitialized()) {
|
||||
this->obj->setParsedOffset(offset);
|
||||
if (obj) {
|
||||
obj->setParsedOffset(offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name)
|
||||
{
|
||||
QPDFObjectHandle result;
|
||||
if (name.isName()) {
|
||||
if (!m->dest_dict.isInitialized()) {
|
||||
if (!m->dest_dict) {
|
||||
m->dest_dict = qpdf.getRoot().getKey("/Dests");
|
||||
}
|
||||
QTC::TC("qpdf", "QPDFOutlineDocumentHelper name named dest");
|
||||
@ -85,7 +85,7 @@ QPDFOutlineDocumentHelper::resolveNamedDest(QPDFObjectHandle name)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result.isInitialized()) {
|
||||
if (!result) {
|
||||
return QPDFObjectHandle::newNull();
|
||||
}
|
||||
if (result.isDictionary()) {
|
||||
|
@ -59,8 +59,8 @@ QPDFOutlineObjectHelper::getDest()
|
||||
QTC::TC("qpdf", "QPDFOutlineObjectHelper action dest");
|
||||
dest = A.getKey("/D");
|
||||
}
|
||||
if (!dest.isInitialized()) {
|
||||
dest = QPDFObjectHandle::newNull();
|
||||
if (!dest) {
|
||||
return QPDFObjectHandle::newNull();
|
||||
}
|
||||
|
||||
if (dest.isName() || dest.isString()) {
|
||||
|
@ -1381,7 +1381,7 @@ QPDFWriter::unparseObject(
|
||||
}
|
||||
}
|
||||
|
||||
if (extensions.isInitialized()) {
|
||||
if (extensions) {
|
||||
std::set<std::string> keys = extensions.getKeys();
|
||||
if (keys.count("/ADBE") > 0) {
|
||||
have_extensions_adbe = true;
|
||||
@ -1412,7 +1412,7 @@ QPDFWriter::unparseObject(
|
||||
}
|
||||
}
|
||||
|
||||
if (extensions.isInitialized()) {
|
||||
if (extensions) {
|
||||
QTC::TC("qpdf", "QPDFWriter preserve Extensions");
|
||||
QPDFObjectHandle adbe = extensions.getKey("/ADBE");
|
||||
if (adbe.isDictionary() &&
|
||||
|
@ -184,16 +184,16 @@ QPDF_Array::writeJSON(int json_version, JSON::Writer& p)
|
||||
p.writeEnd(']');
|
||||
}
|
||||
|
||||
QPDFObjectHandle
|
||||
std::pair<bool, QPDFObjectHandle>
|
||||
QPDF_Array::at(int n) const noexcept
|
||||
{
|
||||
if (n < 0 || n >= size()) {
|
||||
return {};
|
||||
return {false, {}};
|
||||
} else if (sp) {
|
||||
auto const& iter = sp->elements.find(n);
|
||||
return iter == sp->elements.end() ? null_oh : (*iter).second;
|
||||
return {true, iter == sp->elements.end() ? null_oh : (*iter).second};
|
||||
} else {
|
||||
return elements[size_t(n)];
|
||||
return {true, elements[size_t(n)]};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -661,18 +661,17 @@ void
|
||||
QPDF_Stream::replaceFilterData(
|
||||
QPDFObjectHandle const& filter, QPDFObjectHandle const& decode_parms, size_t length)
|
||||
{
|
||||
if (filter.isInitialized()) {
|
||||
this->stream_dict.replaceKey("/Filter", filter);
|
||||
if (filter) {
|
||||
stream_dict.replaceKey("/Filter", filter);
|
||||
}
|
||||
if (decode_parms.isInitialized()) {
|
||||
this->stream_dict.replaceKey("/DecodeParms", decode_parms);
|
||||
if (decode_parms) {
|
||||
stream_dict.replaceKey("/DecodeParms", decode_parms);
|
||||
}
|
||||
if (length == 0) {
|
||||
QTC::TC("qpdf", "QPDF_Stream unknown stream length");
|
||||
this->stream_dict.removeKey("/Length");
|
||||
stream_dict.removeKey("/Length");
|
||||
} else {
|
||||
this->stream_dict.replaceKey(
|
||||
"/Length", QPDFObjectHandle::newInteger(QIntC::to_longlong(length)));
|
||||
stream_dict.replaceKey("/Length", QPDFObjectHandle::newInteger(QIntC::to_longlong(length)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,7 +325,7 @@ QPDF::JSONReactor::anyErrors() const
|
||||
void
|
||||
QPDF::JSONReactor::containerStart()
|
||||
{
|
||||
if (next_obj.isInitialized()) {
|
||||
if (next_obj) {
|
||||
stack.emplace_back(next_state, std::move(next_obj));
|
||||
next_obj = QPDFObjectHandle();
|
||||
} else {
|
||||
@ -558,7 +558,7 @@ QPDF::JSONReactor::dictionaryItem(std::string const& key, JSON const& value)
|
||||
throw std::logic_error("stack empty in st_object_top");
|
||||
}
|
||||
auto& tos = stack.back();
|
||||
if (!tos.object.isInitialized()) {
|
||||
if (!tos.object) {
|
||||
throw std::logic_error("current object uninitialized in st_object_top");
|
||||
}
|
||||
if (key == "value") {
|
||||
@ -767,7 +767,7 @@ QPDF::JSONReactor::makeObject(JSON const& value)
|
||||
result = QPDFObjectHandle::newNull();
|
||||
}
|
||||
}
|
||||
if (!result.isInitialized()) {
|
||||
if (!result) {
|
||||
throw std::logic_error("JSONReactor::makeObject didn't initialize the object");
|
||||
}
|
||||
|
||||
|
@ -955,7 +955,7 @@ qpdf_oh_is_initialized(qpdf_data qpdf, qpdf_oh oh)
|
||||
{
|
||||
QTC::TC("qpdf", "qpdf-c called qpdf_oh_is_initialized");
|
||||
return do_with_oh<QPDF_BOOL>(
|
||||
qpdf, oh, return_false, [](QPDFObjectHandle& o) { return o.isInitialized(); });
|
||||
qpdf, oh, return_false, [](QPDFObjectHandle& o) { return static_cast<bool>(o); });
|
||||
}
|
||||
|
||||
QPDF_BOOL
|
||||
|
@ -30,7 +30,7 @@ class QPDF_Array: public QPDFValue
|
||||
{
|
||||
return sp ? sp->size : int(elements.size());
|
||||
}
|
||||
QPDFObjectHandle at(int n) const noexcept;
|
||||
std::pair<bool, QPDFObjectHandle> at(int n) const noexcept;
|
||||
bool setAt(int n, QPDFObjectHandle const& oh);
|
||||
std::vector<QPDFObjectHandle> getAsVector() const;
|
||||
void setFromVector(std::vector<QPDFObjectHandle> const& items);
|
||||
|
@ -21,69 +21,69 @@ main()
|
||||
a.push_back(QPDFObjectHandle::parse("null"));
|
||||
a.push_back(QPDFObjectHandle::parse("/Quack"));
|
||||
assert(a.size() == 5);
|
||||
assert(a.at(0).isInteger() && (a.at(0).getIntValue() == 1));
|
||||
assert(a.at(1).isString() && (a.at(1).getStringValue() == "potato"));
|
||||
assert(a.at(2).isNull());
|
||||
assert(a.at(3).isNull());
|
||||
assert(a.at(4).isName() && (a.at(4).getName() == "/Quack"));
|
||||
assert(a.at(0).second.isInteger() && (a.at(0).second.getIntValue() == 1));
|
||||
assert(a.at(1).second.isString() && (a.at(1).second.getStringValue() == "potato"));
|
||||
assert(a.at(2).second.isNull());
|
||||
assert(a.at(3).second.isNull());
|
||||
assert(a.at(4).second.isName() && (a.at(4).second.getName() == "/Quack"));
|
||||
|
||||
a.insert(4, QPDFObjectHandle::parse("/BeforeQuack"));
|
||||
assert(a.size() == 6);
|
||||
assert(a.at(0).isInteger() && (a.at(0).getIntValue() == 1));
|
||||
assert(a.at(4).isName() && (a.at(4).getName() == "/BeforeQuack"));
|
||||
assert(a.at(5).isName() && (a.at(5).getName() == "/Quack"));
|
||||
assert(a.at(0).second.isInteger() && (a.at(0).second.getIntValue() == 1));
|
||||
assert(a.at(4).second.isName() && (a.at(4).second.getName() == "/BeforeQuack"));
|
||||
assert(a.at(5).second.isName() && (a.at(5).second.getName() == "/Quack"));
|
||||
|
||||
a.insert(2, QPDFObjectHandle::parse("/Third"));
|
||||
assert(a.size() == 7);
|
||||
assert(a.at(1).isString() && (a.at(1).getStringValue() == "potato"));
|
||||
assert(a.at(2).isName() && (a.at(2).getName() == "/Third"));
|
||||
assert(a.at(3).isNull());
|
||||
assert(a.at(6).isName() && (a.at(6).getName() == "/Quack"));
|
||||
assert(a.at(1).second.isString() && (a.at(1).second.getStringValue() == "potato"));
|
||||
assert(a.at(2).second.isName() && (a.at(2).second.getName() == "/Third"));
|
||||
assert(a.at(3).second.isNull());
|
||||
assert(a.at(6).second.isName() && (a.at(6).second.getName() == "/Quack"));
|
||||
|
||||
a.insert(0, QPDFObjectHandle::parse("/First"));
|
||||
assert(a.size() == 8);
|
||||
assert(a.at(0).isName() && (a.at(0).getName() == "/First"));
|
||||
assert(a.at(1).isInteger() && (a.at(1).getIntValue() == 1));
|
||||
assert(a.at(7).isName() && (a.at(7).getName() == "/Quack"));
|
||||
assert(a.at(0).second.isName() && (a.at(0).second.getName() == "/First"));
|
||||
assert(a.at(1).second.isInteger() && (a.at(1).second.getIntValue() == 1));
|
||||
assert(a.at(7).second.isName() && (a.at(7).second.getName() == "/Quack"));
|
||||
|
||||
a.erase(6);
|
||||
assert(a.size() == 7);
|
||||
assert(a.at(0).isName() && (a.at(0).getName() == "/First"));
|
||||
assert(a.at(1).isInteger() && (a.at(1).getIntValue() == 1));
|
||||
assert(a.at(5).isNull());
|
||||
assert(a.at(6).isName() && (a.at(6).getName() == "/Quack"));
|
||||
assert(a.at(0).second.isName() && (a.at(0).second.getName() == "/First"));
|
||||
assert(a.at(1).second.isInteger() && (a.at(1).second.getIntValue() == 1));
|
||||
assert(a.at(5).second.isNull());
|
||||
assert(a.at(6).second.isName() && (a.at(6).second.getName() == "/Quack"));
|
||||
|
||||
a.erase(6);
|
||||
assert(a.size() == 6);
|
||||
assert(a.at(0).isName() && (a.at(0).getName() == "/First"));
|
||||
assert(a.at(1).isInteger() && (a.at(1).getIntValue() == 1));
|
||||
assert(a.at(3).isName() && (a.at(3).getName() == "/Third"));
|
||||
assert(a.at(4).isNull());
|
||||
assert(a.at(5).isNull());
|
||||
assert(a.at(0).second.isName() && (a.at(0).second.getName() == "/First"));
|
||||
assert(a.at(1).second.isInteger() && (a.at(1).second.getIntValue() == 1));
|
||||
assert(a.at(3).second.isName() && (a.at(3).second.getName() == "/Third"));
|
||||
assert(a.at(4).second.isNull());
|
||||
assert(a.at(5).second.isNull());
|
||||
|
||||
a.setAt(4, QPDFObjectHandle::parse("12"));
|
||||
assert(a.at(4).isInteger() && (a.at(4).getIntValue() == 12));
|
||||
assert(a.at(4).second.isInteger() && (a.at(4).second.getIntValue() == 12));
|
||||
a.setAt(4, QPDFObjectHandle::newNull());
|
||||
assert(a.at(4).isNull());
|
||||
assert(a.at(4).second.isNull());
|
||||
|
||||
a.erase(a.size() - 1);
|
||||
assert(a.size() == 5);
|
||||
assert(a.at(0).isName() && (a.at(0).getName() == "/First"));
|
||||
assert(a.at(1).isInteger() && (a.at(1).getIntValue() == 1));
|
||||
assert(a.at(3).isName() && (a.at(3).getName() == "/Third"));
|
||||
assert(a.at(4).isNull());
|
||||
assert(a.at(0).second.isName() && (a.at(0).second.getName() == "/First"));
|
||||
assert(a.at(1).second.isInteger() && (a.at(1).second.getIntValue() == 1));
|
||||
assert(a.at(3).second.isName() && (a.at(3).second.getName() == "/Third"));
|
||||
assert(a.at(4).second.isNull());
|
||||
|
||||
a.erase(a.size() - 1);
|
||||
assert(a.size() == 4);
|
||||
assert(a.at(0).isName() && (a.at(0).getName() == "/First"));
|
||||
assert(a.at(1).isInteger() && (a.at(1).getIntValue() == 1));
|
||||
assert(a.at(3).isName() && (a.at(3).getName() == "/Third"));
|
||||
assert(a.at(0).second.isName() && (a.at(0).second.getName() == "/First"));
|
||||
assert(a.at(1).second.isInteger() && (a.at(1).second.getIntValue() == 1));
|
||||
assert(a.at(3).second.isName() && (a.at(3).second.getName() == "/Third"));
|
||||
|
||||
a.erase(a.size() - 1);
|
||||
assert(a.size() == 3);
|
||||
assert(a.at(0).isName() && (a.at(0).getName() == "/First"));
|
||||
assert(a.at(1).isInteger() && (a.at(1).getIntValue() == 1));
|
||||
assert(a.at(2).isString() && (a.at(2).getStringValue() == "potato"));
|
||||
assert(a.at(0).second.isName() && (a.at(0).second.getName() == "/First"));
|
||||
assert(a.at(1).second.isInteger() && (a.at(1).second.getIntValue() == 1));
|
||||
assert(a.at(2).second.isString() && (a.at(2).second.getStringValue() == "potato"));
|
||||
|
||||
QPDF pdf;
|
||||
pdf.emptyPDF();
|
||||
@ -92,13 +92,13 @@ main()
|
||||
QPDF_Array& b = *obj->as<QPDF_Array>();
|
||||
b.setAt(5, pdf.newIndirectNull());
|
||||
b.setAt(7, "[0 1 2 3]"_qpdf);
|
||||
assert(b.at(3).isNull());
|
||||
assert(b.at(8).isNull());
|
||||
assert(b.at(5).isIndirect());
|
||||
assert(b.at(3).second.isNull());
|
||||
assert(b.at(8).second.isNull());
|
||||
assert(b.at(5).second.isIndirect());
|
||||
assert(b.unparse() == "[ null null null null null 3 0 R null [ 0 1 2 3 ] null null ]");
|
||||
auto c = b.copy(true);
|
||||
auto d = b.copy(false);
|
||||
b.at(7).setArrayItem(2, "42"_qpdf);
|
||||
b.at(7).second.setArrayItem(2, "42"_qpdf);
|
||||
assert(c->unparse() == "[ null null null null null 3 0 R null [ 0 1 42 3 ] null null ]");
|
||||
assert(d->unparse() == "[ null null null null null 3 0 R null [ 0 1 2 3 ] null null ]");
|
||||
|
||||
|
@ -1428,7 +1428,7 @@ test_42(QPDF& pdf, char const* arg2)
|
||||
assert(i == ai.end());
|
||||
++i;
|
||||
assert(i == ai.end());
|
||||
assert(!i_value.isInitialized());
|
||||
assert(!i_value);
|
||||
--i;
|
||||
assert(i_value.getName() == "/Item2");
|
||||
assert(i->getName() == "/Item2");
|
||||
@ -1444,7 +1444,7 @@ test_42(QPDF& pdf, char const* arg2)
|
||||
++i;
|
||||
++i;
|
||||
assert(i == di.end());
|
||||
assert(!i_value.second.isInitialized());
|
||||
assert(!i_value.second);
|
||||
}
|
||||
assert("" == qtest.getStringValue());
|
||||
array.getArrayItem(-1).assertNull();
|
||||
@ -1542,7 +1542,7 @@ test_42(QPDF& pdf, char const* arg2)
|
||||
assert(m1.a == 0 && m1.b == 0 && m1.c == 0 && m1.d == 0 && m1.e == 0 && m1.f == 0);
|
||||
// Uninitialized
|
||||
QPDFObjectHandle uninitialized;
|
||||
assert(!uninitialized.isInitialized());
|
||||
assert(!uninitialized);
|
||||
assert(!uninitialized.isInteger());
|
||||
assert(!uninitialized.isDictionary());
|
||||
assert(!uninitialized.isScalar());
|
||||
@ -1692,7 +1692,7 @@ test_46(QPDF& pdf, char const* arg2)
|
||||
assert(iter1_val.first == 2);
|
||||
++iter1;
|
||||
assert(iter1 == new1.end());
|
||||
assert(!iter1_val.second.isInitialized());
|
||||
assert(!iter1_val.second);
|
||||
++iter1;
|
||||
assert(iter1->first == 1);
|
||||
--iter1;
|
||||
@ -1842,7 +1842,7 @@ test_48(QPDF& pdf, char const* arg2)
|
||||
assert(iter1_val.first == "2");
|
||||
++iter1;
|
||||
assert(iter1 == new1.end());
|
||||
assert(!iter1_val.second.isInitialized());
|
||||
assert(!iter1_val.second);
|
||||
++iter1;
|
||||
assert(iter1->first == "1");
|
||||
--iter1;
|
||||
|
Loading…
Reference in New Issue
Block a user