2
1
mirror of https://github.com/qpdf/qpdf.git synced 2024-05-31 01:10:51 +00:00

Add getTypeCode() and getTypeName()

Add virtual methods to QPDFObject, wrappers to QPDFObjectHandle, and
implementations to all the QPDF_Object types.
This commit is contained in:
Jay Berkenbilt 2013-01-22 09:57:07 -05:00
parent f81152311e
commit 913eb5ac35
33 changed files with 383 additions and 130 deletions

View File

@ -1,10 +1,23 @@
2013-01-22 Jay Berkenbilt <ejb@ql.org>
* Add QPDFObjectHandle::getTypeCode(). This method returns a
unique integer (enumerated type) value corresponding to the object
type of the QPDFObjectHandle. It can be used as an alternative to
the QPDFObjectHandle::is* methods for type testing, particularly
where there is a desire to use a switch statement or optimize for
performance when testing object types.
* Add QPDFObjectHandle::getTypeName(). This method returns a
string literal describing the object type. It is useful for
testing and debugging.
2013-01-20 Jay Berkenbilt <ejb@ql.org> 2013-01-20 Jay Berkenbilt <ejb@ql.org>
* Added QPDFObjectHandle::parseContentStream, which parses the * Add QPDFObjectHandle::parseContentStream, which parses the
objects in a content stream and calls handlers in a callback objects in a content stream and calls handlers in a callback
class. The example pdf-parse-content illustrates it use. class. The example pdf-parse-content illustrates it use.
* Added QPDF_Keyword and QPDF_InlineImage types along with * Add QPDF_Keyword and QPDF_InlineImage types along with
appropriate wrapper methods in QPDFObjectHandle. These new object appropriate wrapper methods in QPDFObjectHandle. These new object
types are to facilitate content stream parsing. types are to facilitate content stream parsing.

View File

