summaryrefslogtreecommitdiffstats
path: root/cpp/sca
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/sca')
-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
-rw-r--r--cpp/sca/modules/json/json-test.cpp22
-rw-r--r--cpp/sca/modules/json/json.hpp85
5 files changed, 258 insertions, 138 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));
}
}
diff --git a/cpp/sca/modules/json/json-test.cpp b/cpp/sca/modules/json/json-test.cpp
index 42cdb1d643..5a1dcc5d51 100644
--- a/cpp/sca/modules/json/json-test.cpp
+++ b/cpp/sca/modules/json/json-test.cpp
@@ -27,6 +27,7 @@
#include <iostream>
#include <sstream>
#include <string>
+#include "slist.hpp"
#include "json.hpp"
namespace tuscany {
@@ -41,6 +42,11 @@ bool testJSEval() {
return true;
}
+std::ostringstream* jsonWriter(std::ostringstream* os, const std::string& s) {
+ (*os) << s;
+ return os;
+}
+
bool testJSON() {
JSONContext cx;
@@ -49,16 +55,22 @@ bool testJSON() {
print(l, std::cout);
std::cout << std::endl;
- std::ostringstream sos;
- writeJSON(cx, l, sos);
- std::cout << sos.str() << std::endl;
+ std::ostringstream os;
+ lambda<std::ostringstream*(std::ostringstream*, std::string)> writer(jsonWriter);
+ writeJSON(cx, writer, &os, l);
+ std::cout << os.str() << std::endl;
- std::istringstream is(sos.str());
- list<value> r = readJSON(cx, is);
+ std::istringstream is(os.str());
+ list<std::string> il = makeStreamList(is);
+ list<value> r = readJSON(cx, il);
print(r, std::cout);
std::cout << std::endl;
assert(r == l);
+ std::ostringstream wos;
+ write(writeJSON(cx, r), wos);
+ assert(wos.str() == os.str());
+
return true;
}
diff --git a/cpp/sca/modules/json/json.hpp b/cpp/sca/modules/json/json.hpp
index 16e3ce0320..e9938672c5 100644
--- a/cpp/sca/modules/json/json.hpp
+++ b/cpp/sca/modules/json/json.hpp
@@ -19,8 +19,8 @@
/* $Rev$ $Date$ */
-#ifndef tuscany_eval_driver_hpp
-#define tuscany_eval_driver_hpp
+#ifndef tuscany_json_hpp
+#define tuscany_json_hpp
/**
* JSON read/write functions.
@@ -29,8 +29,6 @@
#include <assert.h>
#define XP_UNIX
#include <jsapi.h>
-#include <iostream>
-#include <sstream>
#include <string>
#include "list.hpp"
#include "value.hpp"
@@ -191,41 +189,27 @@ const value jsValToValue(const JSONContext& cx, const jsval& jsv) {
}
/**
- * Reads characters from a JSON input stream.
+ * Consumes JSON strings and populates a JS object.
*/
-JSString* readCallback(const JSONContext& cx, std::istream& is) {
- char buffer[1024];
- if(is.eof())
- return NULL;
- is.read(buffer, 1024);
- const int n = is.gcount();
- if(n <= 0)
- return NULL;
- return JS_NewStringCopyN(cx, buffer, n);
-}
-
-/**
- * Consumes a JSON document and populates a JS object from it.
- */
-bool consumeJSON(const JSONContext& cx, JSONParser* parser, std::istream& is) {
- JSString* jstr = readCallback(cx, is);
- if(jstr == NULL)
+bool consumeJSON(const JSONContext& cx, JSONParser* parser, const list<std::string>& ilist) {
+ if (isNil(ilist))
return true;
+ JSString* jstr = JS_NewStringCopyZ(cx, car(ilist).c_str());
if(!JS_ConsumeJSONText(cx, parser, JS_GetStringChars(jstr), JS_GetStringLength(jstr)))
return false;
- return consumeJSON(cx, parser, is);
+ return consumeJSON(cx, parser, cdr(ilist));
}
/**
- * Read a JSON document from an input stream.
+ * Read JSON tokens from list of strings.
*/
-const list<value> readJSON(const JSONContext& cx, std::istream& is) {
+const list<value> readJSON(const JSONContext& cx, const list<std::string>& ilist) {
jsval val;
JSONParser* parser = JS_BeginJSONParse(cx, &val);
if(parser == NULL)
return list<value> ();
- bool ok = consumeJSON(cx, parser, is);
+ bool ok = consumeJSON(cx, parser, ilist);
if(!JS_FinishJSONParse(cx, parser, JSVAL_NULL))
return list<value> ();
@@ -308,42 +292,47 @@ const jsval valueToJSVal(const JSONContext& cx, const value& val) {
/**
* Context passed to JSON write callback function.
*/
-class JSONWriteContext {
+template<typename R> class JSONWriteContext {
public:
- JSONWriteContext(const JSONContext& cx, std::ostream& os) :
- os(os), cx(cx) {
+ JSONWriteContext(const JSONContext& cx, const lambda<R(R, std::string)>& reduce, const R& accum) : cx(cx), reduce(reduce), accum(accum) {
}
-
-private:
- std::ostream& os;
const JSONContext& cx;
-
- friend JSBool writeCallback(const jschar *buf, uint32 len, void *data);
+ const lambda<R(R, std::string)> reduce;
+ R accum;
};
/**
- * Called by JS_Stringify to write JSON document.
+ * Called by JS_Stringify to write JSON out.
*/
-JSBool writeCallback(const jschar *buf, uint32 len, void *data) {
- JSONWriteContext& cx = *(static_cast<JSONWriteContext*> (data));
- JSString* jstr = JS_NewUCStringCopyN(cx.cx, buf, len);
- cx.os.write(JS_GetStringBytes(jstr), JS_GetStringLength(jstr));
- if(cx.os.fail() || cx.os.bad())
- return JS_FALSE;
+template<typename R> JSBool writeCallback(const jschar *buf, uint32 len, void *data) {
+ JSONWriteContext<R>& wcx = *(static_cast<JSONWriteContext<R>*> (data));
+ JSString* jstr = JS_NewUCStringCopyN(wcx.cx, buf, len);
+ wcx.accum = wcx.reduce(wcx.accum, std::string(JS_GetStringBytes(jstr), JS_GetStringLength(jstr)));
return JS_TRUE;
}
/**
- * Write a JSON document to an output stream.
+ * Write a list of values as a JSON document.
*/
-const bool writeJSON(const JSONContext& cx, const list<value>& l, std::ostream& os) {
+template<typename R> const R writeJSON(const JSONContext& cx, const lambda<R(R, std::string)>& reduce, const R& initial, const list<value>& l) {
jsval val = valueToJSVal(cx, l);
- JSONWriteContext wcx(cx, os);
- if(!JS_Stringify(cx, &val, NULL, JSVAL_NULL, writeCallback, &wcx))
- return false;
- return true;
+ JSONWriteContext<R> wcx(cx, reduce, initial);
+ JS_Stringify(cx, &val, NULL, JSVAL_NULL, writeCallback<R>, &wcx);
+ return wcx.accum;
+}
+
+const list<std::string> writeJSONList(const list<std::string>& listSoFar, const std::string& s) {
+ return cons(s, listSoFar);
+}
+
+/**
+ * Write a list of values as a JSON document represented as a list of strings.
+ */
+const list<std::string> writeJSON(const JSONContext& cx, const list<value>& l) {
+ lambda<list<std::string>(list<std::string>, std::string)> writer(writeJSONList);
+ return reverse(writeJSON(cx, writer, list<std::string>(), l));
}
}
-#endif
+#endif /* tuscany_json_hpp */