Commit 15eaed5c52c85dd97ce5bc829817c5535c527207

Authored by Jay Berkenbilt
1 parent 8657c6f0

Refactor: pull *InputSource out of QPDF

InputSource, FileInputSource, and BufferInputSource are now top-level
classes instead of privately nested inside QPDF.
include/qpdf/BufferInputSource.hh 0 โ†’ 100644
  1 +#ifndef __QPDF_BUFFERINPUTSOURCE_HH__
  2 +#define __QPDF_BUFFERINPUTSOURCE_HH__
  3 +
  4 +#include <qpdf/InputSource.hh>
  5 +#include <qpdf/Buffer.hh>
  6 +
  7 +class BufferInputSource: public InputSource
  8 +{
  9 + public:
  10 + BufferInputSource(std::string const& description, Buffer* buf,
  11 + bool own_memory = false);
  12 + virtual ~BufferInputSource();
  13 + virtual qpdf_offset_t findAndSkipNextEOL();
  14 + virtual std::string const& getName() const;
  15 + virtual qpdf_offset_t tell();
  16 + virtual void seek(qpdf_offset_t offset, int whence);
  17 + virtual void rewind();
  18 + virtual size_t read(char* buffer, size_t length);
  19 + virtual void unreadCh(char ch);
  20 +
  21 + private:
  22 + bool own_memory;
  23 + std::string description;
  24 + Buffer* buf;
  25 + qpdf_offset_t cur_offset;
  26 +};
  27 +
  28 +#endif // __QPDF_BUFFERINPUTSOURCE_HH__
include/qpdf/FileInputSource.hh 0 โ†’ 100644
  1 +#ifndef __QPDF_FILEINPUTSOURCE_HH__
  2 +#define __QPDF_FILEINPUTSOURCE_HH__
  3 +
  4 +#include <qpdf/InputSource.hh>
  5 +
  6 +class FileInputSource: public InputSource
  7 +{
  8 + public:
  9 + FileInputSource();
  10 + void setFilename(char const* filename);
  11 + void setFile(char const* description, FILE* filep, bool close_file);
  12 + virtual ~FileInputSource();
  13 + virtual qpdf_offset_t findAndSkipNextEOL();
  14 + virtual std::string const& getName() const;
  15 + virtual qpdf_offset_t tell();
  16 + virtual void seek(qpdf_offset_t offset, int whence);
  17 + virtual void rewind();
  18 + virtual size_t read(char* buffer, size_t length);
  19 + virtual void unreadCh(char ch);
  20 +
  21 + private:
  22 + FileInputSource(FileInputSource const&);
  23 + FileInputSource& operator=(FileInputSource const&);
  24 +
  25 + void destroy();
  26 +
  27 + bool close_file;
  28 + std::string filename;
  29 + FILE* file;
  30 +};
  31 +
  32 +#endif // __QPDF_FILEINPUTSOURCE_HH__
include/qpdf/InputSource.hh 0 โ†’ 100644
  1 +#ifndef __QPDF_INPUTSOURCE_HH__
  2 +#define __QPDF_INPUTSOURCE_HH__
  3 +
  4 +#include <qpdf/Types.h>
  5 +#include <stdio.h>
  6 +#include <string>
  7 +
  8 +class InputSource
  9 +{
  10 + public:
  11 + InputSource() :
  12 + last_offset(0)
  13 + {
  14 + }
  15 + virtual ~InputSource()
  16 + {
  17 + }
  18 +
  19 + void setLastOffset(qpdf_offset_t);
  20 + qpdf_offset_t getLastOffset() const;
  21 + std::string readLine(size_t max_line_length);
  22 +
  23 + virtual qpdf_offset_t findAndSkipNextEOL() = 0;
  24 + virtual std::string const& getName() const = 0;
  25 + virtual qpdf_offset_t tell() = 0;
  26 + virtual void seek(qpdf_offset_t offset, int whence) = 0;
  27 + virtual void rewind() = 0;
  28 + virtual size_t read(char* buffer, size_t length) = 0;
  29 + virtual void unreadCh(char ch) = 0;
  30 +
  31 + protected:
  32 + qpdf_offset_t last_offset;
  33 +};
  34 +
  35 +#endif // __QPDF_INPUTSOURCE_HH__