@ -30,10 +30,10 @@ class ParserCallbacks: public QPDFObjectHandle::ParserCallbacks
void void
ParserCallbacks::handleObject(QPDFObjectHandle obj) ParserCallbacks::handleObject(QPDFObjectHandle obj)
{ {
std::cout << obj.getTypeName() << ": ";
if (obj.isInlineImage()) if (obj.isInlineImage())
{ {
std::string val = obj.getInlineImageValue(); std::string val = obj.getInlineImageValue();
std::cout << "inline image: ";
char buf[3]; char buf[3];
buf[2] = '\0'; buf[2] = '\0';
for (size_t i = 0; i < val.length(); ++i) for (size_t i = 0; i < val.length(); ++i)

View File

@ -1,11 +1,11 @@
BT keyword: BT
/F1 name: /F1
24 integer: 24
Tf keyword: Tf
72 integer: 72
720 integer: 720
Td keyword: Td
(Potato) string: (Potato)
Tj keyword: Tj
ET keyword: ET
-EOF- -EOF-

View File

@ -18,9 +18,42 @@ class QPDFObjectHandle;
class QPDFObject class QPDFObject
{ {
public: public:
// Objects derived from QPDFObject are accessible through
// QPDFObjectHandle. Each object returns a unique type code that
// has one of the values in the list below. As new object types
// are added to qpdf, additional items may be added to the list,
// so code that switches on these values should take that into
// consideration.
enum object_type_e {
// Object types internal to qpdf
ot_uninitialized,
ot_reserved,
// Object types that can occur in the main document
ot_boolean,
ot_null,
ot_integer,
ot_real,
ot_name,
ot_string,
ot_array,
ot_dictionary,
ot_stream,
// Additional object types that can occur in content streams
ot_keyword,
ot_inlineimage,
};
virtual ~QPDFObject() {} virtual ~QPDFObject() {}
virtual std::string unparse() = 0; virtual std::string unparse() = 0;
// Return a unique type code for the object
virtual object_type_e getTypeCode() const = 0;
// Return a string literal that describes the type, useful for
// debugging and testing
virtual char const* getTypeName() const = 0;
// Accessor to give specific access to non-public methods // Accessor to give specific access to non-public methods
class ObjAccessor class ObjAccessor
{ {

View File

@ -91,6 +91,14 @@ class QPDFObjectHandle
QPDF_DLL QPDF_DLL
bool isInitialized() const; bool isInitialized() const;
// Return type code and type name of underlying object. These are
// useful for doing rapid type tests (like switch statements) or
// for testing and debugging.
QPDF_DLL
QPDFObject::object_type_e getTypeCode() const;
QPDF_DLL
char const* getTypeName() const;
// Exactly one of these will return true for any object. Keyword // Exactly one of these will return true for any object. Keyword
// and InlineImage are only allowed in content streams. // and InlineImage are only allowed in content streams.
QPDF_DLL QPDF_DLL

View File

@ -76,6 +76,32 @@ QPDFObjectHandle::isInitialized() const
return this->initialized; return this->initialized;
} }
QPDFObject::object_type_e
QPDFObjectHandle::getTypeCode() const
{
if (obj.getPointer())
{
return obj->getTypeCode();
}
else
{
return QPDFObject::ot_uninitialized;
}
}
char const*
QPDFObjectHandle::getTypeName() const
{
if (obj.getPointer())
{
return obj->getTypeName();
}
else
{
return "uninitialized";
}
}
template <class T> template <class T>
class QPDFObjectTypeAccessor class QPDFObjectTypeAccessor
{ {

View File

@ -34,6 +34,18 @@ QPDF_Array::unparse()
return result; return result;
} }
QPDFObject::object_type_e
QPDF_Array::getTypeCode() const
{
return QPDFObject::ot_array;
}
char const*
QPDF_Array::getTypeName() const
{
return "array";
}
int int
QPDF_Array::getNItems() const QPDF_Array::getNItems() const
{ {

View File

@ -15,6 +15,18 @@ QPDF_Bool::unparse()
return (val ? "true" : "false"); return (val ? "true" : "false");
} }
QPDFObject::object_type_e
QPDF_Bool::getTypeCode() const
{
return QPDFObject::ot_boolean;
}
char const*
QPDF_Bool::getTypeName() const
{
return "boolean";
}
bool bool
QPDF_Bool::getVal() const QPDF_Bool::getVal() const
{ {

View File

@ -39,6 +39,18 @@ QPDF_Dictionary::unparse()
return result; return result;
} }
QPDFObject::object_type_e
QPDF_Dictionary::getTypeCode() const
{
return QPDFObject::ot_dictionary;
}
char const*
QPDF_Dictionary::getTypeName() const
{
return "dictionary";
}
bool bool
QPDF_Dictionary::hasKey(std::string const& key) QPDF_Dictionary::hasKey(std::string const& key)
{ {

View File

@ -17,6 +17,18 @@ QPDF_InlineImage::unparse()
return this->val; return this->val;
} }
QPDFObject::object_type_e
QPDF_InlineImage::getTypeCode() const
{
return QPDFObject::ot_inlineimage;
}
char const*
QPDF_InlineImage::getTypeName() const
{
return "inline-image";
}
std::string std::string
QPDF_InlineImage::getVal() const QPDF_InlineImage::getVal() const
{ {

View File

@ -17,6 +17,18 @@ QPDF_Integer::unparse()
return QUtil::int_to_string(this->val); return QUtil::int_to_string(this->val);
} }
QPDFObject::object_type_e
QPDF_Integer::getTypeCode() const
{
return QPDFObject::ot_integer;
}
char const*
QPDF_Integer::getTypeName() const
{
return "integer";
}
long long long long
QPDF_Integer::getVal() const QPDF_Integer::getVal() const
{ {

View File

@ -17,6 +17,18 @@ QPDF_Keyword::unparse()
return this->val; return this->val;
} }
QPDFObject::object_type_e
QPDF_Keyword::getTypeCode() const
{
return QPDFObject::ot_keyword;
}
char const*
QPDF_Keyword::getTypeName() const
{
return "keyword";
}
std::string std::string
QPDF_Keyword::getVal() const QPDF_Keyword::getVal() const
{ {

View File

@ -41,6 +41,18 @@ QPDF_Name::unparse()
return normalizeName(this->name); return normalizeName(this->name);
} }
QPDFObject::object_type_e
QPDF_Name::getTypeCode() const
{
return QPDFObject::ot_name;
}
char const*
QPDF_Name::getTypeName() const
{
return "name";
}
std::string std::string
QPDF_Name::getName() const QPDF_Name::getName() const
{ {

View File

@ -9,3 +9,15 @@ QPDF_Null::unparse()
{ {
return "null"; return "null";
} }
QPDFObject::object_type_e
QPDF_Null::getTypeCode() const
{
return QPDFObject::ot_null;
}
char const*
QPDF_Null::getTypeName() const
{
return "null";
}

View File

@ -22,6 +22,18 @@ QPDF_Real::unparse()
return this->val; return this->val;
} }
QPDFObject::object_type_e
QPDF_Real::getTypeCode() const
{
return QPDFObject::ot_real;
}
char const*
QPDF_Real::getTypeName() const
{
return "real";
}
std::string std::string
QPDF_Real::getVal() QPDF_Real::getVal()
{ {

View File

@ -11,3 +11,15 @@ QPDF_Reserved::unparse()
throw std::logic_error("attempt to unparse QPDF_Reserved"); throw std::logic_error("attempt to unparse QPDF_Reserved");
return ""; return "";
} }
QPDFObject::object_type_e
QPDF_Reserved::getTypeCode() const
{
return QPDFObject::ot_reserved;
}
char const*
QPDF_Reserved::getTypeName() const
{
return "reserved";
}

View File

@ -63,6 +63,18 @@ QPDF_Stream::unparse()
QUtil::int_to_string(this->generation) + " R"; QUtil::int_to_string(this->generation) + " R";
} }
QPDFObject::object_type_e
QPDF_Stream::getTypeCode() const
{
return QPDFObject::ot_stream;
}
char const*
QPDF_Stream::getTypeName() const
{
return "stream";
}
QPDFObjectHandle QPDFObjectHandle
QPDF_Stream::getDict() const QPDF_Stream::getDict() const
{ {

View File

@ -33,6 +33,18 @@ QPDF_String::unparse()
return unparse(false); return unparse(false);
} }
QPDFObject::object_type_e
QPDF_String::getTypeCode() const
{
return QPDFObject::ot_string;
}
char const*
QPDF_String::getTypeName() const
{
return "string";
}
std::string std::string
QPDF_String::unparse(bool force_binary) QPDF_String::unparse(bool force_binary)
{ {

View File

@ -12,6 +12,8 @@ class QPDF_Array: public QPDFObject
QPDF_Array(std::vector<QPDFObjectHandle> const& items); QPDF_Array(std::vector<QPDFObjectHandle> const& items);
virtual ~QPDF_Array(); virtual ~QPDF_Array();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
int getNItems() const; int getNItems() const;
QPDFObjectHandle getItem(int n) const; QPDFObjectHandle getItem(int n) const;

View File

@ -9,6 +9,8 @@ class QPDF_Bool: public QPDFObject
QPDF_Bool(bool val); QPDF_Bool(bool val);
virtual ~QPDF_Bool(); virtual ~QPDF_Bool();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
bool getVal() const; bool getVal() const;
private: private:

View File

@ -14,6 +14,8 @@ class QPDF_Dictionary: public QPDFObject
QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items); QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items);
virtual ~QPDF_Dictionary(); virtual ~QPDF_Dictionary();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
// hasKey() and getKeys() treat keys with null values as if they // hasKey() and getKeys() treat keys with null values as if they
// aren't there. getKey() returns null for the value of a // aren't there. getKey() returns null for the value of a

View File

@ -9,6 +9,8 @@ class QPDF_InlineImage: public QPDFObject
QPDF_InlineImage(std::string const& val); QPDF_InlineImage(std::string const& val);
virtual ~QPDF_InlineImage(); virtual ~QPDF_InlineImage();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
std::string getVal() const; std::string getVal() const;
private: private:

View File

@ -9,6 +9,8 @@ class QPDF_Integer: public QPDFObject
QPDF_Integer(long long val); QPDF_Integer(long long val);
virtual ~QPDF_Integer(); virtual ~QPDF_Integer();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
long long getVal() const; long long getVal() const;
private: private:

View File

@ -9,6 +9,8 @@ class QPDF_Keyword: public QPDFObject
QPDF_Keyword(std::string const& val); QPDF_Keyword(std::string const& val);
virtual ~QPDF_Keyword(); virtual ~QPDF_Keyword();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
std::string getVal() const; std::string getVal() const;
private: private:

View File

@ -9,6 +9,8 @@ class QPDF_Name: public QPDFObject
QPDF_Name(std::string const& name); QPDF_Name(std::string const& name);
virtual ~QPDF_Name(); virtual ~QPDF_Name();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
std::string getName() const; std::string getName() const;
// Put # into strings with characters unsuitable for name token // Put # into strings with characters unsuitable for name token

View File

@ -8,6 +8,8 @@ class QPDF_Null: public QPDFObject
public: public:
virtual ~QPDF_Null(); virtual ~QPDF_Null();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
}; };
#endif // __QPDF_NULL_HH__ #endif // __QPDF_NULL_HH__

View File

@ -10,6 +10,8 @@ class QPDF_Real: public QPDFObject
QPDF_Real(double value, int decimal_places = 0); QPDF_Real(double value, int decimal_places = 0);
virtual ~QPDF_Real(); virtual ~QPDF_Real();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
std::string getVal(); std::string getVal();
private: private:

View File

@ -8,6 +8,8 @@ class QPDF_Reserved: public QPDFObject
public: public:
virtual ~QPDF_Reserved(); virtual ~QPDF_Reserved();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
}; };
#endif // __QPDF_RESERVED_HH__ #endif // __QPDF_RESERVED_HH__

