Author: jsdelfino
Date: Mon Nov 16 06:00:12 2009
New Revision: 880598

URL: http://svn.apache.org/viewvc?rev=880598&view=rev
Log:
Fixed support for nested elements and lists. Improved failure/error reporting 
monad. Minor code cleanup.

Modified:
    tuscany/cpp/sca/kernel/element.hpp
    tuscany/cpp/sca/kernel/kernel-test.cpp
    tuscany/cpp/sca/kernel/list.hpp
    tuscany/cpp/sca/kernel/monad.hpp
    tuscany/cpp/sca/kernel/value.hpp
    tuscany/cpp/sca/kernel/xml.hpp
    tuscany/cpp/sca/modules/atom/atom.hpp
    tuscany/cpp/sca/modules/http/curl.hpp
    tuscany/cpp/sca/modules/json/json.hpp

Modified: tuscany/cpp/sca/kernel/element.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/element.hpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/element.hpp (original)
+++ tuscany/cpp/sca/kernel/element.hpp Mon Nov 16 06:00:12 2009
@@ -39,6 +39,24 @@
 const value element("element");
 
 /**
+ * Returns true if a value is an element.
+ */
+bool isElement(const value& v) {
+    if (!isList(v) || isNil(v) || element != car<value>(v))
+        return false;
+    return true;
+}
+
+/**
+ * Returns true if a value is an attribute.
+ */
+bool isAttribute(const value& v) {
+    if (!isList(v) || isNil(v) || attribute != car<value>(v))
+        return false;
+    return true;
+}
+
+/**
  * Returns the name of an attribute.
  */
 const value attributeName(const list<value>& l) {
@@ -99,9 +117,7 @@
     if (!isList(v))
         return false;
     const list<value> l = v;
-    if(isNil(l))
-        return true;
-    return isList(car(l));
+    return (isNil(l) || !isSymbol(car(l)));
 }
 
 const value elementToValue(const value& t) {
@@ -150,12 +166,10 @@
 }
 
 const list<value> elementToValueGroupValues(const value& v, const list<value>& 
l) {
-    if (isNil(l) || !elementToValueIsSymbol(v) || 
!elementToValueIsSymbol(car(l))) {
+    if (isNil(l) || !elementToValueIsSymbol(v) || 
!elementToValueIsSymbol(car(l)))
         return cons(v, l);
-    }
-    if (car<value>(car(l)) != car<value>(v)) {
+    if (car<value>(car(l)) != car<value>(v))
         return cons(v, l);
-    }
     if (!elementToValueIsList(cadr<value>(car(l)))) {
         const value g = mklist<value>(car<value>(v), 
mklist<value>(cdr<value>(v), cdr<value>(car(l))));
         return elementToValueGroupValues(g, cdr(l));
@@ -167,9 +181,7 @@
 
 const list<value> elementsToValues(const list<value>& e) {
     if (isNil(e))
-        return list<value>();
-    const value v = elementToValue(car(e));
-    const list<value> n = elementsToValues(cdr(e));
+        return e;
     return elementToValueGroupValues(elementToValue(car(e)), 
elementsToValues(cdr(e)));
 }
 
@@ -207,7 +219,7 @@
  */
 const list<value> valuesToElements(const list<value>& l) {
     if (isNil(l))
-        return list<value>();
+        return l;
     return cons<value>(valueToElement(car(l)), valuesToElements(cdr(l)));
 }
 
@@ -219,19 +231,19 @@
     const list<value> select;
     selectorLambda(const list<value>& s) : select(s) {
     }
-    const bool evalExpr(const list<value>& s, const list<value> v) const {
+    const bool evalSelect(const list<value>& s, const list<value> v) const {
         if (isNil(s))
             return true;
         if (isNil(v))
             return false;
         if (car(s) != car(v))
             return false;
-        return evalExpr(cdr(s), cdr(v));
+        return evalSelect(cdr(s), cdr(v));
     }
     const bool operator()(const value& v) const {
         if (!isList(v))
             return false;
-        return evalExpr(select, v);
+        return evalSelect(select, v);
     }
 };
 
@@ -239,5 +251,50 @@
     return selectorLambda(s);
 }
 
+/**
+ * Returns the value of the attribute with the given name.
+ */
+struct filterAttribute {
+    const value name;
+    filterAttribute(const value& n) : name(n) {
+    }
+    const bool operator()(const value& v) const {
+        return isAttribute(v) && attributeName((list<value>)v) == name;
+    }
+};
+
+const value attributeValue(const value& name, const value& l) {
+    const list<value> f = filter<value>(filterAttribute(name), list<value>(l));
+    if (isNil(f))
+        return value();
+    return caddr<value>(car(f));
+}
+
+/**
+ * Returns child elements with the given name.
+ */
+struct filterElement {
+    const value name;
+    filterElement(const value& n) : name(n) {
+    }
+    const bool operator()(const value& v) const {
+        return isElement(v) && elementName((list<value>)v) == name;
+    }
+};
+
+const value elementChildren(const value& name, const value& l) {
+    return filter<value>(filterElement(name), list<value>(l));
+}
+
+/**
+ * Return the child element with the given name.
+ */
+const value elementChild(const value& name, const value& l) {
+    const list<value> f = elementChildren(name, l);
+    if (isNil(f))
+        return value();
+    return car(f);
+}
+
 }
 #endif /* tuscany_element_hpp */

