Commit 913eb5ac35011b3d28c653b6f89d936c8f99c844

Authored by Jay Berkenbilt
1 parent f8115231

Add getTypeCode() and getTypeName()

Add virtual methods to QPDFObject, wrappers to QPDFObjectHandle, and
implementations to all the QPDF_Object types.
ChangeLog
  1 +2013-01-22 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * Add QPDFObjectHandle::getTypeCode(). This method returns a
  4 + unique integer (enumerated type) value corresponding to the object
  5 + type of the QPDFObjectHandle. It can be used as an alternative to
  6 + the QPDFObjectHandle::is* methods for type testing, particularly
  7 + where there is a desire to use a switch statement or optimize for
  8 + performance when testing object types.
  9 +
  10 + * Add QPDFObjectHandle::getTypeName(). This method returns a
  11 + string literal describing the object type. It is useful for
  12 + testing and debugging.
  13 +
1 2013-01-20 Jay Berkenbilt <ejb@ql.org> 14 2013-01-20 Jay Berkenbilt <ejb@ql.org>
2 15
3 - * Added QPDFObjectHandle::parseContentStream, which parses the 16 + * Add QPDFObjectHandle::parseContentStream, which parses the
4 objects in a content stream and calls handlers in a callback 17 objects in a content stream and calls handlers in a callback
5 class. The example pdf-parse-content illustrates it use. 18 class. The example pdf-parse-content illustrates it use.
6 19
7 - * Added QPDF_Keyword and QPDF_InlineImage types along with 20 + * Add QPDF_Keyword and QPDF_InlineImage types along with
8 appropriate wrapper methods in QPDFObjectHandle. These new object 21 appropriate wrapper methods in QPDFObjectHandle. These new object
9 types are to facilitate content stream parsing. 22 types are to facilitate content stream parsing.
10 23
examples/pdf-parse-content.cc
@@ -30,10 +30,10 @@ class ParserCallbacks: public QPDFObjectHandle::ParserCallbacks @@ -30,10 +30,10 @@ class ParserCallbacks: public QPDFObjectHandle::ParserCallbacks
30 void 30 void
31 ParserCallbacks::handleObject(QPDFObjectHandle obj) 31 ParserCallbacks::handleObject(QPDFObjectHandle obj)
32 { 32 {
  33 + std::cout << obj.getTypeName() << ": ";
33 if (obj.isInlineImage()) 34 if (obj.isInlineImage())
34 { 35 {
35 std::string val = obj.getInlineImageValue(); 36 std::string val = obj.getInlineImageValue();
36 - std::cout << "inline image: ";  
37 char buf[3]; 37 char buf[3];
38 buf[2] = '\0'; 38 buf[2] = '\0';
39 for (size_t i = 0; i < val.length(); ++i) 39 for (size_t i = 0; i < val.length(); ++i)
examples/qtest/parse-content/content.out
1 -BT  
2 -/F1  
3 -24  
4 -Tf  
5 -72  
6 -720  
7 -Td  
8 -(Potato)  
9 -Tj  
10 -ET 1 +keyword: BT
  2 +name: /F1
  3 +integer: 24
  4 +keyword: Tf
  5 +integer: 72
  6 +integer: 720
  7 +keyword: Td
  8 +string: (Potato)
  9 +keyword: Tj
  10 +keyword: ET
11 -EOF- 11 -EOF-
include/qpdf/QPDFObject.hh
@@ -18,9 +18,42 @@ class QPDFObjectHandle; @@ -18,9 +18,42 @@ class QPDFObjectHandle;
18 class QPDFObject 18 class QPDFObject
19 { 19 {
20 public: 20 public:
  21 +
  22 + // Objects derived from QPDFObject are accessible through
  23 + // QPDFObjectHandle. Each object returns a unique type code that
  24 + // has one of the values in the list below. As new object types
  25 + // are added to qpdf, additional items may be added to the list,
  26 + // so code that switches on these values should take that into
  27 + // consideration.
  28 + enum object_type_e {
  29 + // Object types internal to qpdf
  30 + ot_uninitialized,
  31 + ot_reserved,
  32 + // Object types that can occur in the main document
  33 + ot_boolean,
  34 + ot_null,
  35 + ot_integer,
  36 + ot_real,
  37 + ot_name,
  38 + ot_string,
  39 + ot_array,
  40 + ot_dictionary,
  41 + ot_stream,
  42 + // Additional object types that can occur in content streams
  43 + ot_keyword,
  44 + ot_inlineimage,
  45 + };
  46 +
21 virtual ~QPDFObject() {} 47 virtual ~QPDFObject() {}
22 virtual std::string unparse() = 0; 48 virtual std::string unparse() = 0;
23 49
  50 + // Return a unique type code for the object
  51 + virtual object_type_e getTypeCode() const = 0;
  52 +
  53 + // Return a string literal that describes the type, useful for
  54 + // debugging and testing
  55 + virtual char const* getTypeName() const = 0;
  56 +
24 // Accessor to give specific access to non-public methods 57 // Accessor to give specific access to non-public methods
25 class ObjAccessor 58 class ObjAccessor
26 { 59 {
include/qpdf/QPDFObjectHandle.hh
@@ -91,6 +91,14 @@ class QPDFObjectHandle @@ -91,6 +91,14 @@ class QPDFObjectHandle
91 QPDF_DLL 91 QPDF_DLL
92 bool isInitialized() const; 92 bool isInitialized() const;
93 93
  94 + // Return type code and type name of underlying object. These are
  95 + // useful for doing rapid type tests (like switch statements) or
  96 + // for testing and debugging.
  97 + QPDF_DLL
  98 + QPDFObject::object_type_e getTypeCode() const;
  99 + QPDF_DLL
  100 + char const* getTypeName() const;
  101 +
94 // Exactly one of these will return true for any object. Keyword 102 // Exactly one of these will return true for any object. Keyword
95 // and InlineImage are only allowed in content streams. 103 // and InlineImage are only allowed in content streams.
96 QPDF_DLL 104 QPDF_DLL
libqpdf/QPDFObjectHandle.cc
@@ -76,6 +76,32 @@ QPDFObjectHandle::isInitialized() const @@ -76,6 +76,32 @@ QPDFObjectHandle::isInitialized() const
76 return this->initialized; 76 return this->initialized;
77 } 77 }
78 78
  79 +QPDFObject::object_type_e
  80 +QPDFObjectHandle::getTypeCode() const
  81 +{
  82 + if (obj.getPointer())
  83 + {
  84 + return obj->getTypeCode();
  85 + }
  86 + else
  87 + {
  88 + return QPDFObject::ot_uninitialized;
  89 + }
  90 +}
  91 +
  92 +char const*
  93 +QPDFObjectHandle::getTypeName() const
  94 +{
  95 + if (obj.getPointer())
  96 + {
  97 + return obj->getTypeName();
  98 + }
  99 + else
  100 + {
  101 + return "uninitialized";
  102 + }
  103 +}
  104 +
79 template <class T> 105 template <class T>
80 class QPDFObjectTypeAccessor 106 class QPDFObjectTypeAccessor
81 { 107 {
libqpdf/QPDF_Array.cc
@@ -34,6 +34,18 @@ QPDF_Array::unparse() @@ -34,6 +34,18 @@ QPDF_Array::unparse()
34 return result; 34 return result;
35 } 35 }
36 36
  37 +QPDFObject::object_type_e
  38 +QPDF_Array::getTypeCode() const
  39 +{
  40 + return QPDFObject::ot_array;
  41 +}
  42 +
  43 +char const*
  44 +QPDF_Array::getTypeName() const
  45 +{
  46 + return "array";
  47 +}
  48 +
37 int 49 int
38 QPDF_Array::getNItems() const 50 QPDF_Array::getNItems() const
39 { 51 {
libqpdf/QPDF_Bool.cc
@@ -15,6 +15,18 @@ QPDF_Bool::unparse() @@ -15,6 +15,18 @@ QPDF_Bool::unparse()
15 return (val ? "true" : "false"); 15 return (val ? "true" : "false");
16 } 16 }
17 17
  18 +QPDFObject::object_type_e
  19 +QPDF_Bool::getTypeCode() const
  20 +{
  21 + return QPDFObject::ot_boolean;
  22 +}
  23 +
  24 +char const*
  25 +QPDF_Bool::getTypeName() const
  26 +{
  27 + return "boolean";
  28 +}
  29 +
18 bool 30 bool
19 QPDF_Bool::getVal() const 31 QPDF_Bool::getVal() const
20 { 32 {
libqpdf/QPDF_Dictionary.cc
@@ -39,6 +39,18 @@ QPDF_Dictionary::unparse() @@ -39,6 +39,18 @@ QPDF_Dictionary::unparse()
39 return result; 39 return result;
40 } 40 }
41 41
  42 +QPDFObject::object_type_e
  43 +QPDF_Dictionary::getTypeCode() const
  44 +{
  45 + return QPDFObject::ot_dictionary;
  46 +}
  47 +
  48 +char const*
  49 +QPDF_Dictionary::getTypeName() const
  50 +{
  51 + return "dictionary";
  52 +}
  53 +
42 bool 54 bool
43 QPDF_Dictionary::hasKey(std::string const& key) 55 QPDF_Dictionary::hasKey(std::string const& key)
44 { 56 {
libqpdf/QPDF_InlineImage.cc
@@ -17,6 +17,18 @@ QPDF_InlineImage::unparse() @@ -17,6 +17,18 @@ QPDF_InlineImage::unparse()
17 return this->val; 17 return this->val;
18 } 18 }
19 19
  20 +QPDFObject::object_type_e
  21 +QPDF_InlineImage::getTypeCode() const
  22 +{
  23 + return QPDFObject::ot_inlineimage;
  24 +}
  25 +
  26 +char const*
  27 +QPDF_InlineImage::getTypeName() const
  28 +{
  29 + return "inline-image";
  30 +}
  31 +
20 std::string 32 std::string
21 QPDF_InlineImage::getVal() const 33 QPDF_InlineImage::getVal() const
22 { 34 {
libqpdf/QPDF_Integer.cc
@@ -17,6 +17,18 @@ QPDF_Integer::unparse() @@ -17,6 +17,18 @@ QPDF_Integer::unparse()
17 return QUtil::int_to_string(this->val); 17 return QUtil::int_to_string(this->val);
18 } 18 }
19 19
  20 +QPDFObject::object_type_e
  21 +QPDF_Integer::getTypeCode() const
  22 +{
  23 + return QPDFObject::ot_integer;
  24 +}
  25 +
  26 +char const*
  27 +QPDF_Integer::getTypeName() const
  28 +{
  29 + return "integer";
  30 +}
  31 +
20 long long 32 long long
21 QPDF_Integer::getVal() const 33 QPDF_Integer::getVal() const
22 { 34 {
libqpdf/QPDF_Keyword.cc
@@ -17,6 +17,18 @@ QPDF_Keyword::unparse() @@ -17,6 +17,18 @@ QPDF_Keyword::unparse()
17 return this->val; 17 return this->val;
18 } 18 }
19 19
  20 +QPDFObject::object_type_e
  21 +QPDF_Keyword::getTypeCode() const
  22 +{
  23 + return QPDFObject::ot_keyword;
  24 +}
  25 +
  26 +char const*
  27 +QPDF_Keyword::getTypeName() const
  28 +{
  29 + return "keyword";
  30 +}
  31 +
20 std::string 32 std::string
21 QPDF_Keyword::getVal() const 33 QPDF_Keyword::getVal() const
22 { 34 {
libqpdf/QPDF_Name.cc
@@ -41,6 +41,18 @@ QPDF_Name::unparse() @@ -41,6 +41,18 @@ QPDF_Name::unparse()
41 return normalizeName(this->name); 41 return normalizeName(this->name);
42 } 42 }
43 43
  44 +QPDFObject::object_type_e
  45 +QPDF_Name::getTypeCode() const
  46 +{
  47 + return QPDFObject::ot_name;
  48 +}
  49 +
  50 +char const*
  51 +QPDF_Name::getTypeName() const
  52 +{
  53 + return "name";
  54 +}
  55 +
44 std::string 56 std::string
45 QPDF_Name::getName() const 57 QPDF_Name::getName() const
46 { 58 {
libqpdf/QPDF_Null.cc
@@ -9,3 +9,15 @@ QPDF_Null::unparse() @@ -9,3 +9,15 @@ QPDF_Null::unparse()
9 { 9 {
10 return "null"; 10 return "null";
11 } 11 }
  12 +
  13 +QPDFObject::object_type_e
  14 +QPDF_Null::getTypeCode() const
  15 +{
  16 + return QPDFObject::ot_null;
  17 +}
  18 +
  19 +char const*
  20 +QPDF_Null::getTypeName() const
  21 +{
  22 + return "null";
  23 +}
libqpdf/QPDF_Real.cc
@@ -22,6 +22,18 @@ QPDF_Real::unparse() @@ -22,6 +22,18 @@ QPDF_Real::unparse()
22 return this->val; 22 return this->val;
23 } 23 }
24 24
  25 +QPDFObject::object_type_e
  26 +QPDF_Real::getTypeCode() const
  27 +{
  28 + return QPDFObject::ot_real;
  29 +}
  30 +
  31 +char const*
  32 +QPDF_Real::getTypeName() const
  33 +{
  34 + return "real";
  35 +}
  36 +
25 std::string 37 std::string
26 QPDF_Real::getVal() 38 QPDF_Real::getVal()
27 { 39 {
libqpdf/QPDF_Reserved.cc
@@ -11,3 +11,15 @@ QPDF_Reserved::unparse() @@ -11,3 +11,15 @@ QPDF_Reserved::unparse()
11 throw std::logic_error("attempt to unparse QPDF_Reserved"); 11 throw std::logic_error("attempt to unparse QPDF_Reserved");
12 return ""; 12 return "";
13 } 13 }
  14 +
  15 +QPDFObject::object_type_e
  16 +QPDF_Reserved::getTypeCode() const
  17 +{
  18 + return QPDFObject::ot_reserved;
  19 +}
  20 +
  21 +char const*
  22 +QPDF_Reserved::getTypeName() const
  23 +{
  24 + return "reserved";
  25 +}
libqpdf/QPDF_Stream.cc
@@ -63,6 +63,18 @@ QPDF_Stream::unparse() @@ -63,6 +63,18 @@ QPDF_Stream::unparse()
63 QUtil::int_to_string(this->generation) + " R"; 63 QUtil::int_to_string(this->generation) + " R";
64 } 64 }
65 65
  66 +QPDFObject::object_type_e
  67 +QPDF_Stream::getTypeCode() const
  68 +{
  69 + return QPDFObject::ot_stream;
  70 +}
  71 +
  72 +char const*
  73 +QPDF_Stream::getTypeName() const
  74 +{
  75 + return "stream";
  76 +}
  77 +
66 QPDFObjectHandle 78 QPDFObjectHandle
67 QPDF_Stream::getDict() const 79 QPDF_Stream::getDict() const
68 { 80 {
libqpdf/QPDF_String.cc
@@ -33,6 +33,18 @@ QPDF_String::unparse() @@ -33,6 +33,18 @@ QPDF_String::unparse()
33 return unparse(false); 33 return unparse(false);
34 } 34 }
35 35
  36 +QPDFObject::object_type_e
  37 +QPDF_String::getTypeCode() const
  38 +{
  39 + return QPDFObject::ot_string;
  40 +}
  41 +
  42 +char const*
  43 +QPDF_String::getTypeName() const
  44 +{
  45 + return "string";
  46 +}
  47 +
36 std::string 48 std::string
37 QPDF_String::unparse(bool force_binary) 49 QPDF_String::unparse(bool force_binary)
38 { 50 {
libqpdf/qpdf/QPDF_Array.hh
@@ -12,6 +12,8 @@ class QPDF_Array: public QPDFObject @@ -12,6 +12,8 @@ class QPDF_Array: public QPDFObject
12 QPDF_Array(std::vector<QPDFObjectHandle> const& items); 12 QPDF_Array(std::vector<QPDFObjectHandle> const& items);
13 virtual ~QPDF_Array(); 13 virtual ~QPDF_Array();
14 virtual std::string unparse(); 14 virtual std::string unparse();
  15 + virtual QPDFObject::object_type_e getTypeCode() const;
  16 + virtual char const* getTypeName() const;
15 17
16 int getNItems() const; 18 int getNItems() const;
17 QPDFObjectHandle getItem(int n) const; 19 QPDFObjectHandle getItem(int n) const;
libqpdf/qpdf/QPDF_Bool.hh
@@ -9,6 +9,8 @@ class QPDF_Bool: public QPDFObject @@ -9,6 +9,8 @@ class QPDF_Bool: public QPDFObject
9 QPDF_Bool(bool val); 9 QPDF_Bool(bool val);
10 virtual ~QPDF_Bool(); 10 virtual ~QPDF_Bool();
11 virtual std::string unparse(); 11 virtual std::string unparse();
  12 + virtual QPDFObject::object_type_e getTypeCode() const;
  13 + virtual char const* getTypeName() const;
12 bool getVal() const; 14 bool getVal() const;
13 15
14 private: 16 private:
libqpdf/qpdf/QPDF_Dictionary.hh
@@ -14,6 +14,8 @@ class QPDF_Dictionary: public QPDFObject @@ -14,6 +14,8 @@ class QPDF_Dictionary: public QPDFObject
14 QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items); 14 QPDF_Dictionary(std::map<std::string, QPDFObjectHandle> const& items);
15 virtual ~QPDF_Dictionary(); 15 virtual ~QPDF_Dictionary();
16 virtual std::string unparse(); 16 virtual std::string unparse();
  17 + virtual QPDFObject::object_type_e getTypeCode() const;
  18 + virtual char const* getTypeName() const;
17 19
18 // hasKey() and getKeys() treat keys with null values as if they 20 // hasKey() and getKeys() treat keys with null values as if they
19 // aren't there. getKey() returns null for the value of a 21 // aren't there. getKey() returns null for the value of a
libqpdf/qpdf/QPDF_InlineImage.hh
@@ -9,6 +9,8 @@ class QPDF_InlineImage: public QPDFObject @@ -9,6 +9,8 @@ class QPDF_InlineImage: public QPDFObject
9 QPDF_InlineImage(std::string const& val); 9 QPDF_InlineImage(std::string const& val);
10 virtual ~QPDF_InlineImage(); 10 virtual ~QPDF_InlineImage();
11 virtual std::string unparse(); 11 virtual std::string unparse();
  12 + virtual QPDFObject::object_type_e getTypeCode() const;
  13 + virtual char const* getTypeName() const;
12 std::string getVal() const; 14 std::string getVal() const;
13 15
14 private: 16 private:
libqpdf/qpdf/QPDF_Integer.hh
@@ -9,6 +9,8 @@ class QPDF_Integer: public QPDFObject @@ -9,6 +9,8 @@ class QPDF_Integer: public QPDFObject
9 QPDF_Integer(long long val); 9 QPDF_Integer(long long val);
10 virtual ~QPDF_Integer(); 10 virtual ~QPDF_Integer();
11 virtual std::string unparse(); 11 virtual std::string unparse();
  12 + virtual QPDFObject::object_type_e getTypeCode() const;
  13 + virtual char const* getTypeName() const;
12 long long getVal() const; 14 long long getVal() const;
13 15
14 private: 16 private:
libqpdf/qpdf/QPDF_Keyword.hh
@@ -9,6 +9,8 @@ class QPDF_Keyword: public QPDFObject @@ -9,6 +9,8 @@ class QPDF_Keyword: public QPDFObject
9 QPDF_Keyword(std::string const& val); 9 QPDF_Keyword(std::string const& val);
10 virtual ~QPDF_Keyword(); 10 virtual ~QPDF_Keyword();
11 virtual std::string unparse(); 11 virtual std::string unparse();
  12 + virtual QPDFObject::object_type_e getTypeCode() const;
  13 + virtual char const* getTypeName() const;
12 std::string getVal() const; 14 std::string getVal() const;
13 15
14 private: 16 private:
libqpdf/qpdf/QPDF_Name.hh
@@ -9,6 +9,8 @@ class QPDF_Name: public QPDFObject @@ -9,6 +9,8 @@ class QPDF_Name: public QPDFObject
9 QPDF_Name(std::string const& name); 9 QPDF_Name(std::string const& name);
10 virtual ~QPDF_Name(); 10 virtual ~QPDF_Name();
11 virtual std::string unparse(); 11 virtual std::string unparse();
  12 + virtual QPDFObject::object_type_e getTypeCode() const;
  13 + virtual char const* getTypeName() const;
12 std::string getName() const; 14 std::string getName() const;
13 15
14 // Put # into strings with characters unsuitable for name token 16 // Put # into strings with characters unsuitable for name token
libqpdf/qpdf/QPDF_Null.hh
@@ -8,6 +8,8 @@ class QPDF_Null: public QPDFObject @@ -8,6 +8,8 @@ class QPDF_Null: public QPDFObject
8 public: 8 public:
9 virtual ~QPDF_Null(); 9 virtual ~QPDF_Null();
10 virtual std::string unparse(); 10 virtual std::string unparse();
  11 + virtual QPDFObject::object_type_e getTypeCode() const;
  12 + virtual char const* getTypeName() const;
11 }; 13 };
12 14
13 #endif // __QPDF_NULL_HH__ 15 #endif // __QPDF_NULL_HH__
libqpdf/qpdf/QPDF_Real.hh
@@ -10,6 +10,8 @@ class QPDF_Real: public QPDFObject @@ -10,6 +10,8 @@ class QPDF_Real: public QPDFObject
10 QPDF_Real(double value, int decimal_places = 0); 10 QPDF_Real(double value, int decimal_places = 0);
11 virtual ~QPDF_Real(); 11 virtual ~QPDF_Real();
12 virtual std::string unparse(); 12 virtual std::string unparse();
  13 + virtual QPDFObject::object_type_e getTypeCode() const;
  14 + virtual char const* getTypeName() const;
13 std::string getVal(); 15 std::string getVal();
14 16
15 private: 17 private:
libqpdf/qpdf/QPDF_Reserved.hh
@@ -8,6 +8,8 @@ class QPDF_Reserved: public QPDFObject @@ -8,6 +8,8 @@ class QPDF_Reserved: public QPDFObject
8 public: 8 public:
9 virtual ~QPDF_Reserved(); 9 virtual ~QPDF_Reserved();
10 virtual std::string unparse(); 10 virtual std::string unparse();
  11 + virtual QPDFObject::object_type_e getTypeCode() const;
  12 + virtual char const* getTypeName() const;
11 }; 13 };
12 14
13 #endif // __QPDF_RESERVED_HH__ 15 #endif // __QPDF_RESERVED_HH__
libqpdf/qpdf/QPDF_Stream.hh
@@ -17,6 +17,8 @@ class QPDF_Stream: public QPDFObject @@ -17,6 +17,8 @@ class QPDF_Stream: public QPDFObject
17 qpdf_offset_t offset, size_t length); 17 qpdf_offset_t offset, size_t length);
18 virtual ~QPDF_Stream(); 18 virtual ~QPDF_Stream();
19 virtual std::string unparse(); 19 virtual std::string unparse();
  20 + virtual QPDFObject::object_type_e getTypeCode() const;
  21 + virtual char const* getTypeName() const;
