summaryrefslogtreecommitdiffstats
path: root/cpp/sca/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/sca/kernel')
-rw-r--r--cpp/sca/kernel/kernel-test.cpp68
-rw-r--r--cpp/sca/kernel/slist.hpp96
-rw-r--r--cpp/sca/kernel/xml.hpp125
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));
}
}