include/qpdf/QPDF.hh
@@ -21,6 +21,7 @@ @@ -21,6 +21,7 @@
21 #include <qpdf/QPDFObjectHandle.hh> 21 #include <qpdf/QPDFObjectHandle.hh>
22 #include <qpdf/QPDFTokenizer.hh> 22 #include <qpdf/QPDFTokenizer.hh>
23 #include <qpdf/Buffer.hh> 23 #include <qpdf/Buffer.hh>
  24 +#include <qpdf/InputSource.hh>
24 25
25 class QPDF_Stream; 26 class QPDF_Stream;
26 class BitStream; 27 class BitStream;
@@ -474,80 +475,6 @@ class QPDF @@ -474,80 +475,6 @@ class QPDF
474 private: 475 private:
475 static std::string qpdf_version; 476 static std::string qpdf_version;
476 477
477 - class InputSource  
478 - {  
479 - public:  
480 - InputSource() :  
481 - last_offset(0)  
482 - {  
483 - }  
484 - virtual ~InputSource()  
485 - {  
486 - }  
487 -  
488 - void setLastOffset(qpdf_offset_t);  
489 - qpdf_offset_t getLastOffset() const;  
490 - std::string readLine(size_t max_line_length);  
491 -  
492 - virtual qpdf_offset_t findAndSkipNextEOL() = 0;  
493 - virtual std::string const& getName() const = 0;  
494 - virtual qpdf_offset_t tell() = 0;  
495 - virtual void seek(qpdf_offset_t offset, int whence) = 0;  
496 - virtual void rewind() = 0;  
497 - virtual size_t read(char* buffer, size_t length) = 0;  
498 - virtual void unreadCh(char ch) = 0;  
499 -  
500 - protected:  
501 - qpdf_offset_t last_offset;  
502 - };  
503 -  
504 - class FileInputSource: public InputSource  
505 - {  
506 - public:  
507 - FileInputSource();  
508 - void setFilename(char const* filename);  
509 - void setFile(char const* description, FILE* filep, bool close_file);  
510 - virtual ~FileInputSource();  
511 - virtual qpdf_offset_t findAndSkipNextEOL();  
512 - virtual std::string const& getName() const;  
513 - virtual qpdf_offset_t tell();  
514 - virtual void seek(qpdf_offset_t offset, int whence);  
515 - virtual void rewind();  
516 - virtual size_t read(char* buffer, size_t length);  
517 - virtual void unreadCh(char ch);  
518 -  
519 - private:  
520 - FileInputSource(FileInputSource const&);  
521 - FileInputSource& operator=(FileInputSource const&);  
522 -  
523 - void destroy();  
524 -  
525 - bool close_file;  
526 - std::string filename;  
527 - FILE* file;  
528 - };  
529 -  
530 - class BufferInputSource: public InputSource  
531 - {  
532 - public:  
533 - BufferInputSource(std::string const& description, Buffer* buf,  
534 - bool own_memory = false);  
535 - virtual ~BufferInputSource();  
536 - virtual qpdf_offset_t findAndSkipNextEOL();  
537 - virtual std::string const& getName() const;  
538 - virtual qpdf_offset_t tell();  
539 - virtual void seek(qpdf_offset_t offset, int whence);  
540 - virtual void rewind();  
541 - virtual size_t read(char* buffer, size_t length);  
542 - virtual void unreadCh(char ch);  
543 -  
544 - private:  
545 - bool own_memory;  
546 - std::string description;  
547 - Buffer* buf;  
548 - qpdf_offset_t cur_offset;  
549 - };  
550 -  
551 class ObjGen 478 class ObjGen
552 { 479 {
553 public: 480 public:
libqpdf/BufferInputSource.cc 0 โ†’ 100644
  1 +#include <qpdf/BufferInputSource.hh>
  2 +#include <string.h>
  3 +#include <stdexcept>
  4 +
  5 +BufferInputSource::BufferInputSource(std::string const& description,
  6 + Buffer* buf, bool own_memory) :
  7 + own_memory(own_memory),
  8 + description(description),
  9 + buf(buf),
  10 + cur_offset(0)
  11 +{
  12 +}
  13 +
  14 +BufferInputSource::~BufferInputSource()
  15 +{
  16 + if (own_memory)
  17 + {
  18 + delete this->buf;
  19 + }
  20 +}
  21 +
  22 +qpdf_offset_t
  23 +BufferInputSource::findAndSkipNextEOL()
  24 +{
  25 + if (this->cur_offset < 0)
  26 + {
  27 + throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
  28 + }
  29 + qpdf_offset_t end_pos = (qpdf_offset_t) this->buf->getSize();
  30 + if (this->cur_offset >= end_pos)
  31 + {
  32 + this->last_offset = end_pos;
  33 + this->cur_offset = end_pos;
  34 + return end_pos;
  35 + }
  36 +
  37 + qpdf_offset_t result = 0;
  38 + size_t len = (size_t)(end_pos - this->cur_offset);
  39 + unsigned char const* buffer = this->buf->getBuffer();
  40 +
  41 + void* start = (void*)(buffer + this->cur_offset);
  42 + unsigned char* p1 = (unsigned char*)memchr(start, '\r', len);
  43 + unsigned char* p2 = (unsigned char*)memchr(start, '\n', len);
  44 + unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
  45 + if (p)
  46 + {
  47 + result = p - buffer;
  48 + this->cur_offset = result + 1;
  49 + ++p;
  50 + while ((this->cur_offset < end_pos) &&
  51 + ((*p == '\r') || (*p == '\n')))
  52 + {
  53 + ++p;
  54 + ++this->cur_offset;
  55 + }
  56 + }
  57 + else
  58 + {
  59 + this->cur_offset = end_pos;
  60 + result = end_pos;
  61 + }
  62 + return result;
  63 +}
  64 +
  65 +std::string const&
  66 +BufferInputSource::getName() const
  67 +{
  68 + return this->description;
  69 +}
  70 +
  71 +qpdf_offset_t
  72 +BufferInputSource::tell()
  73 +{
  74 + return this->cur_offset;
  75 +}
  76 +
  77 +void
  78 +BufferInputSource::seek(qpdf_offset_t offset, int whence)
  79 +{
  80 + switch (whence)
  81 + {
  82 + case SEEK_SET:
  83 + this->cur_offset = offset;
  84 + break;
  85 +
  86 + case SEEK_END:
  87 + this->cur_offset = (qpdf_offset_t)this->buf->getSize() + offset;
  88 + break;
  89 +
  90 + case SEEK_CUR:
  91 + this->cur_offset += offset;
  92 + break;
  93 +
  94 + default:
  95 + throw std::logic_error(
  96 + "INTERNAL ERROR: invalid argument to BufferInputSource::seek");
  97 + break;
  98 + }
  99 +
  100 + if (this->cur_offset < 0)
  101 + {
  102 + throw std::runtime_error(
  103 + this->description + ": seek before beginning of buffer");
  104 + }
  105 +}
  106 +
  107 +void
  108 +BufferInputSource::rewind()
  109 +{
  110 + this->cur_offset = 0;
  111 +}
  112 +
  113 +size_t
  114 +BufferInputSource::read(char* buffer, size_t length)
  115 +{
  116 + if (this->cur_offset < 0)
  117 + {
  118 + throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");
  119 + }
  120 + qpdf_offset_t end_pos = (qpdf_offset_t) this->buf->getSize();
  121 + if (this->cur_offset >= end_pos)
  122 + {
  123 + this->last_offset = end_pos;
  124 + return 0;
  125 + }
  126 +
  127 + this->last_offset = this->cur_offset;
  128 + size_t len = std::min((size_t)(end_pos - this->cur_offset), length);
  129 + memcpy(buffer, buf->getBuffer() + this->cur_offset, len);
  130 + this->cur_offset += len;
  131 + return len;
  132 +}
  133 +
  134 +void
  135 +BufferInputSource::unreadCh(char ch)
  136 +{
  137 + if (this->cur_offset > 0)
  138 + {
  139 + --this->cur_offset;
  140 + }
  141 +}
libqpdf/FileInputSource.cc 0 โ†’ 100644
  1 +#include <qpdf/FileInputSource.hh>
  2 +#include <string.h>
  3 +#include <qpdf/QUtil.hh>
  4 +#include <qpdf/QPDFExc.hh>
  5 +
  6 +FileInputSource::FileInputSource() :
  7 + close_file(false),
  8 + file(0)
  9 +{
  10 +}
  11 +
  12 +void
  13 +FileInputSource::setFilename(char const* filename)
  14 +{
  15 + destroy();
  16 + this->filename = filename;
  17 + this->close_file = true;
  18 + this->file = QUtil::fopen_wrapper(std::string("open ") + this->filename,
  19 + fopen(this->filename.c_str(), "rb"));
  20 +}
  21 +
  22 +void
  23 +FileInputSource::setFile(
  24 + char const* description, FILE* filep, bool close_file)
  25 +{
  26 + destroy();
  27 + this->filename = description;
  28 + this->close_file = close_file;
  29 + this->file = filep;
  30 + this->seek(0, SEEK_SET);
  31 +}
  32 +
  33 +FileInputSource::~FileInputSource()
  34 +{
  35 + destroy();
  36 +}
  37 +
  38 +void
  39 +FileInputSource::destroy()
  40 +{
  41 + if (this->file && this->close_file)
  42 + {
  43 + fclose(this->file);
  44 + this->file = 0;
  45 + }
  46 +}
  47 +
  48 +qpdf_offset_t
  49 +FileInputSource::findAndSkipNextEOL()
  50 +{
  51 + qpdf_offset_t result = 0;
  52 + bool done = false;
  53 + char buf[10240];
  54 + while (! done)
  55 + {
  56 + qpdf_offset_t cur_offset = QUtil::tell(this->file);
  57 + size_t len = this->read(buf, sizeof(buf));
  58 + if (len == 0)
  59 + {
  60 + done = true;
  61 + result = this->tell();
  62 + }
  63 + else
  64 + {
  65 + char* p1 = (char*)memchr((void*)buf, '\r', len);
  66 + char* p2 = (char*)memchr((void*)buf, '\n', len);
  67 + char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;
  68 + if (p)
  69 + {
  70 + result = cur_offset + (p - buf);
  71 + // We found \r or \n. Keep reading until we get past
  72 + // \r and \n characters.
  73 + this->seek(result + 1, SEEK_SET);
  74 + char ch;
  75 + while (! done)
  76 + {
  77 + if (this->read(&ch, 1) == 0)
  78 + {
  79 + done = true;
  80 + }
  81 + else if (! ((ch == '\r') || (ch == '\n')))
  82 + {
  83 + this->unreadCh(ch);
  84 + done = true;
  85 + }
  86 + }
  87 + }
  88 + }
  89 + }
  90 + return result;
  91 +}
  92 +
  93 +std::string const&
  94 +FileInputSource::getName() const
  95 +{
  96 + return this->filename;
  97 +}
  98 +
  99 +qpdf_offset_t
  100 +FileInputSource::tell()
  101 +{
  102 + return QUtil::tell(this->file);
  103 +}
  104 +
  105 +void
  106 +FileInputSource::seek(qpdf_offset_t offset, int whence)
  107 +{
  108 + QUtil::os_wrapper(std::string("seek to ") + this->filename + ", offset " +
  109 + QUtil::int_to_string(offset) + " (" +
  110 + QUtil::int_to_string(whence) + ")",
  111 + QUtil::seek(this->file, offset, whence));
  112 +}
  113 +
  114 +void
  115 +FileInputSource::rewind()
  116 +{
  117 + ::rewind(this->file);
  118 +}
  119 +
  120 +size_t
  121 +FileInputSource::read(char* buffer, size_t length)
  122 +{
  123 + this->last_offset = QUtil::tell(this->file);
  124 + size_t len = fread(buffer, 1, length, this->file);
  125 + if ((len == 0) && ferror(this->file))
  126 + {
  127 + throw QPDFExc(qpdf_e_system,
  128 + this->filename, "",
  129 + this->last_offset,
  130 + std::string("read ") +
  131 + QUtil::int_to_string(length) + " bytes");
  132 + }
  133 + return len;
  134 +}
  135 +
  136 +void
  137 +FileInputSource::unreadCh(char ch)
  138 +{
  139 + QUtil::os_wrapper(this->filename + ": unread character",
  140 + ungetc((unsigned char)ch, this->file));
  141 +}
libqpdf/InputSource.cc 0 โ†’ 100644
  1 +#include <qpdf/InputSource.hh>
  2 +#include <string.h>
  3 +#include <qpdf/PointerHolder.hh>
  4 +
  5 +void
  6 +InputSource::setLastOffset(qpdf_offset_t offset)
  7 +{
  8 + this->last_offset = offset;
  9 +}
  10 +
  11 +qpdf_offset_t
  12 +InputSource::getLastOffset() const
  13 +{
  14 + return this->last_offset;
  15 +}
  16 +
  17 +std::string
  18 +InputSource::readLine(size_t max_line_length)
  19 +{
  20 + // Return at most max_line_length characters from the next line.
  21 + // Lines are terminated by one or more \r or \n characters.
  22 + // Consume the trailing newline characters but don't return them.
  23 + // After this is called, the file will be positioned after a line
  24 + // terminator or at the end of the file, and last_offset will
  25 + // point to position the file had when this method was called.
  26 +
  27 + qpdf_offset_t offset = this->tell();
  28 + char* buf = new char[max_line_length + 1];
  29 + PointerHolder<char> bp(true, buf);
  30 + memset(buf, '\0', max_line_length + 1);
  31 + this->read(buf, max_line_length);
  32 + this->seek(offset, SEEK_SET);
  33 + qpdf_offset_t eol = this->findAndSkipNextEOL();
  34 + this->last_offset = offset;
  35 + size_t line_length = eol - offset;
  36 + if (line_length < max_line_length)
  37 + {
  38 + buf[line_length] = '\0';
  39 + }
  40 + return std::string(buf);
  41 +}
libqpdf/QPDF.cc
@@ -11,6 +11,8 @@ @@ -11,6 +11,8 @@
11 #include <qpdf/PCRE.hh> 11 #include <qpdf/PCRE.hh>
12 #include <qpdf/Pipeline.hh> 12 #include <qpdf/Pipeline.hh>
13 #include <qpdf/Pl_Discard.hh> 13 #include <qpdf/Pl_Discard.hh>
  14 +#include <qpdf/FileInputSource.hh>
  15 +#include <qpdf/BufferInputSource.hh>
14 16
15 #include <qpdf/QPDFExc.hh> 17 #include <qpdf/QPDFExc.hh>
16 #include <qpdf/QPDF_Null.hh> 18 #include <qpdf/QPDF_Null.hh>
@@ -36,318 +38,6 @@ static char const* EMPTY_PDF = @@ -36,318 +38,6 @@ static char const* EMPTY_PDF =
36 "110\n" 38 "110\n"
37 "%%EOF\n"; 39 "%%EOF\n";
38 40
39 -void  
40 -QPDF::InputSource::setLastOffset(qpdf_offset_t offset)  
41 -{  
42 - this->last_offset = offset;  
43 -}  
44 -  
45 -qpdf_offset_t  
46 -QPDF::InputSource::getLastOffset() const  
47 -{  
48 - return this->last_offset;  
49 -}  
50 -  
51 -std::string  
52 -QPDF::InputSource::readLine(size_t max_line_length)  
53 -{  
54 - // Return at most max_line_length characters from the next line.  
55 - // Lines are terminated by one or more \r or \n characters.  
56 - // Consume the trailing newline characters but don't return them.  
57 - // After this is called, the file will be positioned after a line  
58 - // terminator or at the end of the file, and last_offset will  
59 - // point to position the file had when this method was called.  
60 -  
61 - qpdf_offset_t offset = this->tell();  
62 - char* buf = new char[max_line_length + 1];  
63 - PointerHolder<char> bp(true, buf);  
64 - memset(buf, '\0', max_line_length + 1);  
65 - this->read(buf, max_line_length);  
66 - this->seek(offset, SEEK_SET);  
67 - qpdf_offset_t eol = this->findAndSkipNextEOL();  
68 - this->last_offset = offset;  
69 - size_t line_length = eol - offset;  
70 - if (line_length < max_line_length)  
71 - {  
72 - buf[line_length] = '\0';  
73 - }  
74 - return std::string(buf);  
75 -}  
76 -  
77 -QPDF::FileInputSource::FileInputSource() :  
78 - close_file(false),  
79 - file(0)  
80 -{  
81 -}  
82 -  
83 -void  
84 -QPDF::FileInputSource::setFilename(char const* filename)  
85 -{  
86 - destroy();  
87 - this->filename = filename;  
88 - this->close_file = true;  
89 - this->file = QUtil::fopen_wrapper(std::string("open ") + this->filename,  
90 - fopen(this->filename.c_str(), "rb"));  
91 -}  
92 -  
93 -void  
94 -QPDF::FileInputSource::setFile(  
95 - char const* description, FILE* filep, bool close_file)  
96 -{  
97 - destroy();  
98 - this->filename = description;  
99 - this->close_file = close_file;  
100 - this->file = filep;  
101 - this->seek(0, SEEK_SET);  
102 -}  
103 -  
104 -QPDF::FileInputSource::~FileInputSource()  
105 -{  
106 - destroy();  
107 -}  
108 -  
109 -void  
110 -QPDF::FileInputSource::destroy()  
111 -{  
112 - if (this->file && this->close_file)  
113 - {  
114 - fclose(this->file);  
115 - this->file = 0;  
116 - }  
117 -}  
118 -  
119 -qpdf_offset_t  
120 -QPDF::FileInputSource::findAndSkipNextEOL()  
121 -{  
122 - qpdf_offset_t result = 0;  
123 - bool done = false;  
124 - char buf[10240];  
125 - while (! done)  
126 - {  
127 - qpdf_offset_t cur_offset = QUtil::tell(this->file);  
128 - size_t len = this->read(buf, sizeof(buf));  
129 - if (len == 0)  
130 - {  
131 - done = true;  
132 - result = this->tell();  
133 - }  
134 - else  
135 - {  
136 - char* p1 = (char*)memchr((void*)buf, '\r', len);  
137 - char* p2 = (char*)memchr((void*)buf, '\n', len);  
138 - char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;  
139 - if (p)  
140 - {  
141 - result = cur_offset + (p - buf);  
142 - // We found \r or \n. Keep reading until we get past  
143 - // \r and \n characters.  
144 - this->seek(result + 1, SEEK_SET);  
145 - char ch;  
146 - while (! done)  
147 - {  
148 - if (this->read(&ch, 1) == 0)  
149 - {  
150 - done = true;  
151 - }  
152 - else if (! ((ch == '\r') || (ch == '\n')))  
153 - {  
154 - this->unreadCh(ch);  
155 - done = true;  
156 - }  
157 - }  
158 - }  
159 - }  
160 - }  
161 - return result;  
162 -}  
163 -  
164 -std::string const&  
165 -QPDF::FileInputSource::getName() const  
166 -{  
167 - return this->filename;  
168 -}  
169 -  
170 -qpdf_offset_t  
171 -QPDF::FileInputSource::tell()  
172 -{  
173 - return QUtil::tell(this->file);  
174 -}  
175 -  
176 -void  
177 -QPDF::FileInputSource::seek(qpdf_offset_t offset, int whence)  
178 -{  
179 - QUtil::os_wrapper(std::string("seek to ") + this->filename + ", offset " +  
180 - QUtil::int_to_string(offset) + " (" +  
181 - QUtil::int_to_string(whence) + ")",  
182 - QUtil::seek(this->file, offset, whence));  
183 -}  
184 -  
185 -void  
186 -QPDF::FileInputSource::rewind()  
187 -{  
188 - ::rewind(this->file);  
189 -}  
190 -  
191 -size_t  
192 -QPDF::FileInputSource::read(char* buffer, size_t length)  
193 -{  
194 - this->last_offset = QUtil::tell(this->file);  
195 - size_t len = fread(buffer, 1, length, this->file);  
196 - if ((len == 0) && ferror(this->file))  
197 - {  
198 - throw QPDFExc(qpdf_e_system,  
199 - this->filename, "",  
200 - this->last_offset,  
201 - std::string("read ") +  
202 - QUtil::int_to_string(length) + " bytes");  
203 - }  
204 - return len;  
205 -}  
206 -  
207 -void  
208 -QPDF::FileInputSource::unreadCh(char ch)  
209 -{  
210 - QUtil::os_wrapper(this->filename + ": unread character",  
211 - ungetc((unsigned char)ch, this->file));  
212 -}  
213 -  
214 -QPDF::BufferInputSource::BufferInputSource(std::string const& description,  
215 - Buffer* buf, bool own_memory) :  
216 - own_memory(own_memory),  
217 - description(description),  
218 - buf(buf),  
219 - cur_offset(0)  
220 -{  
221 -}  
222 -  
223 -QPDF::BufferInputSource::~BufferInputSource()  
224 -{  
225 - if (own_memory)  
226 - {  
227 - delete this->buf;  
228 - }  
229 -}  
230 -  
231 -qpdf_offset_t  
232 -QPDF::BufferInputSource::findAndSkipNextEOL()  
233 -{  
234 - if (this->cur_offset < 0)  
235 - {  
236 - throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");  
237 - }  
238 - qpdf_offset_t end_pos = (qpdf_offset_t) this->buf->getSize();  
239 - if (this->cur_offset >= end_pos)  
240 - {  
241 - this->last_offset = end_pos;  
242 - this->cur_offset = end_pos;  
243 - return end_pos;  
244 - }  
245 -  
246 - qpdf_offset_t result = 0;  
247 - size_t len = (size_t)(end_pos - this->cur_offset);  
248 - unsigned char const* buffer = this->buf->getBuffer();  
249 -  
250 - void* start = (void*)(buffer + this->cur_offset);  
251 - unsigned char* p1 = (unsigned char*)memchr(start, '\r', len);  
252 - unsigned char* p2 = (unsigned char*)memchr(start, '\n', len);  
253 - unsigned char* p = (p1 && p2) ? std::min(p1, p2) : p1 ? p1 : p2;  
254 - if (p)  
255 - {  
256 - result = p - buffer;  
257 - this->cur_offset = result + 1;  
258 - ++p;  
259 - while ((this->cur_offset < end_pos) &&  
260 - ((*p == '\r') || (*p == '\n')))  
261 - {  
262 - ++p;  
263 - ++this->cur_offset;  
264 - }  
265 - }  
266 - else  
267 - {  
268 - this->cur_offset = end_pos;  
269 - result = end_pos;  
270 - }  
271 - return result;  
272 -}  
273 -  
274 -std::string const&  
275 -QPDF::BufferInputSource::getName() const  
276 -{  
277 - return this->description;  
278 -}  
279 -  
280 -qpdf_offset_t  
281 -QPDF::BufferInputSource::tell()  
282 -{  
283 - return this->cur_offset;  
284 -}  
285 -  
286 -void  
287 -QPDF::BufferInputSource::seek(qpdf_offset_t offset, int whence)  
288 -{  
289 - switch (whence)  
290 - {  
291 - case SEEK_SET:  
292 - this->cur_offset = offset;  
293 - break;  
294 -  
295 - case SEEK_END:  
296 - this->cur_offset = (qpdf_offset_t)this->buf->getSize() + offset;  
297 - break;  
298 -  
299 - case SEEK_CUR:  
300 - this->cur_offset += offset;  
301 - break;  
302 -  
303 - default:  
304 - throw std::logic_error(  
305 - "INTERNAL ERROR: invalid argument to BufferInputSource::seek");  
306 - break;  
307 - }  
308 -  
309 - if (this->cur_offset < 0)  
310 - {  
311 - throw std::runtime_error(  
312 - this->description + ": seek before beginning of buffer");  
313 - }  
314 -}  
315 -  
316 -void  
317 -QPDF::BufferInputSource::rewind()  
318 -{  
319 - this->cur_offset = 0;  
320 -}  
321 -  
322 -size_t  
323 -QPDF::BufferInputSource::read(char* buffer, size_t length)  
324 -{  
325 - if (this->cur_offset < 0)  
326 - {  
327 - throw std::logic_error("INTERNAL ERROR: BufferInputSource offset < 0");  
328 - }  
329 - qpdf_offset_t end_pos = (qpdf_offset_t) this->buf->getSize();  
330 - if (this->cur_offset >= end_pos)  
331 - {  
332 - this->last_offset = end_pos;  
333 - return 0;  
334 - }  
335 -  
336 - this->last_offset = this->cur_offset;  
337 - size_t len = std::min((size_t)(end_pos - this->cur_offset), length);  
338 - memcpy(buffer, buf->getBuffer() + this->cur_offset, len);  
339 - this->cur_offset += len;  
340 - return len;  
341 -}  
342 -  
343 -void  
344 -QPDF::BufferInputSource::unreadCh(char ch)  
345 -{  
346 - if (this->cur_offset > 0)  
347 - {  
348 - --this->cur_offset;  
349 - }  
350 -}  
351 41
352 QPDF::ObjGen::ObjGen(int o = 0, int g = 0) : 42 QPDF::ObjGen::ObjGen(int o = 0, int g = 0) :
353 obj(o), 43 obj(o),
libqpdf/build.mk
@@ -8,6 +8,9 @@ SRCS_libqpdf = \ @@ -8,6 +8,9 @@ SRCS_libqpdf = \
8 libqpdf/BitStream.cc \ 8 libqpdf/BitStream.cc \
9 libqpdf/BitWriter.cc \ 9 libqpdf/BitWriter.cc \
10 libqpdf/Buffer.cc \ 10 libqpdf/Buffer.cc \
  11 + libqpdf/BufferInputSource.cc \
  12 + libqpdf/FileInputSource.cc \
  13 + libqpdf/InputSource.cc \
11 libqpdf/MD5.cc \ 14 libqpdf/MD5.cc \
12 libqpdf/PCRE.cc \ 15 libqpdf/PCRE.cc \
13 libqpdf/Pipeline.cc \ 16 libqpdf/Pipeline.cc \