20 QPDFObjectHandle getDict() const; 22 QPDFObjectHandle getDict() const;
21 23
22 // See comments in QPDFObjectHandle.hh for these methods. 24 // See comments in QPDFObjectHandle.hh for these methods.
libqpdf/qpdf/QPDF_String.hh
@@ -11,6 +11,8 @@ class QPDF_String: public QPDFObject @@ -11,6 +11,8 @@ class QPDF_String: public QPDFObject
11 QPDF_String(std::string const& val); 11 QPDF_String(std::string const& val);
12 virtual ~QPDF_String(); 12 virtual ~QPDF_String();
13 virtual std::string unparse(); 13 virtual std::string unparse();
  14 + virtual QPDFObject::object_type_e getTypeCode() const;
  15 + virtual char const* getTypeName() const;
14 std::string unparse(bool force_binary); 16 std::string unparse(bool force_binary);
15 std::string getVal() const; 17 std::string getVal() const;
16 std::string getUTF8Val() const; 18 std::string getUTF8Val() const;
qpdf/qtest/qpdf/eof-in-inline-image.out
1 -BT  
2 -/F1  
3 -24  
4 -Tf  
5 -72  
6 -720  
7 -Td  
8 -(Potato)  
9 -Tj  
10 -ET  
11 -BI  
12 -/CS  
13 -/G  
14 -/W  
15 -1  
16 -/H  
17 -1  
18 -/BPC  
19 -8  
20 -/F  
21 -/Fl  
22 -/DP  
23 -<< /Columns 1 /Predictor 15 >>  
24 -ID 1 +keyword: BT
  2 +name: /F1
  3 +integer: 24
  4 +keyword: Tf
  5 +integer: 72
  6 +integer: 720
  7 +keyword: Td
  8 +string: (Potato)
  9 +keyword: Tj
  10 +keyword: ET
  11 +keyword: BI
  12 +name: /CS
  13 +name: /G
  14 +name: /W
  15 +integer: 1
  16 +name: /H
  17 +integer: 1
  18 +name: /BPC
  19 +integer: 8
  20 +name: /F
  21 +name: /Fl
  22 +name: /DP
  23 +dictionary: << /Columns 1 /Predictor 15 >>
  24 +keyword: ID