View File

@ -17,6 +17,8 @@ class QPDF_Stream: public QPDFObject
qpdf_offset_t offset, size_t length); qpdf_offset_t offset, size_t length);
virtual ~QPDF_Stream(); virtual ~QPDF_Stream();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
QPDFObjectHandle getDict() const; QPDFObjectHandle getDict() const;
// See comments in QPDFObjectHandle.hh for these methods. // See comments in QPDFObjectHandle.hh for these methods.

View File

@ -11,6 +11,8 @@ class QPDF_String: public QPDFObject
QPDF_String(std::string const& val); QPDF_String(std::string const& val);
virtual ~QPDF_String(); virtual ~QPDF_String();
virtual std::string unparse(); virtual std::string unparse();
virtual QPDFObject::object_type_e getTypeCode() const;
virtual char const* getTypeName() const;
std::string unparse(bool force_binary); std::string unparse(bool force_binary);
std::string getVal() const; std::string getVal() const;
std::string getUTF8Val() const; std::string getUTF8Val() const;

View File

@ -1,25 +1,25 @@
BT keyword: BT
/F1 name: /F1
24 integer: 24
Tf keyword: Tf
72 integer: 72
720 integer: 720
Td keyword: Td
(Potato) string: (Potato)
Tj keyword: Tj
ET keyword: ET
BI keyword: BI
/CS name: /CS
/G name: /G
/W name: /W
1 integer: 1
/H name: /H
1 integer: 1
/BPC name: /BPC
8 integer: 8
/F name: /F
/Fl name: /Fl
/DP name: /DP
<< /Columns 1 /Predictor 15 >> dictionary: << /Columns 1 /Predictor 15 >>
ID keyword: ID
content stream object 4 0 (stream data, file position 139): EOF found while reading inline image content stream object 4 0 (stream data, file position 139): EOF found while reading inline image

