From f9dcf53c508e3aa5ba7e0af5f5313781b368d987 Mon Sep 17 00:00:00 2001 From: Martin Gieseking Date: Tue, 31 Oct 2017 11:25:18 +0100 Subject: [PATCH] simplified code to lookup PS operators --- src/InputReader.cpp | 16 ----- src/InputReader.hpp | 2 - src/PSInterpreter.cpp | 156 +++++++++++++++++++----------------------- 3 files changed, 70 insertions(+), 104 deletions(-) diff --git a/src/InputReader.cpp b/src/InputReader.cpp index cd69add8..6b2e566d 100644 --- a/src/InputReader.cpp +++ b/src/InputReader.cpp @@ -110,22 +110,6 @@ bool InputReader::check (const char *s, bool consume) { } -int InputReader::compare (const char *s, bool consume) { - size_t count = 0; - for (const char *p=s; *p; p++) { - int c = peek(count++); - if (c != *p) - return c < *p ? -1 : 1; - } - int c = peek(count); - if (c < 0 || !isspace(c)) - return 1; - if (consume) - skip(count); - return 0; -} - - /** Reads an integer from the buffer. All characters that are part of * the read integer constant are skipped. If this function returns false, * the buffer pointer points to the same position as before the function call. diff --git a/src/InputReader.hpp b/src/InputReader.hpp index a04c1b4f..15a47323 100644 --- a/src/InputReader.hpp +++ b/src/InputReader.hpp @@ -36,7 +36,6 @@ class InputReader { virtual bool eof () const =0; virtual bool check (char c) const {return peek() == c;} virtual bool check (const char *s, bool consume=true); - virtual int compare (const char *s, bool consume=true); virtual void skip (size_t n); virtual bool skipUntil (const char *s); virtual int find (char c) const; @@ -103,5 +102,4 @@ class StringMatcher { size_t _charsRead; }; - #endif diff --git a/src/PSInterpreter.cpp b/src/PSInterpreter.cpp index 8319c897..cdc0ccd1 100644 --- a/src/PSInterpreter.cpp +++ b/src/PSInterpreter.cpp @@ -18,9 +18,11 @@ ** along with this program; if not, see . ** *************************************************************************/ +#include #include #include #include +#include #include "FileFinder.hpp" #include "InputReader.hpp" #include "Message.hpp" @@ -238,108 +240,90 @@ int GSDLLCALL PSInterpreter::output (void *inst, const char *buf, int len) { } -/** Converts a vector of strings to a vector of doubles. - * @param[in] str the strings to be converted - * @param[out] d the resulting doubles */ -static void str2double (const vector &str, vector &d) { - for (size_t i=0; i < str.size(); i++) { - istringstream iss(str[i]); - iss >> d[i]; - } -} - - /** Evaluates a command emitted by Ghostscript and invokes the corresponding * method of interface class PSActions. * @param[in] in reader pointing to the next command */ void PSInterpreter::callActions (InputReader &in) { - // array of currently supported operators (must be ascendingly sorted) - static const struct Operator { - const char *name; // name of operator + struct Operator { int pcount; // number of parameters (< 0 : variable number of parameters) - void (PSActions::*op)(vector &p); // operation handler - } operators [] = { - {"applyscalevals", 3, &PSActions::applyscalevals}, - {"clip", 0, &PSActions::clip}, - {"clippath", 0, &PSActions::clippath}, - {"closepath", 0, &PSActions::closepath}, - {"curveto", 6, &PSActions::curveto}, - {"eoclip", 0, &PSActions::eoclip}, - {"eofill", 0, &PSActions::eofill}, - {"fill", 0, &PSActions::fill}, - {"grestore", 0, &PSActions::grestore}, - {"grestoreall", 0, &PSActions::grestoreall}, - {"gsave", 0, &PSActions::gsave}, - {"initclip", 0, &PSActions::initclip}, - {"lineto", 2, &PSActions::lineto}, - {"makepattern", -1, &PSActions::makepattern}, - {"moveto", 2, &PSActions::moveto}, - {"newpath", 1, &PSActions::newpath}, - {"querypos", 2, &PSActions::querypos}, - {"raw", -1, 0}, - {"restore", 1, &PSActions::restore}, - {"rotate", 1, &PSActions::rotate}, - {"save", 1, &PSActions::save}, - {"scale", 2, &PSActions::scale}, - {"setcmykcolor", 4, &PSActions::setcmykcolor}, - {"setdash", -1, &PSActions::setdash}, - {"setgray", 1, &PSActions::setgray}, - {"sethsbcolor", 3, &PSActions::sethsbcolor}, - {"setlinecap", 1, &PSActions::setlinecap}, - {"setlinejoin", 1, &PSActions::setlinejoin}, - {"setlinewidth", 1, &PSActions::setlinewidth}, - {"setmatrix", 6, &PSActions::setmatrix}, - {"setmiterlimit", 1, &PSActions::setmiterlimit}, - {"setopacityalpha", 1, &PSActions::setopacityalpha}, - {"setpattern", -1, &PSActions::setpattern}, - {"setrgbcolor", 3, &PSActions::setrgbcolor}, - {"shfill", -1, &PSActions::shfill}, - {"stroke", 0, &PSActions::stroke}, - {"translate", 2, &PSActions::translate}, + void (PSActions::*handler)(vector &p); // operation handler + }; + static const unordered_map operators { + {"applyscalevals", { 3, &PSActions::applyscalevals}}, + {"clip", { 0, &PSActions::clip}}, + {"clippath", { 0, &PSActions::clippath}}, + {"closepath", { 0, &PSActions::closepath}}, + {"curveto", { 6, &PSActions::curveto}}, + {"eoclip", { 0, &PSActions::eoclip}}, + {"eofill", { 0, &PSActions::eofill}}, + {"fill", { 0, &PSActions::fill}}, + {"grestore", { 0, &PSActions::grestore}}, + {"grestoreall", { 0, &PSActions::grestoreall}}, + {"gsave", { 0, &PSActions::gsave}}, + {"initclip", { 0, &PSActions::initclip}}, + {"lineto", { 2, &PSActions::lineto}}, + {"makepattern", {-1, &PSActions::makepattern}}, + {"moveto", { 2, &PSActions::moveto}}, + {"newpath", { 1, &PSActions::newpath}}, + {"querypos", { 2, &PSActions::querypos}}, + {"raw", {-1, nullptr}}, + {"restore", { 1, &PSActions::restore}}, + {"rotate", { 1, &PSActions::rotate}}, + {"save", { 1, &PSActions::save}}, + {"scale", { 2, &PSActions::scale}}, + {"setcmykcolor", { 4, &PSActions::setcmykcolor}}, + {"setdash", {-1, &PSActions::setdash}}, + {"setgray", { 1, &PSActions::setgray}}, + {"sethsbcolor", { 3, &PSActions::sethsbcolor}}, + {"setlinecap", { 1, &PSActions::setlinecap}}, + {"setlinejoin", { 1, &PSActions::setlinejoin}}, + {"setlinewidth", { 1, &PSActions::setlinewidth}}, + {"setmatrix", { 6, &PSActions::setmatrix}}, + {"setmiterlimit", { 1, &PSActions::setmiterlimit}}, + {"setopacityalpha",{ 1, &PSActions::setopacityalpha}}, + {"setpattern", {-1, &PSActions::setpattern}}, + {"setrgbcolor", { 3, &PSActions::setrgbcolor}}, + {"shfill", {-1, &PSActions::shfill}}, + {"stroke", { 0, &PSActions::stroke}}, + {"translate", { 2, &PSActions::translate}}, }; if (_actions) { in.skipSpace(); - // binary search - int first=0, last=sizeof(operators)/sizeof(Operator)-1; - while (first <= last) { - int mid = first+(last-first)/2; - int cmp = in.compare(operators[mid].name); - if (cmp < 0) - last = mid-1; - else if (cmp > 0) - first = mid+1; + auto it = operators.find(in.getWord()); + if (it != operators.end()) { + if (!it->second.handler) { // raw string data received? + _rawData.clear(); + in.skipSpace(); + while (!in.eof()) { + _rawData.emplace_back(in.getString()); + in.skipSpace(); + } + } else { - if (!operators[mid].op) { // raw string data received - _rawData.clear(); + // collect parameters + vector params; + int pcount = it->second.pcount; + if (pcount < 0) { // variable number of parameters? in.skipSpace(); - while (!in.eof()) { - _rawData.emplace_back(in.getString()); + while (!in.eof()) { // read all available parameters + params.emplace_back(in.getString()); in.skipSpace(); } } - else { - // collect parameters and call handler - vector params; - int pcount = operators[mid].pcount; - if (pcount < 0) { // variable number of parameters? + else { // fix number of parameters + for (int i=0; i < pcount; i++) { in.skipSpace(); - while (!in.eof()) { // read all available parameters - params.emplace_back(in.getString()); - in.skipSpace(); - } - } - else { // fix number of parameters - for (int i=0; i < pcount; i++) { - in.skipSpace(); - params.emplace_back(in.getString()); - } + params.emplace_back(in.getString()); } - vector v(params.size()); - str2double(params, v); - (_actions->*operators[mid].op)(v); - _actions->executed(); } - break; + // convert parameter strings to doubles + vector v(params.size()); + transform(params.begin(), params.end(), v.begin(), [](const string &str) { + return stod(str); + }); + // call operator handler + (_actions->*it->second.handler)(v); + _actions->executed(); } } }