mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 19:08:59 +00:00
Add new QPDFObjectHandle::Integer and QPDFObjectHandle::asInteger
Implement all existing integer accessors in terms of asInteger.
This commit is contained in:
parent
df852cd695
commit
f2fc1d3db8
@ -23,6 +23,7 @@
|
||||
#define QPDFOBJECTHANDLE_HH
|
||||
|
||||
#include <qpdf/QPDFObjectHandle_core.hh>
|
||||
#include <qpdf/QPDFObjectHandle_typed.hh>
|
||||
|
||||
// See qpdf/QPDFObjectHandle_core.hh for the definition of QPDFObjectHandle.
|
||||
|
||||
|
@ -66,6 +66,8 @@ class QPDFObjectHandle
|
||||
friend class QPDFParser;
|
||||
|
||||
public:
|
||||
class Typed;
|
||||
class Integer;
|
||||
// This class is used by replaceStreamData. It provides an alternative way of associating
|
||||
// stream data with a stream. See comments on replaceStreamData and newStream for additional
|
||||
// details.
|
||||
@ -647,6 +649,8 @@ class QPDFObjectHandle
|
||||
// return type may be returned. For example, on a system with 32-bit int, a numeric object with
|
||||
// a value of 2^40 (or anything too big for 32 bits) will be returned as INT_MAX.
|
||||
QPDF_DLL
|
||||
QPDFObjectHandle::Integer asInteger(bool optional = false);
|
||||
QPDF_DLL
|
||||
long long getIntValue();
|
||||
QPDF_DLL
|
||||
bool getValueAsInt(long long&);
|
||||
@ -1367,7 +1371,6 @@ class QPDFObjectHandle
|
||||
QPDF_Bool* asBool();
|
||||
QPDF_Dictionary* asDictionary();
|
||||
QPDF_InlineImage* asInlineImage();
|
||||
QPDF_Integer* asInteger();
|
||||
QPDF_Name* asName();
|
||||
QPDF_Null* asNull();
|
||||
QPDF_Operator* asOperator();
|
||||
|
138
include/qpdf/QPDFObjectHandle_typed.hh
Normal file
138
include/qpdf/QPDFObjectHandle_typed.hh
Normal file
@ -0,0 +1,138 @@
|
||||
// Copyright (c) 2005-2024 Jay Berkenbilt
|
||||
//
|
||||
// This file is part of qpdf.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Versions of qpdf prior to version 7 were released under the terms
|
||||
// of version 2.0 of the Artistic License. At your option, you may
|
||||
// continue to consider qpdf to be licensed under those terms. Please
|
||||
// see the manual for additional information.
|
||||
|
||||
#ifndef QPDFOBJECTHANDLE_TYPED_HH
|
||||
#define QPDFOBJECTHANDLE_TYPED_HH
|
||||
|
||||
#include <bitset>
|
||||
|
||||
class QPDFObjectHandle::Typed
|
||||
{
|
||||
public:
|
||||
operator QPDFObjectHandle() const
|
||||
{
|
||||
return oh;
|
||||
}
|
||||
|
||||
QPDF_DLL
|
||||
operator bool() noexcept
|
||||
{
|
||||
return flags.test(fl_valid);
|
||||
}
|
||||
|
||||
QPDF_DLL
|
||||
operator bool() const noexcept
|
||||
{
|
||||
return flags.test(fl_valid);
|
||||
}
|
||||
|
||||
QPDF_DLL
|
||||
bool
|
||||
null() const noexcept
|
||||
{
|
||||
return flags.test(fl_null);
|
||||
}
|
||||
|
||||
QPDF_DLL
|
||||
QPDFObjGen
|
||||
getObjGen() const
|
||||
{
|
||||
return oh.getObjGen();
|
||||
}
|
||||
|
||||
// ... and all the other methods applicable to all object types.
|
||||
|
||||
protected:
|
||||
using Flags = std::bitset<3>;
|
||||
|
||||
enum flags { fl_valid, fl_null, fl_no_type_check };
|
||||
|
||||
Typed() = default;
|
||||
Typed(QPDFObjectHandle const& oh, Flags flags) :
|
||||
oh(oh),
|
||||
flags(flags)
|
||||
{
|
||||
}
|
||||
|
||||
Typed(QPDFObjectHandle&& oh, Flags flags) :
|
||||
oh(std::move(oh)),
|
||||
flags(flags)
|
||||
{
|
||||
}
|
||||
|
||||
Typed(Typed const&) = default;
|
||||
Typed(Typed&&) = default;
|
||||
Typed& operator=(Typed const&) = default;
|
||||
Typed& operator=(Typed&&) = default;
|
||||
~Typed() = default;
|
||||
|
||||
QPDFObjectHandle oh;
|
||||
Flags flags{};
|
||||
};
|
||||
|
||||
class QPDFObjectHandle::Integer: public QPDFObjectHandle::Typed
|
||||
{
|
||||
friend class QPDFObjectHandle;
|
||||
|
||||
public:
|
||||
QPDF_DLL
|
||||
operator long long();
|
||||
|
||||
QPDF_DLL
|
||||
operator int();
|
||||
|
||||
QPDF_DLL
|
||||
operator unsigned long long();
|
||||
|
||||
QPDF_DLL
|
||||
operator unsigned int();
|
||||
|
||||
QPDF_DLL
|
||||
long long
|
||||
value()
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
assign_to(T& var)
|
||||
{
|
||||
if (flags.test(0)) {
|
||||
var = *this;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
Integer() = default;
|
||||
Integer(QPDFObjectHandle const& oh, Flags flags) :
|
||||
QPDFObjectHandle::Typed(oh, flags)
|
||||
{
|
||||
}
|
||||
Integer(QPDFObjectHandle&& oh, QPDF_Integer* ptr, Flags flags) :
|
||||
QPDFObjectHandle::Typed(std::move(oh), flags)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
#endif // QPDFOBJECTHANDLE_TYPED_HH
|
@ -273,12 +273,6 @@ QPDFObjectHandle::asInlineImage()
|
||||
return dereference() ? obj->as<QPDF_InlineImage>() : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Integer*
|
||||
QPDFObjectHandle::asInteger()
|
||||
{
|
||||
return dereference() ? obj->as<QPDF_Integer>() : nullptr;
|
||||
}
|
||||
|
||||
QPDF_Name*
|
||||
QPDFObjectHandle::asName()
|
||||
{
|
||||
@ -499,110 +493,123 @@ QPDFObjectHandle::getValueAsBool(bool& value)
|
||||
|
||||
// Integer accessors
|
||||
|
||||
QPDFObjectHandle::Integer
|
||||
QPDFObjectHandle::asInteger(bool optional)
|
||||
{
|
||||
if (isInteger()) {
|
||||
return {*this, 1U};
|
||||
}
|
||||
if (isNull()) {
|
||||
return {*this, optional ? 3U : 2U};
|
||||
}
|
||||
return {*this, 0U};
|
||||
}
|
||||
|
||||
QPDFObjectHandle::Integer::operator long long()
|
||||
{
|
||||
if (flags == 1U) {
|
||||
if (auto ptr = oh.obj ? oh.obj->as<QPDF_Integer>() : nullptr) {
|
||||
return ptr->getVal();
|
||||
} else {
|
||||
throw std::logic_error("object changed");
|
||||
}
|
||||
}
|
||||
if (!flags.test(fl_valid)) {
|
||||
oh.typeWarning("integer", "returning 0");
|
||||
}
|
||||
QTC::TC("qpdf", "QPDFObjectHandle integer returning 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
QPDFObjectHandle::Integer::operator int()
|
||||
{
|
||||
auto value = operator long long();
|
||||
if (value < INT_MIN) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle int returning INT_MIN");
|
||||
oh.warnIfPossible("requested value of integer is too small; returning INT_MIN");
|
||||
return INT_MIN;
|
||||
}
|
||||
if (value > INT_MAX) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle int returning INT_MAX");
|
||||
oh.warnIfPossible("requested value of integer is too big; returning INT_MAX");
|
||||
return INT_MAX;
|
||||
}
|
||||
return static_cast<int>(value);
|
||||
}
|
||||
|
||||
QPDFObjectHandle::Integer::operator unsigned long long()
|
||||
{
|
||||
auto value = operator long long();
|
||||
if (value < 0) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle uint returning 0");
|
||||
oh.warnIfPossible("unsigned value request for negative number; returning 0");
|
||||
return 0;
|
||||
}
|
||||
return static_cast<unsigned long long>(value);
|
||||
}
|
||||
|
||||
QPDFObjectHandle::Integer::operator unsigned int()
|
||||
{
|
||||
auto value = operator long long();
|
||||
if (value < 0) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle uint uint returning 0");
|
||||
oh.warnIfPossible("unsigned integer value request for negative number; returning 0");
|
||||
return 0;
|
||||
}
|
||||
if (value > UINT_MAX) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle uint returning UINT_MAX");
|
||||
oh.warnIfPossible("requested value of unsigned integer is too big; returning UINT_MAX");
|
||||
return UINT_MAX;
|
||||
}
|
||||
return static_cast<unsigned int>(value);
|
||||
}
|
||||
|
||||
long long
|
||||
QPDFObjectHandle::getIntValue()
|
||||
{
|
||||
auto integer = asInteger();
|
||||
if (integer) {
|
||||
return integer->getVal();
|
||||
} else {
|
||||
typeWarning("integer", "returning 0");
|
||||
QTC::TC("qpdf", "QPDFObjectHandle integer returning 0");
|
||||
return 0;
|
||||
}
|
||||
return asInteger();
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsInt(long long& value)
|
||||
{
|
||||
auto integer = asInteger();
|
||||
if (integer == nullptr) {
|
||||
return false;
|
||||
}
|
||||
value = integer->getVal();
|
||||
return true;
|
||||
return asInteger().assign_to(value);
|
||||
}
|
||||
|
||||
int
|
||||
QPDFObjectHandle::getIntValueAsInt()
|
||||
{
|
||||
int result = 0;
|
||||
long long v = getIntValue();
|
||||
if (v < INT_MIN) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle int returning INT_MIN");
|
||||
warnIfPossible("requested value of integer is too small; returning INT_MIN");
|
||||
result = INT_MIN;
|
||||
} else if (v > INT_MAX) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle int returning INT_MAX");
|
||||
warnIfPossible("requested value of integer is too big; returning INT_MAX");
|
||||
result = INT_MAX;
|
||||
} else {
|
||||
result = static_cast<int>(v);
|
||||
}
|
||||
return result;
|
||||
return asInteger();
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsInt(int& value)
|
||||
{
|
||||
if (!isInteger()) {
|
||||
return false;
|
||||
}
|
||||
value = getIntValueAsInt();
|
||||
return true;
|
||||
return asInteger().assign_to(value);
|
||||
}
|
||||
|
||||
unsigned long long
|
||||
QPDFObjectHandle::getUIntValue()
|
||||
{
|
||||
unsigned long long result = 0;
|
||||
long long v = getIntValue();
|
||||
if (v < 0) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle uint returning 0");
|
||||
warnIfPossible("unsigned value request for negative number; returning 0");
|
||||
} else {
|
||||
result = static_cast<unsigned long long>(v);
|
||||
}
|
||||
return result;
|
||||
return asInteger();
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsUInt(unsigned long long& value)
|
||||
{
|
||||
if (!isInteger()) {
|
||||
return false;
|
||||
}
|
||||
value = getUIntValue();
|
||||
return true;
|
||||
return asInteger().assign_to(value);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
QPDFObjectHandle::getUIntValueAsUInt()
|
||||
{
|
||||
unsigned int result = 0;
|
||||
long long v = getIntValue();
|
||||
if (v < 0) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle uint uint returning 0");
|
||||
warnIfPossible("unsigned integer value request for negative number; returning 0");
|
||||
result = 0;
|
||||
} else if (v > UINT_MAX) {
|
||||
QTC::TC("qpdf", "QPDFObjectHandle uint returning UINT_MAX");
|
||||
warnIfPossible("requested value of unsigned integer is too big; returning UINT_MAX");
|
||||
result = UINT_MAX;
|
||||
} else {
|
||||
result = static_cast<unsigned int>(v);
|
||||
}
|
||||
return result;
|
||||
return asInteger();
|
||||
}
|
||||
|
||||
bool
|
||||
QPDFObjectHandle::getValueAsUInt(unsigned int& value)
|
||||
{
|
||||
if (!isInteger()) {
|
||||
return false;
|
||||
}
|
||||
value = getUIntValueAsUInt();
|
||||
return true;
|
||||
return asInteger().assign_to(value);
|
||||
}
|
||||
|
||||
// Real accessors
|
||||
|
Loading…
Reference in New Issue
Block a user