From c9bfccc35345ce58fb5774d4b0b6a9868b262c0a Mon Sep 17 00:00:00 2001 From: giorgio Date: Wed, 5 Sep 2012 08:31:30 +0000 Subject: git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1381061 13f79535-47bb-0310-9956-ffa450edef68 --- .../branches/lightweight-sca/kernel/sstream.hpp | 262 +++++++++++++++++++++ 1 file changed, 262 insertions(+) create mode 100644 sca-cpp/branches/lightweight-sca/kernel/sstream.hpp (limited to 'sca-cpp/branches/lightweight-sca/kernel/sstream.hpp') 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 +#include +#include +#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& 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 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 tokenize(const char* sep, const string& str) { + struct nested { + static const list tokenize(const char* sep, const size_t slen, const string& str, const size_t start) { + if (start >= length(str)) + return list(); + 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& l) { + struct nested { + static ostringstream& join(const char* sep, const list& 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 operator()() { + char buffer[1024]; + const size_t n = read(is, buffer, sizeof(buffer)); + if (n ==0) + return list(); + return cons(string(buffer, n), (*this)()); + } +}; + +const list streamList(istream& is) { + return ilistRead(is)(); +} + +/** + * Fragment the first element of a list of strings to fit the given max length. + */ +const list fragment(list 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& l, ostream& os) { + if(isNil(l)) + return os; + os << car(l); + return write(cdr(l), os); +} + +} + +#endif /* tuscany_sstream_hpp */ -- cgit v1.2.3