View File

@ -1,95 +1,95 @@
BT keyword: BT
/F1 name: /F1
24 integer: 24
Tf keyword: Tf
72 integer: 72
720 integer: 720
Td keyword: Td
(Potato) string: (Potato)
Tj keyword: Tj
ET keyword: ET
-EOF- -EOF-
0.1 real: 0.1
0 integer: 0
0 integer: 0
0.1 real: 0.1
0 integer: 0
0 integer: 0
cm keyword: cm
q keyword: q
0 integer: 0
1.1999 real: 1.1999
-1.1999 real: -1.1999
0 integer: 0
121.19 real: 121.19
150.009 real: 150.009
cm keyword: cm
BI keyword: BI
/CS name: /CS
/G name: /G
/W name: /W
1 integer: 1
/H name: /H
1 integer: 1
/BPC name: /BPC
8 integer: 8
/F name: /F
/Fl name: /Fl
/DP name: /DP
<< /Columns 1 /Predictor 15 >> dictionary: << /Columns 1 /Predictor 15 >>
ID keyword: ID
inline image: 789c63fc0f0001030101 inline-image: 789c63fc0f0001030101
EI keyword: EI
Q keyword: Q
q keyword: q
0 integer: 0
35.997 real: 35.997
-128.389 real: -128.389
0 integer: 0
431.964 real: 431.964
7269.02 real: 7269.02
cm keyword: cm
BI keyword: BI
/CS name: /CS
/G name: /G
/W name: /W
30 integer: 30
/H name: /H
107 integer: 107
/BPC name: /BPC
8 integer: 8
/F name: /F
/Fl name: /Fl
/DP name: /DP
<< /Columns 30 /Predictor 15 >> dictionary: << /Columns 30 /Predictor 15 >>
ID keyword: ID
inline image: 789cedd1a11100300800b1b2ffd06503148283bc8dfcf8af2a306ee352eff2e06318638c31c63b3801627b620a inline-image: 789cedd1a11100300800b1b2ffd06503148283bc8dfcf8af2a306ee352eff2e06318638c31c63b3801627b620a
EI keyword: EI
Q keyword: Q
q keyword: q
0 integer: 0
38.3968 real: 38.3968
-93.5922 real: -93.5922
0 integer: 0
431.964 real: 431.964
7567.79 real: 7567.79
cm keyword: cm
BI keyword: BI
/CS name: /CS
/G name: /G
/W name: /W
32 integer: 32
/H name: /H
78 integer: 78
/BPC name: /BPC
8 integer: 8
/F name: /F
/Fl name: /Fl
/DP name: /DP
<< /Columns 32 /Predictor 15 >> dictionary: << /Columns 32 /Predictor 15 >>
ID keyword: ID
inline image: 789c63fccf801f308e2a185530aa60882a20203faa605401890a0643aa1e5530aa6054010d140000bdd03c13 inline-image: 789c63fccf801f308e2a185530aa60882a20203faa605401890a0643aa1e5530aa6054010d140000bdd03c13
EI keyword: EI
Q keyword: Q
-EOF- -EOF-
test 37 done test 37 done