25 content stream object 4 0 (stream data, file position 139): EOF found while reading inline image 25 content stream object 4 0 (stream data, file position 139): EOF found while reading inline image
qpdf/qtest/qpdf/tokenize-content-streams.out
1 -BT  
2 -/F1  
3 -24  
4 -Tf  
5 -72  
6 -720  
7 -Td  
8 -(Potato)  
9 -Tj  
10 -ET 1 +keyword: BT
  2 +name: /F1
  3 +integer: 24
  4 +keyword: Tf
  5 +integer: 72
  6 +integer: 720
  7 +keyword: Td
  8 +string: (Potato)
  9 +keyword: Tj
  10 +keyword: ET
11 -EOF- 11 -EOF-
12 -0.1  
13 -0  
14 -0  
15 -0.1  
16 -0  
17 -0  
18 -cm  
19 -q  
20 -0  
21 -1.1999  
22 --1.1999  
23 -0  
24 -121.19  
25 -150.009  
26 -cm  
27 -BI  
28 -/CS  
29 -/G  
30 -/W  
31 -1  
32 -/H  
33 -1  
34 -/BPC  
35 -8  
36 -/F  
37 -/Fl  
38 -/DP  
39 -<< /Columns 1 /Predictor 15 >>  
40 -ID  
41 -inline image: 789c63fc0f0001030101  
42 -EI  
43 -Q  
44 -q  
45 -0  
46 -35.997  
47 --128.389  
48 -0  
49 -431.964  
50 -7269.02  
51 -cm  
52 -BI  
53 -/CS  
54 -/G  
55 -/W  
56 -30  
57 -/H  
58 -107  
59 -/BPC  
60 -8  
61 -/F  
62 -/Fl  
63 -/DP  
64 -<< /Columns 30 /Predictor 15 >>  
65 -ID  
66 -inline image: 789cedd1a11100300800b1b2ffd06503148283bc8dfcf8af2a306ee352eff2e06318638c31c63b3801627b620a  
67 -EI  
68 -Q  
69 -q  
70 -0  
71 -38.3968  
72 --93.5922  
73 -0  
74 -431.964  
75 -7567.79  
76 -cm  
77 -BI  
78 -/CS  
79 -/G  
80 -/W  
81 -32  
82 -/H  
83 -78  
84 -/BPC  
85 -8  
86 -/F  
87 -/Fl  
88 -/DP  
89 -<< /Columns 32 /Predictor 15 >>  
90 -ID  
91 -inline image: 789c63fccf801f308e2a185530aa60882a20203faa605401890a0643aa1e5530aa6054010d140000bdd03c13  
92 -EI  
93 -Q 12 +real: 0.1
  13 +integer: 0
  14 +integer: 0
  15 +real: 0.1
  16 +integer: 0
  17 +integer: 0
  18 +keyword: cm
  19 +keyword: q
  20 +integer: 0
  21 +real: 1.1999
  22 +real: -1.1999
  23 +integer: 0
  24 +real: 121.19
  25 +real: 150.009
  26 +keyword: cm
  27 +keyword: BI
  28 +name: /CS
  29 +name: /G
  30 +name: /W
  31 +integer: 1
  32 +name: /H
  33 +integer: 1
  34 +name: /BPC
  35 +integer: 8
  36 +name: /F
  37 +name: /Fl
  38 +name: /DP
  39 +dictionary: << /Columns 1 /Predictor 15 >>
  40 +keyword: ID
  41 +inline-image: 789c63fc0f0001030101
  42 +keyword: EI
  43 +keyword: Q
  44 +keyword: q
  45 +integer: 0
  46 +real: 35.997
  47 +real: -128.389
  48 +integer: 0
  49 +real: 431.964
  50 +real: 7269.02
  51 +keyword: cm
  52 +keyword: BI
  53 +name: /CS
  54 +name: /G
  55 +name: /W
  56 +integer: 30
  57 +name: /H
  58 +integer: 107
  59 +name: /BPC
  60 +integer: 8
  61 +name: /F
  62 +name: /Fl
  63 +name: /DP
  64 +dictionary: << /Columns 30 /Predictor 15 >>
  65 +keyword: ID
  66 +inline-image: 789cedd1a11100300800b1b2ffd06503148283bc8dfcf8af2a306ee352eff2e06318638c31c63b3801627b620a
  67 +keyword: EI
  68 +keyword: Q
  69 +keyword: q
  70 +integer: 0
  71 +real: 38.3968
  72 +real: -93.5922
  73 +integer: 0
  74 +real: 431.964
  75 +real: 7567.79
  76 +keyword: cm
  77 +keyword: BI
  78 +name: /CS
  79 +name: /G
  80 +name: /W
  81 +integer: 32
  82 +name: /H
  83 +integer: 78
  84 +name: /BPC
  85 +integer: 8
  86 +name: /F
  87 +name: /Fl
  88 +name: /DP
  89 +dictionary: << /Columns 32 /Predictor 15 >>
  90 +keyword: ID
  91 +inline-image: 789c63fccf801f308e2a185530aa60882a20203faa605401890a0643aa1e5530aa6054010d140000bdd03c13
  92 +keyword: EI
  93 +keyword: Q
