aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/streambuf165
-rw-r--r--src/Android.mk1
-rw-r--r--src/streambuf.cpp73
-rw-r--r--tests/Android.mk1
-rw-r--r--tests/test_streambuf.cpp78
5 files changed, 318 insertions, 0 deletions
diff --git a/include/streambuf b/include/streambuf
new file mode 100644
index 0000000..f83dd2f
--- /dev/null
+++ b/include/streambuf
@@ -0,0 +1,165 @@
+/* -*- c++ -*- */
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef ANDROID_ASTL_STREAMBUF__
+#define ANDROID_ASTL_STREAMBUF__
+
+#include <char_traits.h>
+
+namespace std {
+
+/**
+ * Basic implementation of streambuf. The STL standard defines a
+ * basic_streambuf template that gets specialized for char and
+ * wchar. Since Android supports only char, we don't use a template
+ * here.
+ * Only output ops are supported.
+ * There are only 2 public entry points:
+ * - sputc
+ * - sputn
+ */
+
+class streambuf
+{
+ public:
+ typedef char_traits traits_type;
+ typedef traits_type::char_type char_type;
+ typedef traits_type::int_type int_type;
+ typedef streampos pos_type;
+ typedef streamoff off_type;
+
+ public:
+ virtual ~streambuf();
+
+ /**
+ * Entry points for derived buffer functions. The public
+ * version pubfoo dispatch to the protected foo member
+ * functions.
+ */
+ int pubsync() { return this->sync(); }
+
+ /**
+ * Entry point for all single-character output functions. If a
+ * write position is available (buffer not full), stores c at that
+ * position, incr the position and return
+ * traits.::to_int_type(c). If no position is available returns
+ * overflow(c).
+ */
+ int_type sputc(char_type c) {
+ int_type ret;
+
+ if (this->pptr() < this->epptr()) {
+ *this->pptr() = c;
+ this->pbump(1);
+ return traits_type::to_int_type(c);
+ } else {
+ ret = this->overflow(traits_type::to_int_type(c));
+ }
+ return ret;
+ }
+
+ /**
+ * Write str[0] to str[n-1] to output sequence. Stops if sputc
+ * would return traits_type::eof().
+ * @param str A buffer area.
+ * @param nnum Maximum number of characters to write.
+ * @return The number of characters written.
+ */
+ streamsize sputn(const char_type* str, streamsize num) {
+ return this->xsputn(str, num);
+ }
+
+ protected:
+ streambuf();
+
+
+ /**
+ * Access to the put area.
+ * - pbase() returns the beginning pointer for the output sequence.
+ * - pptr() returns the next pointer for the output sequence.
+ * - epptr() returns the end pointer for the output sequence.
+ * - pbump(int) Advance the write postion in the output sequence.
+ */
+ char_type* pbase() const { return mPutBeg; }
+ char_type* pptr() const { return mPutCurr; }
+ char_type* epptr() const { return mPutEnd; }
+ void pbump(int num) {
+ if (mPutCurr + num > mPutCurr && mPutCurr + num <= mPutEnd) {
+ mPutCurr += num;
+ }
+ }
+
+ /**
+ * Set the 3 write pointers.
+ */
+ void setp(char_type* beg, char_type* end) {
+ if (end >= beg) {
+ mPutBeg = mPutCurr = beg;
+ mPutEnd = end;
+ }
+ }
+
+ /**
+ * Sync buffer array. Provided by derived class.
+ */
+ virtual int sync() { return 0; }
+
+ /**
+ * See sputn. Provided by derived class.
+ */
+ virtual streamsize xsputn(const char_type* str, streamsize num);
+
+ /**
+ * Consumes one char from the buffer, writes to the controlled
+ * sequence if possible. This is called when the buffer is
+ * full. Typically the impl will flush the buffer, write the
+ * character 'c'.
+ * Provided by derived class.
+ * @return traits::eof() in case of error, anything else otherwise.
+ */
+ virtual int_type overflow(int_type /* c */ = traits_type::eof())
+ { return traits_type::eof(); }
+
+ /**
+ * Minimal abstraction for an internal buffer.
+ * - put == output == write
+ */
+ char_type* mPutBeg; // Start of put area.
+ char_type* mPutCurr; // Current put area.
+ char_type* mPutEnd; // End of put area.
+
+ private:
+ // No copy constructors.
+ streambuf(const streambuf& sb);
+ streambuf& operator=(const streambuf&) { return *this; }
+};
+
+} // namespace std
+
+#endif
diff --git a/src/Android.mk b/src/Android.mk
index e555dab..c6c3d54 100644
--- a/src/Android.mk
+++ b/src/Android.mk
@@ -22,6 +22,7 @@ astl_common_src_files := \
ios_base.cpp \
ios_pos_types.cpp \
ostream.cpp \
+ streambuf.cpp \
string.cpp
# Build the target lib
diff --git a/src/streambuf.cpp b/src/streambuf.cpp
new file mode 100644
index 0000000..0acebb3
--- /dev/null
+++ b/src/streambuf.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <streambuf>
+#include <algorithm> // for min
+namespace std {
+
+// Implementation of the streambuf, common stuff for all the stream buffers.
+streambuf::streambuf()
+ : mPutBeg(0), mPutCurr(0), mPutEnd(0) { }
+
+streambuf::streambuf(const streambuf& sb)
+ : mPutBeg(sb.mPutBeg), mPutCurr(sb.mPutCurr), mPutEnd(sb.mPutEnd) { }
+
+streambuf::~streambuf() {}
+
+streamsize streambuf::xsputn(const char_type* str, streamsize num) {
+ streamsize written = 0;
+
+ while (written < num) {
+ const streamsize avail = this->epptr() - this->pptr();
+ if (avail) {
+ const streamsize remaining = num - written;
+ const streamsize len = std::min(avail, remaining);
+ traits_type::copy(this->pptr(), str, len);
+ written += len;
+ str += len;
+ this->pbump(len);
+ }
+
+ if (written < num) {
+ // Indicate to the impl that we overflown. Either the impl
+ // can increase its buffer and consume one character (in
+ // which case eof() is not returned) or it can't and we
+ // stop here.
+ int_type c = this->overflow(traits_type::to_int_type(*str));
+ if (!traits_type::eq_int_type(c, traits_type::eof())) {
+ ++written;
+ ++str;
+ } else {
+ break;
+ }
+ }
+ }
+ return written;
+}
+
+} // namespace std
diff --git a/tests/Android.mk b/tests/Android.mk
index 88dd282..5de2eb7 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -70,6 +70,7 @@ sources := \
test_limits.cpp \
test_memory.cpp \
test_set.cpp \
+ test_streambuf.cpp \
test_string.cpp \
test_type_traits.cpp \
test_uninitialized.cpp \
diff --git a/tests/test_streambuf.cpp b/tests/test_streambuf.cpp
new file mode 100644
index 0000000..cc58abc
--- /dev/null
+++ b/tests/test_streambuf.cpp
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "../include/streambuf"
+#ifndef ANDROID_ASTL_STREAMBUF__
+#error "Wrong header included!!"
+#endif
+#include "common.h"
+
+#include <char_traits.h>
+
+namespace android {
+using std::char_traits;
+
+class streambuf: public std::streambuf {
+ public:
+ streambuf() {
+ setp(mBuffer, mBuffer + sizeof(mBuffer));
+ char_traits::assign(mBuffer, sizeof(mBuffer), 'X');
+ }
+
+ char mBuffer[5];
+};
+
+bool testSputc() {
+ streambuf buf;
+
+ EXPECT_TRUE(buf.sputc('A') == 65);
+ EXPECT_TRUE(buf.sputc('B') == 66);
+ EXPECT_TRUE(buf.sputc('C') == 67);
+ EXPECT_TRUE(buf.sputc('D') == 68);
+ EXPECT_TRUE(buf.sputc('E') == 69);
+ EXPECT_TRUE(buf.sputc('F') == char_traits::eof());
+ EXPECT_TRUE(buf.sputc('G') == char_traits::eof());
+ return true;
+}
+
+bool testSputn() {
+ streambuf buf;
+
+ EXPECT_TRUE(buf.sputn("ABCDE", 5) == 5);
+ EXPECT_TRUE(buf.sputn("F", 1) == 0);
+ return true;
+}
+
+} // namespace android
+
+int main(int argc, char **argv){
+ FAIL_UNLESS(testSputc);
+ FAIL_UNLESS(testSputn);
+ return kPassed;
+}