View File

@ -72,10 +72,11 @@ class ParserCallbacks: public QPDFObjectHandle::ParserCallbacks
void void
ParserCallbacks::handleObject(QPDFObjectHandle obj) ParserCallbacks::handleObject(QPDFObjectHandle obj)
{ {
std::cout << obj.getTypeName() << ": ";
if (obj.isInlineImage()) if (obj.isInlineImage())
{ {
assert(obj.getTypeCode() == QPDFObject::ot_inlineimage);
std::string val = obj.getInlineImageValue(); std::string val = obj.getInlineImageValue();
std::cout << "inline image: ";
char buf[3]; char buf[3];
buf[2] = '\0'; buf[2] = '\0';
for (size_t i = 0; i < val.length(); ++i) for (size_t i = 0; i < val.length(); ++i)
@ -142,6 +143,10 @@ void runtest(int n, char const* filename1, char const* arg2)
assert(password.length() == 32); assert(password.length() == 32);
QPDF::trim_user_password(password); QPDF::trim_user_password(password);
assert(password == "1234567890123456789012(45678"); assert(password == "1234567890123456789012(45678");
QPDFObjectHandle uninitialized;
assert(uninitialized.getTypeCode() == QPDFObject::ot_uninitialized);
assert(strcmp(uninitialized.getTypeName(), "uninitialized") == 0);
} }
QPDF pdf; QPDF pdf;