94 -EOF- 94 -EOF-
95 test 37 done 95 test 37 done
qpdf/test_driver.cc
@@ -72,10 +72,11 @@ class ParserCallbacks: public QPDFObjectHandle::ParserCallbacks @@ -72,10 +72,11 @@ class ParserCallbacks: public QPDFObjectHandle::ParserCallbacks
72 void 72 void
73 ParserCallbacks::handleObject(QPDFObjectHandle obj) 73 ParserCallbacks::handleObject(QPDFObjectHandle obj)
74 { 74 {
  75 + std::cout << obj.getTypeName() << ": ";
75 if (obj.isInlineImage()) 76 if (obj.isInlineImage())
76 { 77 {
  78 + assert(obj.getTypeCode() == QPDFObject::ot_inlineimage);
77 std::string val = obj.getInlineImageValue(); 79 std::string val = obj.getInlineImageValue();
78 - std::cout << "inline image: ";  
79 char buf[3]; 80 char buf[3];
80 buf[2] = '\0'; 81 buf[2] = '\0';
81 for (size_t i = 0; i < val.length(); ++i) 82 for (size_t i = 0; i < val.length(); ++i)
@@ -142,6 +143,10 @@ void runtest(int n, char const* filename1, char const* arg2) @@ -142,6 +143,10 @@ void runtest(int n, char const* filename1, char const* arg2)
142 assert(password.length() == 32); 143 assert(password.length() == 32);
143 QPDF::trim_user_password(password); 144 QPDF::trim_user_password(password);
144 assert(password == "1234567890123456789012(45678"); 145 assert(password == "1234567890123456789012(45678");
  146 +
  147 + QPDFObjectHandle uninitialized;
  148 + assert(uninitialized.getTypeCode() == QPDFObject::ot_uninitialized);
  149 + assert(strcmp(uninitialized.getTypeName(), "uninitialized") == 0);
145 } 150 }
146 151
147 QPDF pdf; 152 QPDF pdf;