summaryrefslogtreecommitdiffstats
path: root/sca-cpp/branches/lightweight-sca/kernel/sstream.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/branches/lightweight-sca/kernel/sstream.hpp')
-rw-r--r--sca-cpp/branches/lightweight-sca/kernel/sstream.hpp262
1 files changed, 262 insertions, 0 deletions
diff --git a/sca-cpp/branches/lightweight-sca/kernel/sstream.hpp b/sca-cpp/branches/lightweight-sca/kernel/sstream.hpp
new file mode 100644
index 0000000000..17fd28b48b
--- /dev/null
+++ b/sca-cpp/branches/lightweight-sca/kernel/sstream.hpp
@@ -0,0 +1,262 @@
+/*
+ * 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_sstream_hpp
+#define tuscany_sstream_hpp
+
+/**
+ * Char buffer based streams.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <memory.h>
+#include "string.hpp"
+#include "stream.hpp"
+#include "list.hpp"
+
+namespace tuscany {
+
+/**
+ * Instrumentable memcpy.
+ */
+void* stream_memcpy(void* t, const void* s, const size_t n) {
+ return memcpy(t, s, n);
+}
+
+/**
+ * Write a list of strings into a buffer.
+ */
+const bool writeList(const list<string>& l, char* buf) {
+ if (isNil(l))
+ return true;
+ const string c = car(l);
+ char* b = buf - length(c);
+ memcpy(b, c_str(c), length(c));
+ return writeList(cdr(l), b);
+}
+
+/**
+ * Output stream backed by a char buffer.
+ */
+class ostringstream : public ostream {
+public:
+ ostringstream() : len(0) {
+ }
+
+ ~ostringstream() {
+ }
+
+ ostringstream(const ostringstream& os) {
+ len = os.len;
+ buf = os.buf;
+ }
+
+ ostringstream& vprintf(const char* fmt, ...) {
+ va_list args;
+ string s;
+ va_start (args, fmt);
+ s.len = vsnprintf(NULL, 0, fmt, args);
+ s.buf = gc_cnew(s.len + 1);
+ va_start (args, fmt);
+ vsnprintf(s.buf, s.len + 1, fmt, args);
+ buf = cons(s, buf);
+ len += s.len;
+ va_end (args);
+ return *this;
+ }
+
+ ostringstream& write(const string& s) {
+ buf = cons(s, buf);
+ len += s.len;
+ return *this;
+ }
+
+ ostringstream& flush() {
+ return *this;
+ }
+
+private:
+ const string str() {
+ if (isNil(buf))
+ return string();
+ string s;
+ s.len = len;
+ s.buf = gc_cnew(s.len + 1);
+ writeList(buf, s.buf + len);
+ s.buf[s.len] = '\0';
+ return s;
+ }
+
+ friend const string str(ostringstream& os);
+
+ size_t len;
+ list<string> buf;
+};
+
+/**
+ * Return a string representation of a stream.
+ */
+const string str(ostringstream& os) {
+ return os.str();
+}
+
+/**
+ * Input stream backed by a char buffer
+ */
+class istringstream : public istream {
+public:
+ istringstream(const string& s) {
+ cur = 0;
+ const size_t slen = length(s);
+ len = slen;
+ buf = c_str(s);
+ }
+
+ ~istringstream() {
+ }
+
+ istringstream(const istringstream& is) {
+ len = is.len;
+ cur = is.cur;
+ buf = is.buf;
+ }
+
+ const size_t read(void* b, size_t size) {
+ const size_t n = len - cur;
+ if (n == 0)
+ return 0;
+ if (n > size) {
+ stream_memcpy(b, buf + cur, size);
+ cur = cur + size;
+ return size;
+ }
+ stream_memcpy(b, buf + cur, n);
+ cur = cur + n;
+ return n;
+ }
+
+ const bool eof() {
+ return cur == len;
+ }
+
+ const bool fail() {
+ return false;
+ }
+
+ const int get() {
+ if (eof())
+ return -1;
+ const int c = buf[cur];
+ cur += 1;
+ return c;
+ }
+
+ const int peek() {
+ if (eof())
+ return -1;
+ return buf[cur];
+ }
+
+private:
+ size_t len;
+ size_t cur;
+ const char* buf;
+};
+
+/**
+ * Tokenize a string into a list of strings.
+ */
+const list<string> tokenize(const char* sep, const string& str) {
+ struct nested {
+ static const list<string> tokenize(const char* sep, const size_t slen, const string& str, const size_t start) {
+ if (start >= length(str))
+ return list<string>();
+ const size_t i = find(str, sep, start);
+ if (i == length(str))
+ return mklist(string(substr(str, start)));
+ return cons(string(substr(str, start, i - start)), tokenize(sep, slen, str, i + slen));
+ }
+ };
+ return nested::tokenize(sep, strlen(sep), str, 0);
+}
+
+/**
+ * Join a list of strings into a single string.
+ */
+const string join(const char* sep, const list<string>& l) {
+ struct nested {
+ static ostringstream& join(const char* sep, const list<string>& l, ostringstream& os) {
+ if (isNil(l))
+ return os;
+ os << car(l);
+ if (!isNil(cdr(l)))
+ os << sep;
+ return join(sep, cdr(l), os);
+ }
+ };
+ ostringstream os;
+ return str(nested::join(sep, l, os));
+}
+
+/**
+ * Returns a lazy list view of an input stream.
+ */
+struct ilistRead{
+ istream &is;
+ ilistRead(istream& is) : is(is) {
+ }
+ const list<string> operator()() {
+ char buffer[1024];
+ const size_t n = read(is, buffer, sizeof(buffer));
+ if (n ==0)
+ return list<string>();
+ return cons(string(buffer, n), (*this)());
+ }
+};
+
+const list<string> streamList(istream& is) {
+ return ilistRead(is)();
+}
+
+/**
+ * Fragment the first element of a list of strings to fit the given max length.
+ */
+const list<string> fragment(list<string> l, size_t max) {
+ const string s = car(l);
+ if (length(s) <= max)
+ return l;
+ return cons(substr(s, 0, max), cons(substr(s, max), cdr(l)));
+}
+
+/**
+ * Write a list of strings to an output stream.
+ */
+ostream& write(const list<string>& l, ostream& os) {
+ if(isNil(l))
+ return os;
+ os << car(l);
+ return write(cdr(l), os);
+}
+
+}
+
+#endif /* tuscany_sstream_hpp */