aboutsummaryrefslogtreecommitdiffstats
path: root/libtests
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2017-08-06 14:42:01 +0200
committerJay Berkenbilt <ejb@ql.org>2017-08-11 03:30:32 +0200
commit296b679d6e3217cc112b7ed19b363b82356615ef (patch)
tree7cb9b3aa95c00da45cf1a7cf67a020c1ee54a6c9 /libtests
parentef8ae5449dc30782451beba64fdd0af86e1cb931 (diff)
downloadqpdf-296b679d6e3217cc112b7ed19b363b82356615ef.tar.zst
Implement findFirst and findLast in InputSource
Preparing to refactor some pattern searching code to use these instead of their own memchr loops. This should simplify the code that replaces PCRE.
Diffstat (limited to 'libtests')
-rw-r--r--libtests/build.mk1
-rw-r--r--libtests/input_source.cc108
-rw-r--r--libtests/libtests.testcov8
-rw-r--r--libtests/qtest/input_source.test26
-rw-r--r--libtests/qtest/input_source/input_source.out14
5 files changed, 157 insertions, 0 deletions
diff --git a/libtests/build.mk b/libtests/build.mk
index 22d9299e..2a272799 100644
--- a/libtests/build.mk
+++ b/libtests/build.mk
@@ -6,6 +6,7 @@ BINS_libtests = \
concatenate \
flate \
hex \
+ input_source \
lzw \
md5 \
pcre \
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;
+}
diff --git a/libtests/libtests.testcov b/libtests/libtests.testcov
index ddbccd24..a5fe625f 100644
--- a/libtests/libtests.testcov
+++ b/libtests/libtests.testcov
@@ -16,3 +16,11 @@ bits write zero bits 0
Pl_ASCIIHexDecoder ignore space 0
Pl_ASCIIHexDecoder no-op flush 0
Pl_ASCIIHexDecoder partial flush 1
+InputSource read next block 1
+InputSource find EOF 1
+InputSource out of range 0
+InputSource first char matched but not string 0
+InputSource start_chars matched but not check 0
+InputSource not enough bytes 0
+InputSource findLast found more than one 0
+InputSource found match at buf[0] 0
diff --git a/libtests/qtest/input_source.test b/libtests/qtest/input_source.test
new file mode 100644
index 00000000..89a1c21a
--- /dev/null
+++ b/libtests/qtest/input_source.test
@@ -0,0 +1,26 @@
+#!/usr/bin/env perl
+require 5.008;
+use warnings;
+use strict;
+
+chdir("input_source") or die "chdir testdir failed: $!\n";
+
+require TestDriver;
+
+my $td = new TestDriver('InputSource');
+
+cleanup();
+
+$td->runtest("input source tests",
+ {$td->COMMAND => "input_source"},
+ {$td->FILE => "input_source.out",
+ $td->EXIT_STATUS => 0},
+ $td->NORMALIZE_NEWLINES);
+
+cleanup();
+
+$td->report(1);
+
+sub cleanup
+{
+}
diff --git a/libtests/qtest/input_source/input_source.out b/libtests/qtest/input_source/input_source.out
new file mode 100644
index 00000000..6af379c6
--- /dev/null
+++ b/libtests/qtest/input_source/input_source.out
@@ -0,0 +1,14 @@
+find potato salad: PASS
+barely find potato salad: PASS
+barely find potato salad: PASS
+potato salad is too late: PASS
+potato salad is too late: PASS
+potato salad not found: PASS
+potato salad not found: PASS
+potato salad at EOF: PASS
+findFirst found first: PASS
+findLast found potato salad: PASS
+findLast found at EOF: PASS
+potato but not salad salad at EOF: PASS
+findLast found potato salad: PASS
+findLast found first one: PASS