diff options
Diffstat (limited to 'cpp/sca/kernel')
-rw-r--r-- | cpp/sca/kernel/kernel-test.cpp | 68 | ||||
-rw-r--r-- | cpp/sca/kernel/slist.hpp | 96 | ||||
-rw-r--r-- | cpp/sca/kernel/xml.hpp | 125 |
3 files changed, 204 insertions, 85 deletions
diff --git a/cpp/sca/kernel/kernel-test.cpp b/cpp/sca/kernel/kernel-test.cpp index 7eaa6a6354..576775b75e 100644 --- a/cpp/sca/kernel/kernel-test.cpp +++ b/cpp/sca/kernel/kernel-test.cpp @@ -31,6 +31,7 @@ #include <sstream> #include "function.hpp" #include "list.hpp" +#include "slist.hpp" #include "parallel.hpp" #include "value.hpp" #include "xml.hpp" @@ -218,6 +219,15 @@ bool testReverse() { return true; } +bool testTokenize() { + assert(tokenize("/", "aaa/bbb/ccc/ddd") == makeList<std::string>("aaa", "bbb", "ccc", "ddd")); + assert(tokenize("/", "/bbb/ccc/ddd") == makeList<std::string>("", "bbb", "ccc", "ddd")); + assert(tokenize("/", "/bbb/ccc/") == makeList<std::string>("", "bbb", "ccc")); + assert(tokenize("/", "/bbb//ccc/") == makeList<std::string>("", "bbb", "", "ccc")); + assert(tokenize("/", "abc/def/") == makeList<std::string>("abc", "def")); + return true; +} + double testSeqMap(double x) { return x; } @@ -285,15 +295,42 @@ double fib(double n) { bool testCppPerf() { struct timeval start; struct timeval end; - gettimeofday(&start, NULL); + { + gettimeofday(&start, NULL); + + list<double> s = seq(0.0, 999.0); + list<double> r = map((lambda<double(double)> )fib, s); + assert(1000 == length(r)); - list<double> s = seq(0.0, 999.0); - list<double> r = map((lambda<double(double)> )fib, s); - assert(1000 == length(r)); + gettimeofday(&end, NULL); + //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); + //std::cout << "Fib cpp function map perf test " << t << " ms" << std::endl; + } + + { + struct nested { + static double fib(double n) { + struct nested { + static double fib_aux(double n, double a, double b) { + if(n == 0.0) + return a; + return fib_aux(n - 1.0, b, a + b); + } + }; + return nested::fib_aux(n, 0.0, 1.0); + } + }; - gettimeofday(&end, NULL); - //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); - //std::cout << "Fib cpp perf test " << t << " ms" << std::endl; + gettimeofday(&start, NULL); + + list<double> s = seq(0.0, 999.0); + list<double> r = map(lambda<double(double)>(nested::fib), s); + assert(1000 == length(r)); + + gettimeofday(&end, NULL); + //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); + //std::cout << "Fib cpp nested function map perf test " << t << " ms" << std::endl; + } return true; } @@ -390,7 +427,7 @@ const bool isName(const value& token) { bool testReadXML() { std::istringstream is(currencyXML); - const list<value> currency = readXML(is); + const list<value> currency = readXML(makeStreamList(is)); const value composite = car(currency); assert(isElement(composite)); @@ -401,12 +438,22 @@ bool testReadXML() { return true; } +std::ostringstream* xmlWriter(std::ostringstream* os, const std::string& s) { + (*os) << s; + return os; +} + bool testWriteXML() { std::istringstream is(currencyXML); - const list<value> currency = readXML(is); + const list<std::string> il = makeStreamList(is); + + const list<value> currency = readXML(il); std::ostringstream os; - writeXML(currency, os); + lambda<std::ostringstream*(std::ostringstream*, std::string)> writer(xmlWriter); + writeXML(writer, &os, currency); assert(os.str() == currencyXML); + + assert(writeXML(currency) == il); return true; } @@ -429,6 +476,7 @@ int main() { tuscany::testFilter(); tuscany::testMember(); tuscany::testReverse(); + tuscany::testTokenize(); tuscany::testSeq(); tuscany::testValue(); tuscany::testValueGC(); diff --git a/cpp/sca/kernel/slist.hpp b/cpp/sca/kernel/slist.hpp new file mode 100644 index 0000000000..54c2d77574 --- /dev/null +++ b/cpp/sca/kernel/slist.hpp @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +/* $Rev$ $Date$ */ + +#ifndef tuscany_slist_hpp +#define tuscany_slist_hpp + +/** + * Useful functions to work with lists of strings and character streams. + */ + +#include <iostream> +#include <string> +#include "function.hpp" +#include "list.hpp" + +namespace tuscany { + +/** + * Tokenize a string into a list of strings. + */ +const list<std::string> tokenize(const std::string& sep, const std::string& str) { + struct nested { + static const list<std::string> tokenize(const std::string& sep, const std::string& str, const unsigned int start = 0) { + if (start >= str.length()) + return list<std::string>(); + const unsigned int i = str.find_first_of(sep, start); + if (i == std::string::npos) + return makeList(str.substr(start)); + return cons(str.substr(start, i - start), tokenize(sep, str, i + 1)); + } + }; + return nested::tokenize(sep, str, 0); +} + +/** + * Returns a lazy list view of an input stream. + */ +struct ilistRead{ + std::istream &is; + ilistRead(std::istream& is) : is(is) { + } + const list<std::string> operator()() { + char buffer[1024]; + is.read(buffer, 1024); + const int n = is.gcount(); + if (n ==0) + return list<std::string>(); + return cons(std::string(buffer, n), (*this)()); + } +}; + +const list<std::string> makeStreamList(std::istream& is) { + return ilistRead(is)(); +} + +/** + * Fragment the first element of a list of strings to fit the given max length. + */ +const list<std::string> fragment(list<std::string> l, unsigned int max) { + const std::string s = car(l); + if (s.length() <= max) + return l; + return cons(s.substr(0, max), cons(s.substr(max), cdr(l))); +} + +/** + * Write a list of strings to an output stream. + */ +std::ostream& write(const list<std::string>& l, std::ostream& os) { + if(isNil(l)) + return os; + os << car(l); + return write(cdr(l), os); +} + +} + +#endif /* tuscany_slist_hpp */ diff --git a/cpp/sca/kernel/xml.hpp b/cpp/sca/kernel/xml.hpp index 7ddfd6bc44..cfae5678b8 100644 --- a/cpp/sca/kernel/xml.hpp +++ b/cpp/sca/kernel/xml.hpp @@ -30,8 +30,6 @@ #include <libxml/xmlwriter.h> #include <libxml/xmlschemas.h> #include <libxml/globals.h> -#include <iostream> -#include <fstream> #include <string> #include "list.hpp" @@ -158,7 +156,7 @@ const list<value> readList(const list<value>& listSoFar, XMLReader& reader) { } /** - * Read an XML document from a libxml2 XML reader. + * Read a list of values from a libxml2 XML reader. */ const list<value> read(XMLReader& reader) { value nextToken = readToken(reader); @@ -168,49 +166,35 @@ const list<value> read(XMLReader& reader) { } /** - * Callback function called by libxml2 to read the XML input stream. + * Context passed to the read callback function. */ -int readCallback(void *context, char* buffer, int len) { - std::istream* is = static_cast<std::istream*>(context); - is->read(buffer, len); - const int n = is->gcount(); - return n; -} - -/** - * Read an XML document from an input stream. - */ -const list<value> readXML(std::istream& is) { - xmlTextReaderPtr xml = xmlReaderForIO(readCallback, NULL, &is, NULL, NULL, XML_PARSE_NONET); - if (xml == NULL) - return list<value>(); - XMLReader reader(xml); - return read(reader); -} - -/** - * Callback function called by libxml2 to read the XML file input stream. - */ -int readFileCallback(void *context, char* buffer, int len) { - std::ifstream* is = static_cast<std::ifstream*>(context); - is->read(buffer, len); - return is->gcount(); -} +class XMLReadContext { +public: + XMLReadContext(const list<std::string>& ilist) : ilist(ilist) { + } + list<std::string> ilist; +}; /** - * Callback function called by libxml2 to close the XML file input stream. + * Callback function called by libxml2 to read XML. */ -int readCloseFileCallback(void *context) { - std::ifstream* fis = static_cast<std::ifstream*>(context); - fis->close(); - return 0; +int readCallback(void *context, char* buffer, int len) { + XMLReadContext& rc = *static_cast<XMLReadContext*>(context); + if (isNil(rc.ilist)) + return 0; + rc.ilist = fragment(rc.ilist, len); + std::string s = car(rc.ilist); + rc.ilist = cdr(rc.ilist); + s.copy(buffer, s.length()); + return s.length(); } /** - * Read an XML document from a file input stream. + * Read a list values from a list of strings representing an XML document. */ -const list<value> readXML(std::ifstream& is) { - xmlTextReaderPtr xml = xmlReaderForIO(readFileCallback, readCloseFileCallback, &is, NULL, NULL, XML_PARSE_NONET); +const list<value> readXML(const list<std::string>& ilist) { + XMLReadContext cx(ilist); + xmlTextReaderPtr xml = xmlReaderForIO(readCallback, NULL, &cx, NULL, NULL, XML_PARSE_NONET); if (xml == NULL) return list<value>(); XMLReader reader(xml); @@ -313,7 +297,7 @@ const bool writeList(const list<value>& l, const xmlTextWriterPtr xml) { } /** - * Write an XML document to a libxml2 XML writer. + * Write a list of values to a libxml2 XML writer. */ const bool write(const list<value>& l, const xmlTextWriterPtr xml) { if (xmlTextWriterStartDocument(xml, NULL, encoding, NULL) < 0) @@ -325,56 +309,47 @@ const bool write(const list<value>& l, const xmlTextWriterPtr xml) { } /** - * Callback function called by libxml2 to write to the XML output stream. + * Context passed to the write callback function. */ -int writeCallback(void *context, const char* buffer, int len) { - std::ostream* os = static_cast<std::ostream*>(context); - os->write(buffer, len); - if (os->fail() || os->bad()) - return -1; - return len; -} +template<typename R> class XMLWriteContext { +public: + XMLWriteContext(const lambda<R(R, std::string)>& reduce, const R& accum) : reduce(reduce), accum(accum) { + } + const lambda<R(R, std::string)> reduce; + R accum; +}; /** - * Write an XML document to an output stream. + * Callback function called by libxml2 to write XML out. */ -const bool writeXML(const list<value>& l, std::ostream& os) { - xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback, NULL, &os, NULL); - xmlTextWriterPtr xml = xmlNewTextWriter(out); - if (xml == NULL) - return false; - return write(l, xml); +template<typename R> int writeCallback(void *context, const char* buffer, int len) { + XMLWriteContext<R>& cx = *static_cast<XMLWriteContext<R>*>(context); + cx.accum = cx.reduce(cx.accum, std::string(buffer, len)); + return len; } /** - * Callback function called by libxml2 to write to the XML file output stream. + * Write a list of values as an XML document. */ -int writeFileCallback(void *context, const char* buffer, int len) { - std::ofstream* os = static_cast<std::ofstream*>(context); - os->write(buffer, len); - if (os->fail() || os->bad()) - return -1; - return len; +template<typename R> const R writeXML(const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) { + XMLWriteContext<R> cx(reduce, initial); + xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback<R>, NULL, &cx, NULL); + xmlTextWriterPtr xml = xmlNewTextWriter(out); + if (xml != NULL) + write(l, xml); + return cx.accum; } -/** - * Callback function called by libxml2 to close the XML file output stream. - */ -int writeCloseFileCallback(void *context) { - std::ofstream* fos = static_cast<std::ofstream*>(context); - fos->close(); - return 0; +const list<std::string> writeXMLList(const list<std::string>& listSoFar, const std::string& s) { + return cons(s, listSoFar); } /** - * Write an XML document to a file output stream. + * Write a list of values as an XML document represented as a list of strings. */ -const bool writeXML(const list<value>& l, std::ofstream& os) { - xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeFileCallback, writeCloseFileCallback, &os, NULL); - xmlTextWriterPtr xml = xmlNewTextWriter(out); - if (xml == NULL) - return false; - return write(l, xml); +const list<std::string> writeXML(const list<value>& l) { + lambda<list<std::string>(list<std::string>, std::string)> writer(writeXMLList); + return reverse(writeXML(writer, list<std::string>(), l)); } } |