aboutsummaryrefslogtreecommitdiffstats
path: root/libtests/input_source.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libtests/input_source.cc')
-rw-r--r--libtests/input_source.cc108
1 files changed, 108 insertions, 0 deletions
diff --git a/libtests/input_source.cc b/libtests/input_source.cc
new file mode 100644
index 00000000..091a1ea1
--- /dev/null
+++ b/libtests/input_source.cc
@@ -0,0 +1,108 @@
+#include <iostream>
+#include <qpdf/BufferInputSource.hh>
+#include <qpdf/PointerHolder.hh>
+#include <qpdf/Buffer.hh>
+#include <qpdf/QPDFTokenizer.hh>
+
+static PointerHolder<Buffer>
+get_buffer()
+{
+ size_t size = 3172;
+ PointerHolder<Buffer> b(new Buffer(size));
+ unsigned char* p = b->getBuffer();
+ for (size_t i = 0; i < size; ++i)
+ {
+ p[i] = static_cast<unsigned char>(i & 0xff);
+ }
+ return b;
+}
+
+class Finder: public InputSource::Finder
+{
+ public:
+ Finder(PointerHolder<InputSource> is, std::string const& after) :
+ is(is),
+ after(after)
+ {
+ }
+ virtual ~Finder()
+ {
+ }
+ virtual bool check();
+
+ private:
+ PointerHolder<InputSource> is;
+ std::string after;
+};
+
+bool
+Finder::check()
+{
+ QPDFTokenizer tokenizer;
+ QPDFTokenizer::Token t = tokenizer.readToken(is, "finder", true);
+ if (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, "potato"))
+ {
+ t = tokenizer.readToken(is, "finder", true);
+ return (t == QPDFTokenizer::Token(QPDFTokenizer::tt_word, after));
+ }
+ return false;
+}
+
+void check(char const* description, bool expected, bool actual)
+{
+ std::cout << description << ": "
+ << ((actual == expected) ? "PASS" : "FAIL")
+ << std::endl;
+}
+
+int main()
+{
+ PointerHolder<Buffer> b1 = get_buffer();
+ unsigned char* b = b1->getBuffer();
+ // Straddle block boundaries
+ memcpy(b + 1022, "potato", 6);
+ // Overlap so that the first check() would advance past the start
+ // of the next match
+ memcpy(b + 2037, "potato potato salad ", 20);
+ PointerHolder<InputSource> is =
+ new BufferInputSource("test buffer input source", b1.getPointer());
+ Finder f1(is, "salad");
+ check("find potato salad", true,
+ is->findFirst("potato", 0, 0, f1));
+ check("barely find potato salad", true,
+ is->findFirst("potato", 1100, 945, f1));
+ check("barely find potato salad", true,
+ is->findFirst("potato", 2000, 45, f1));
+ check("potato salad is too late", false,
+ is->findFirst("potato", 1100, 944, f1));
+ check("potato salad is too late", false,
+ is->findFirst("potato", 2000, 44, f1));
+ check("potato salad not found", false,
+ is->findFirst("potato", 2045, 0, f1));
+ check("potato salad not found", false,
+ is->findFirst("potato", 0, 1, f1));
+
+ // Put one more right at EOF
+ memcpy(b + b1->getSize() - 12, "potato salad", 12);
+ check("potato salad at EOF", true,
+ is->findFirst("potato", 3000, 0, f1));
+
+ is->findFirst("potato", 0, 0, f1);
+ check("findFirst found first", true,
+ is->tell() == 2056);
+ check("findLast found potato salad", true,
+ is->findLast("potato", 0, 0, f1));
+ check("findLast found at EOF", true,
+ is->tell() == 3172);
+
+ // Make check() bump into EOF
+ memcpy(b + b1->getSize() - 6, "potato", 6);
+ check("potato but not salad salad at EOF", false,
+ is->findFirst("potato", 3000, 0, f1));
+ check("findLast found potato salad", true,
+ is->findLast("potato", 0, 0, f1));
+ check("findLast found first one", true,
+ is->tell() == 2056);
+
+ return 0;
+}