Modified: tuscany/cpp/sca/kernel/kernel-test.cpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/kernel-test.cpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/kernel-test.cpp (original)
+++ tuscany/cpp/sca/kernel/kernel-test.cpp Mon Nov 16 06:00:12 2009
@@ -650,7 +650,8 @@
     assert((m >> success<int, std::string>()) == m);
     assert(m >> failableF >> failableG == m >> failableH);
 
-    failable<int, std::string> ooops("ooops");
+    failable<int, std::string> ooops = mkfailure<int, std::string>("ooops");
+    assert(reason(ooops) == "ooops");
     assert(ooops >> failableF >> failableG == ooops);
     return true;
 }

Modified: tuscany/cpp/sca/kernel/list.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/list.hpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/list.hpp (original)
+++ tuscany/cpp/sca/kernel/list.hpp Mon Nov 16 06:00:12 2009
@@ -175,17 +175,10 @@
 }
 
 /**
- * Construct a list from a single value.
- */
-template<typename T> const list<T> cons(const T& car) {
-    return list<T> (car, result(list<T> ()));
-}
-
-/**
  * Construct a list of one value.
  */
 template<typename T> const list<T> mklist(const T& car) {
-    return cons<T>(car);
+    return list<T> (car, result(list<T> ()));
 }
 
 /**

Modified: tuscany/cpp/sca/kernel/monad.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/monad.hpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/monad.hpp (original)
+++ tuscany/cpp/sca/kernel/monad.hpp Mon Nov 16 06:00:12 2009
@@ -68,6 +68,14 @@
 };
 
 /**
+ * Write an identity monad to a stream.
+ */
+template<typename V> std::ostream& operator<<(std::ostream& out, const id<V>& 
m) {
+    out << (V)m;
+    return out;
+}
+
+/**
  * Return an identity monad from a value.
  */
 template<typename V> const id<V> mkunit(const V& v) {
@@ -134,6 +142,18 @@
 };
 
 /**
+ * Write a maybe monad to a stream.
+ */
+template<typename V> std::ostream& operator<<(std::ostream& out, const 
maybe<V>& m) {
+    if (!hasValue(m)) {
+        out << "nothing";
+        return out;
+    }
+    out << (V)m;
+    return out;
+}
+
+/**
  * Return a maybe monad with a value in it.
  */
 template<typename V> const maybe<V> mkjust(const V& v) {
@@ -174,20 +194,23 @@
  */
 template<typename V, typename F> class failable {
 public:
+    failable() : hasv(false) {
+    }
+
     failable(const V& v) : hasv(true), v(v) {
     }
 
-    failable(const F& f) : hasv(false), f(f) {
+    failable(const failable<V, F>& m) : hasv(m.hasv) {
+        if (hasv)
+            v = m.v;
+        else
+            f = m.f;
     }
 
     operator const V() const {
         return v;
     }
 
-    operator const F() const {
-        return f;
-    }
-
     const failable<V, F>& operator=(const failable<V, F>& m) {
         if(this == &m)
             return *this;
@@ -212,14 +235,32 @@
     }
 
 private:
-    const bool hasv;
+    bool hasv;
     V v;
     F f;
 
+    failable(const bool hasv, const F& f) : hasv(hasv), f(f) {
+    }
+
     template<typename A, typename B> friend const bool hasValue(const 
failable<A, B>& m);
+    template<typename A, typename B> friend const B reason(const failable<A, 
B>& m);
+    template<typename A, typename B> friend const failable<A, B> 
mkfailure(const B& f);
 };
 
 /**
+ * Write a failable monad to a stream.
+ */
+template<typename V, typename F> std::ostream& operator<<(std::ostream& out, 
const failable<V, F>& m) {
+    if (!hasValue(m)) {
+        out << reason(m);
+        return out;
+    }
+    const V v = m;
+    out << v;
+    return out;
+}
+
+/**
  * Returns a failable monad with a success value in it.
  */
 template<typename V, typename F> const failable<V, F> mksuccess(const V& v) {
@@ -231,6 +272,17 @@
 }
 
 /**
+ * Returns a failable monad with a failure in it.
+ */
+template<typename V, typename F> const failable<V, F> mkfailure(const F& f) {
+    return failable<V, F>(false, f);
+}
+
+template<typename V, typename F> const lambda<failable<V, F>(V)> failure() {
+    return mkfailure<V, F>;
+}
+
+/**
  * Returns true if the monad contains a value.
  */
 template<typename V, typename F> const bool hasValue(const failable<V, F>& m) {
@@ -238,6 +290,13 @@
 }
 
 /**
+ * Returns the reason for failure of a failable monad.
+ */
+template<typename V, typename F> const F reason(const failable<V, F>& m) {
+    return m.f;
+}
+
+/**
  * Bind a function to a failable monad. Passes the success value in the monad 
to the function
  * if present, or does nothing if there's no value and a failure instead.
  */
@@ -330,6 +389,16 @@
 };
 
 /**
+ * Write a state monad to a stream.
+ */
+template<typename S, typename V> std::ostream& operator<<(std::ostream& out, 
const state<S, V>& m) {
+    const S s = m;
+    const V v = m;
+    out << '(' << s << ' ' << v << ')';
+    return out;
+}
+
+/**
  * Return a state monad carrying a result value.
  */
 template<typename S, typename V> struct returnState {

Modified: tuscany/cpp/sca/kernel/value.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/value.hpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/value.hpp (original)
+++ tuscany/cpp/sca/kernel/value.hpp Mon Nov 16 06:00:12 2009
@@ -362,7 +362,9 @@
 
 };
 
-
+/**
+ * Write a value to a stream.
+ */
 std::ostream& operator<<(std::ostream& out, const value& v) {
     switch(v.type) {
     case value::List:
@@ -399,46 +401,86 @@
     }
 }
 
+/**
+ * Returns the type of a value.
+ */
 const value::ValueType type(const value& v) {
     return v.type;
 }
 
+/**
+ * Returns true if a value is nil.
+ */
 const bool isNil(const value& value) {
     return value.type == value::Undefined;
 }
 
+/**
+ * Returns true if a value is a lambda.
+ */
+const bool isLambda(const value& value) {
+    return value.type == value::Lambda;
+}
+
+/**
+ * Returns true if a value is a string.
+ */
 const bool isString(const value& value) {
     return value.type == value::String;
 }
 
+/**
+ * Returns true if a value is a symbol.
+ */
 const bool isSymbol(const value& value) {
     return value.type == value::Symbol;
 }
 
+/**
+ * Returns true if a value is a list.
+ */
 const bool isList(const value& value) {
     return value.type == value::List;
 }
 
+/**
+ * Returns true if a value is a number.
+ */
 const bool isNumber(const value& value) {
     return value.type == value::Number;
 }
 
+/**
+ * Returns true if a value is a boolean.
+ */
 const bool isBool(const value& value) {
     return value.type == value::Bool;
 }
 
+/**
+ * Returns true if a value is a character.
+ */
 const bool isChar(const value& value) {
     return value.type == value::Char;
 }
 
+/**
+ * Returns true if a value is a pointer.
+ */
 const bool isPtr(const value& value) {
     return value.type == value::Ptr;
 }
 
+/**
+ * Returns true if a value is a pooled pointer.
+ */
 const bool isPoolPtr(const value& value) {
     return value.type == value::PoolPtr;
 }
 
+/**
+ * Returns true if a value is a tagged list.
+ */
 const bool isTaggedList(const value& exp, value tag) {
     if(isList(exp) && !isNil((list<value>)exp))
         return car((list<value>)exp) == tag;

Modified: tuscany/cpp/sca/kernel/xml.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/kernel/xml.hpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/kernel/xml.hpp (original)
+++ tuscany/cpp/sca/kernel/xml.hpp Mon Nov 16 06:00:12 2009
@@ -144,7 +144,7 @@
  */
 const value readToken(XMLReader& reader) {
     const int tokenType = reader.read();
-    if (tokenType == XMLReader::End)
+    if (tokenType == XMLReader::None || tokenType == XMLReader::End)
         return value();
     if (tokenType == XMLReader::Element)
         return startElement;
@@ -228,7 +228,7 @@
  */
 const list<value> expandElementValues(const value& n, const list<value>& l) {
     if (isNil(l))
-        return list<value>();
+        return l;
     return cons<value>(value(cons<value>(element, cons<value>(n, 
(list<value>)car(l)))), expandElementValues(n, cdr(l)));
 }
 
@@ -240,7 +240,7 @@
     const value token(car(l));
     if (isTaggedList(token, attribute)) {
         if (xmlTextWriterWriteAttribute(xml, (const 
xmlChar*)std::string(attributeName(token)).c_str(), (const 
xmlChar*)std::string(attributeValue(token)).c_str()) < 0)
-            return std::string("xmlTextWriterWriteAttribute failed");
+            return mkfailure<bool, std::string>("xmlTextWriterWriteAttribute 
failed");
 
     } else if (isTaggedList(token, element)) {
 
@@ -257,7 +257,7 @@
 
                 // Write an element with a single value
                 if (xmlTextWriterStartElement(xml, (const 
xmlChar*)std::string(elementName(token)).c_str()) < 0)
-                    return std::string("xmlTextWriterStartElement failed");
+                    return mkfailure<bool, 
std::string>("xmlTextWriterStartElement failed");
 
                 // Write its children
                 const failable<bool, std::string> w = 
writeList(elementChildren(token), xml);
@@ -265,14 +265,14 @@
                     return w;
 
                 if (xmlTextWriterEndElement(xml) < 0)
-                    return std::string("xmlTextWriterEndElement failed");
+                    return mkfailure<bool, 
std::string>("xmlTextWriterEndElement failed");
             }
         }
         else {
 
             // Write an element
             if (xmlTextWriterStartElement(xml, (const 
xmlChar*)std::string(elementName(token)).c_str()) < 0)
-                return std::string("xmlTextWriterStartElement failed");
+                return mkfailure<bool, std::string>("xmlTextWriterStartElement 
failed");
 
             // Write its children
             const failable<bool, std::string> w = 
writeList(elementChildren(token), xml);
@@ -280,13 +280,13 @@
                 return w;
 
             if (xmlTextWriterEndElement(xml) < 0)
-                return std::string("xmlTextWriterEndElement failed");
+                return mkfailure<bool, std::string>("xmlTextWriterEndElement 
failed");
         }
     } else {
 
         // Write XML text
         if (xmlTextWriterWriteString(xml, (const 
xmlChar*)std::string(token).c_str()) < 0)
-            return std::string("xmlTextWriterWriteString failed");
+            return mkfailure<bool, std::string>("xmlTextWriterWriteString 
failed");
 
     }
 
@@ -299,14 +299,14 @@
  */
 const failable<bool, std::string> write(const list<value>& l, const 
xmlTextWriterPtr xml) {
     if (xmlTextWriterStartDocument(xml, NULL, encoding, NULL) < 0)
-        return std::string("xmlTextWriterStartDocument failed");
+        return mkfailure<bool, std::string>("xmlTextWriterStartDocument 
failed");
 
     const failable<bool, std::string> w = writeList(l, xml);
     if (!hasValue(w))
         return w;
 
     if (xmlTextWriterEndDocument(xml) < 0)
-        return std::string("xmlTextWriterEndDocument failed");
+        return mkfailure<bool, std::string>("xmlTextWriterEndDocument failed");
     return true;
 }
 
@@ -337,15 +337,15 @@
     XMLWriteContext<R> cx(reduce, initial);
     xmlOutputBufferPtr out = xmlOutputBufferCreateIO(writeCallback<R>, NULL, 
&cx, NULL);
     if (out == NULL)
-        return std::string("xmlOutputBufferCreateIO failed");
+        return mkfailure<R, std::string>("xmlOutputBufferCreateIO failed");
     xmlTextWriterPtr xml = xmlNewTextWriter(out);
     if (xml == NULL)
-        return std::string("xmlNewTextWriter failed");
+        return mkfailure<R, std::string>("xmlNewTextWriter failed");
 
     const failable<bool, std::string> w = write(l, xml);
     xmlFreeTextWriter(xml);
     if (!hasValue(w)) {
-        return std::string(w);
+        return mkfailure<R, std::string>(reason(w));
     }
     return cx.accum;
 }

Modified: tuscany/cpp/sca/modules/atom/atom.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/atom/atom.hpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/atom/atom.hpp (original)
+++ tuscany/cpp/sca/modules/atom/atom.hpp Mon Nov 16 06:00:12 2009
@@ -52,7 +52,7 @@
  */
 const list<value> entriesValues(const list<value>& e) {
     if (isNil(e))
-        return list<value>();
+        return e;
     return cons<value>(entryValue(car(e)), entriesValues(cdr(e)));
 }
 
@@ -62,7 +62,7 @@
 const failable<list<value>, std::string> readEntry(const list<std::string>& 
ilist) {
     const list<value> e = readXML(ilist);
     if (isNil(e))
-        return std::string("Empty entry");
+        return mkfailure<list<value>, std::string>("Empty entry");
     return entryValue(car(e));
 }
 
@@ -72,7 +72,7 @@
 const failable<list<value>, std::string> readFeed(const list<std::string>& 
ilist) {
     const list<value> f = readXML(ilist);
     if (isNil(f))
-        return std::string("Empty feed");
+        return mkfailure<list<value>, std::string>("Empty feed");
     const list<value> t = filter<value>(selector(mklist<value>(element, 
"title")), car(f));
     const list<value> i = filter<value>(selector(mklist<value>(element, 
"id")), car(f));
     const list<value> e = filter<value>(selector(mklist<value>(element, 
"entry")), car(f));
@@ -99,7 +99,7 @@
  */
 const list<value> entriesElements(const list<value>& l) {
     if (isNil(l))
-        return list<value>();
+        return l;
     return cons<value>(entryElement(car(l)), entriesElements(cdr(l)));
 }
 
@@ -156,7 +156,7 @@
  */
 const list<value> feedValuesToElementsLoop(const list<value> val) {
     if (isNil(val))
-        return list<value>();
+        return val;
     return cons<value>(entryValuesToElements(car(val)), 
feedValuesToElementsLoop(cdr(val)));
 }
 

Modified: tuscany/cpp/sca/modules/http/curl.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/http/curl.hpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/http/curl.hpp (original)
+++ tuscany/cpp/sca/modules/http/curl.hpp Mon Nov 16 06:00:12 2009
@@ -137,13 +137,13 @@
  * Apply an HTTP verb to a list containing a list of headers and a list of 
content, and
  * a reduce function used to process the response.
  */
-curl_slist* headers(curl_slist* cl, const list<std::string> h) {
+curl_slist* headers(curl_slist* cl, const list<std::string>& h) {
     if (isNil(h))
         return cl;
     return headers(curl_slist_append(cl, std::string(car(h)).c_str()), cdr(h));
 }
 
-template<typename R> const failable<list<R>, std::string> apply(const 
list<list<std::string> > req, const lambda<R(std::string, R)>& reduce, const R& 
initial, const std::string& url, const std::string& verb, CURLHandle& ch) {
+template<typename R> const failable<list<R>, std::string> apply(const 
list<list<std::string> >& req, const lambda<R(std::string, R)>& reduce, const 
R& initial, const std::string& url, const std::string& verb, const CURLHandle& 
ch) {
 
     // Init the curl session
     curl_easy_reset(ch);
@@ -190,13 +190,13 @@
 
     // Return the HTTP return code or content
     if (rc)
-        return std::string(curl_easy_strerror(rc));
+        return mkfailure<list<R>, std::string>(curl_easy_strerror(rc));
     long httprc;
     curl_easy_getinfo (ch, CURLINFO_RESPONSE_CODE, &httprc);
     if (httprc != 200 && httprc != 201) {
         std::ostringstream es;
         es << "HTTP code " << httprc;
-        return es.str();
+        return mkfailure<list<R>, std::string>(es.str());
     }
     return mklist<R>(hcx.accum, wcx.accum);
 }
@@ -204,13 +204,13 @@
 /**
  * Evaluate an expression remotely, at the given URL.
  */
-const failable<value, std::string>  evalExpr(const value expr, const 
std::string& url, CURLHandle& ch) {
+const failable<value, std::string> evalExpr(const value& expr, const 
std::string& url, const CURLHandle& ch) {
 
     // Convert expression to a JSON-RPC request
     json::JSONContext cx;
     const failable<list<std::string>, std::string> jsreq = jsonRequest(1, 
car<value>(expr), cdr<value>(expr), cx);
     if (!hasValue(jsreq))
-        return std::string(jsreq);
+        return mkfailure<value, std::string>(reason(jsreq));
 
     if (logContent) {
         std::cout<< "content: " << std::endl;
@@ -223,7 +223,7 @@
     const list<std::string> h = mklist<std::string>("Content-Type: 
application/json-rpc");
     const failable<list<list<std::string> >, std::string> res = 
apply<list<std::string> >(mklist<list<std::string> >(h, jsreq), 
rcons<std::string>, list<std::string>(), url, "POST", ch);
     if (!hasValue(res))
-        return std::string(res);
+        return mkfailure<value, std::string>(reason(res));
 
     // Return result
     if (logContent) {
@@ -238,7 +238,7 @@
 /**
  * HTTP GET, return the resource at the given URL.
  */
-template<typename R> const failable<list<R>, std::string> get(const 
lambda<R(std::string, R)>& reduce, const R& initial, const std::string& url, 
CURLHandle& ch) {
+template<typename R> const failable<list<R>, std::string> get(const 
lambda<R(std::string, R)>& reduce, const R& initial, const std::string& url, 
const CURLHandle& ch) {
     const list<list<std::string> > req = mklist(list<std::string>(), 
list<std::string>());
     return apply(req, reduce, initial, url, "GET", ch);
 }
@@ -246,17 +246,17 @@
 /**
  * HTTP GET, return a list of values representing the resource at the given 
URL.
  */
-const failable<value, std::string> get(const std::string& url, CURLHandle& ch) 
{
+const failable<value, std::string> get(const std::string& url, const 
CURLHandle& ch) {
 
     // Get the contents of the resource at the given URL
     const failable<list<list<std::string> >, std::string> res = 
get<list<std::string> >(rcons<std::string>, list<std::string>(), url, ch);
     if (!hasValue(res))
-        return std::string(res);
+        return mkfailure<value, std::string>(reason(res));
     const list<list<std::string> > ls = res;
 
-    // TODO Return an ATOM feed
     const std::string ct;
     if (ct.find("application/atom+xml") != std::string::npos) {
+        // TODO Return an ATOM feed
     }
 
     // Return the content as a string value
@@ -268,12 +268,12 @@
 /**
  * HTTP POST.
  */
-const failable<value, std::string> post(const value& val, const std::string& 
url, CURLHandle& ch) {
+const failable<value, std::string> post(const value& val, const std::string& 
url, const CURLHandle& ch) {
 
     // Convert value to an ATOM entry
     const failable<list<std::string>, std::string> entry = 
atom::writeATOMEntry(atom::entryValuesToElements(val));
     if (!hasValue(entry))
-        return std::string(entry);
+        return mkfailure<value, std::string>(reason(entry));
     if (logContent) {
         std::cout << "content:" << std::endl;
         write(list<std::string>(entry), std::cout);
@@ -285,45 +285,63 @@
     const list<list<std::string> > req = mklist<list<std::string> >(h, entry);
     const failable<list<list<std::string> >, std::string> res = 
apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, 
"POST", ch);
     if (!hasValue(res))
-        return std::string(res);
+        return mkfailure<value, std::string>(reason(res));
     return value(true);
 }
 
 /**
  * HTTP PUT.
  */
-const failable<value, std::string> put(const value& val, const std::string& 
url, CURLHandle& ch) {
+const failable<value, std::string> put(const value& val, const std::string& 
url, const CURLHandle& ch) {
 
     // Convert value to an ATOM entry
     const failable<list<std::string>, std::string> entry = 
atom::writeATOMEntry(atom::entryValuesToElements(val));
     if (!hasValue(entry))
-        return std::string(entry);
+        return mkfailure<value, std::string>(reason(entry));
     if (logContent) {
         std::cout << "content:" << std::endl;
         write(list<std::string>(entry), std::cout);
         std::cout << std::endl;
     }
 
-    // POST it to the URL
+    // PUT it to the URL
     const list<std::string> h = mklist<std::string>("Content-Type: 
application/atom+xml");
     const list<list<std::string> > req = mklist<list<std::string> >(h, entry);
     const failable<list<list<std::string> >, std::string> res = 
apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, 
"PUT", ch);
     if (!hasValue(res))
-        return std::string(res);
+        return mkfailure<value, std::string>(reason(res));
     return value(true);
 }
 
 /**
  * HTTP DELETE.
  */
-const failable<value, std::string> del(const std::string& url, CURLHandle& ch) 
{
+const failable<value, std::string> del(const std::string& url, const 
CURLHandle& ch) {
     const list<list<std::string> > req = mklist(list<std::string>(), 
list<std::string>());
     const failable<list<list<std::string> >, std::string> res = 
apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, 
"DELETE", ch);
     if (!hasValue(res))
-        return std::string(res);
+        return mkfailure<value, std::string>(reason(res));
     return value(true);
 }
 
+/**
+ * HTTP client proxy function.
+ */
+struct proxy {
+    proxy(const std::string& url, const CURLHandle& ch) : url(url), ch(ch) {
+    }
+
+    const value operator()(const list<value>& args) const {
+        failable<value, std::string> val = evalExpr(args, url, ch);
+        if (!hasValue(val))
+            return value();
+        return val;
+    }
+
+    const std::string url;
+    const CURLHandle& ch;
+};
+
 }
 }
 

Modified: tuscany/cpp/sca/modules/json/json.hpp
URL: 
http://svn.apache.org/viewvc/tuscany/cpp/sca/modules/json/json.hpp?rev=880598&r1=880597&r2=880598&view=diff
==============================================================================
--- tuscany/cpp/sca/modules/json/json.hpp (original)
+++ tuscany/cpp/sca/modules/json/json.hpp Mon Nov 16 06:00:12 2009
@@ -200,7 +200,7 @@
         return true;
     JSString* jstr = JS_NewStringCopyZ(cx, car(ilist).c_str());
     if(!JS_ConsumeJSONText(cx, parser, JS_GetStringChars(jstr), 
JS_GetStringLength(jstr)))
-        return "JS_ConsumeJSONText failed";
+        return mkfailure<bool, std::string>("JS_ConsumeJSONText failed");
     return consume(parser, cdr(ilist), cx);
 }
 
@@ -211,14 +211,14 @@
     jsval val;
     JSONParser* parser = JS_BeginJSONParse(cx, &val);
     if(parser == NULL)
-        return std::string("JS_BeginJSONParse failed");
+        return mkfailure<list<value>, std::string>("JS_BeginJSONParse failed");
 
     const failable<bool, std::string> consumed = consume(parser, ilist, cx);
 
     if(!JS_FinishJSONParse(cx, parser, JSVAL_NULL))
-        return std::string("JS_FinishJSONParse failed");
+        return mkfailure<list<value>, std::string>("JS_FinishJSONParse 
failed");
     if(!hasValue(consumed))
-        return std::string(consumed);
+        return mkfailure<list<value>, std::string>(reason(consumed));
 
     return list<value>(jsValToValue(val, cx));
 }
@@ -357,11 +357,11 @@
     jsval val = OBJECT_TO_JSVAL(o);
     const failable<bool, std::string> w = writeList(l, o, cx);
     if (!hasValue(w))
-        return std::string(w);
+        return mkfailure<R, std::string>(reason(w));
 
     WriteContext<R> wcx(reduce, initial, cx);
     if (!JS_Stringify(cx, &val, NULL, JSVAL_NULL, writeCallback<R>, &wcx))
-        return std::string("JS_Stringify failed");
+        return mkfailure<R, std::string>("JS_Stringify failed");
     return wcx.accum;
 }
 
@@ -380,8 +380,7 @@
  */
 const failable<list<std::string>, std::string> jsonRequest(const value& id, 
const value& func, const value& params, json::JSONContext& cx) {
     const list<value> r = mklist<value>(mklist<value>("id", id), 
mklist<value>("method", func), mklist<value>("params", params));
-    failable<list<std::string>, std::string> ls = 
writeJSON(valuesToElements(r), cx);
-    return ls;
+    return writeJSON(valuesToElements(r), cx);
 }
 
 /**


Reply via email to