diff options
author | Nicolas Catania <niko@google.com> | 2010-01-26 20:36:16 -0800 |
---|---|---|
committer | Nicolas Catania <niko@google.com> | 2010-02-05 17:01:13 -0800 |
commit | f759b92d2877872c2f9300304d5aee0e41bd1306 (patch) | |
tree | 8fa829c59b829adda055706ca7c8c913e30a99d2 | |
parent | 808f34a8cab52569bfca26cec6fd96740aa2ea25 (diff) | |
download | astl-f759b92d2877872c2f9300304d5aee0e41bd1306.tar.gz |
First cut of the sstream implementation.
Added the sstream header file the stringbuf and stringstream classes.
Added missing openmode flags in ios_base.h
-rw-r--r-- | include/ios_base.h | 38 | ||||
-rw-r--r-- | include/sstream | 121 | ||||
-rw-r--r-- | src/Android.mk | 1 | ||||
-rw-r--r-- | src/sstream.cpp | 87 | ||||
-rw-r--r-- | tests/Android.mk | 1 | ||||
-rw-r--r-- | tests/test_sstream.cpp | 118 |
6 files changed, 363 insertions, 3 deletions
diff --git a/include/ios_base.h b/include/ios_base.h index 2fe6660..57f3913 100644 --- a/include/ios_base.h +++ b/include/ios_base.h @@ -56,6 +56,18 @@ enum IosBaseFlags { ios_baseflags_floatfield = ios_baseflags_scientific | ios_baseflags_fixed, ios_baseflags_end = 1 << 15 }; + +// Openmode +enum IosBaseOpenmode { + ios_baseopenmode_app = 1 << 0, + ios_baseopenmode_ate = 1 << 1, + ios_baseopenmode_binary = 1 << 2, + ios_baseopenmode_in = 1 << 3, + ios_baseopenmode_out = 1 << 4, + ios_baseopenmode_trunc = 1 << 5, + ios_baseopenmode_end = 1 << 6 +}; + } // namespace android namespace std { @@ -74,9 +86,6 @@ namespace std { class ios_base { public: - typedef int io_state; - typedef int open_mode; - typedef int seek_dir; typedef std::streampos streampos; typedef std::streamoff streamoff; @@ -87,6 +96,11 @@ class ios_base public: virtual ~ios_base(); typedef int fmtflags; + typedef int iostate; + typedef int openmode; + typedef int seekdir; + + // FLAGS // boolalpha: Insert and extract bool type in alphabetic format. // dec: Convert integer input or generates integer output in @@ -151,6 +165,24 @@ class ios_base // Clears 'mask'. void unsetf(fmtflags mask); + + // OPENMODE + + // app: seek to end before each write. + // ate: open and seek to end imediately after opening. + // binary: perform I/O in binary mode. + // in: open for input. + // out: open for output. + // trunc: truncate and existing stream when opening. + static const openmode app = android::ios_baseopenmode_app; + static const openmode ate = android::ios_baseopenmode_ate; + static const openmode binary = android::ios_baseopenmode_binary; + static const openmode in = android::ios_baseopenmode_in; + static const openmode out = android::ios_baseopenmode_out; + static const openmode trunc = android::ios_baseopenmode_trunc; + + // PRECISION and WIDTH + /** * @return The precision (number of digits after the decimal * point) to generate on certain output conversions. 6 by default. diff --git a/include/sstream b/include/sstream new file mode 100644 index 0000000..ec75297 --- /dev/null +++ b/include/sstream @@ -0,0 +1,121 @@ +/* -*- 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_SSTREAM__ +#define ANDROID_ASTL_SSTREAM__ + +#include <char_traits.h> +#include <ios_base.h> +#include <streambuf> +#include <string> +#include <ostream> + +namespace std { + +// Declare basic_stringbuf which is a buffer implemented using a std::string. +// Then declare stringstream which implement a stream using basic_stringbuf. + +struct basic_stringbuf : public streambuf { + public: + typedef streambuf::traits_type traits_type; + typedef streambuf::char_type char_type; + typedef streambuf::int_type int_type; + typedef streambuf::pos_type pos_type; + typedef streambuf::off_type off_type; + + // Construct an instance, in/out by default. + explicit basic_stringbuf(ios_base::openmode mode = + ios_base::in | ios_base::out); + + // Construct an instance and copy str into the underlying buffer + // and initialize the input and output sequence according to the + // flags set in mode. + explicit basic_stringbuf(const string& str, + ios_base::openmode mode = + ios_base::in | ios_base::out); + + virtual ~basic_stringbuf(); + + // @return A copy of the underlying buffer. If the buffer was + // creted in input mode, this is equal to the the input + // sequence. Otherwise it is equal to the output sequence. + // TODO: In the standard a copy is returned instead of const ref - + // not sure why. + const string& str() const; + + // Clear the current buffer then copy the content of str into + // it. Initialize the input/output sequences according to the mode + // used. + // @param str The string to use as a new sequence. + void str(const string & str); + + // @return -1 on output stream otherwise the number char available + // for reading. + streamsize in_avail(); + + protected: + // Override the default impl from ostream to do the work. + virtual streamsize xsputn(const char_type* str, streamsize num); + + ios_base::openmode mMode; + string mString; +}; + +// In a regular STL this is <char> full specialization. +typedef basic_stringbuf stringbuf; + + +class stringstream : public ostream { + public: + explicit stringstream(ios_base::openmode mode = + ios_base::in | ios_base::out); + + explicit stringstream(const string& str, + ios_base::openmode mode = + ios_base::in | ios_base::out); + virtual ~stringstream(); + + const string& str() const { return mStringBuf.str(); } + void str(const string & str) { mStringBuf.str(str); } + + // TODO: move this to ostream. + ostream& put(char c); + + private: + basic_stringbuf mStringBuf; +}; + +// In a regular STL stringstream inherits from ostringstream and +// istringstream. Since we use stringstream everywhere we just declare +// ostringstream as an alias to pass compilation. +typedef stringstream ostringstream; + +} // namespace std + +#endif // ANDROID_ASTL_SSTREAM__ diff --git a/src/Android.mk b/src/Android.mk index 0dcf05d..85b1a68 100644 --- a/src/Android.mk +++ b/src/Android.mk @@ -23,6 +23,7 @@ astl_common_src_files := \ ios_pos_types.cpp \ list.cpp \ ostream.cpp \ + sstream.cpp \ stdio_filebuf.cpp \ streambuf.cpp \ string.cpp diff --git a/src/sstream.cpp b/src/sstream.cpp new file mode 100644 index 0000000..a97540c --- /dev/null +++ b/src/sstream.cpp @@ -0,0 +1,87 @@ +/* + * 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 <sstream> +#include <streambuf> +#include <ios_base.h> + +namespace std { + +// basic_stringbuf + +basic_stringbuf::basic_stringbuf(ios_base::openmode mode) : + mMode(mode) { } + +basic_stringbuf::basic_stringbuf(const string& str, ios_base::openmode mode) : + mMode(mode), mString(str) { } + +basic_stringbuf::~basic_stringbuf() { } + +const string& basic_stringbuf::str() const { + return mString; +} + +void basic_stringbuf::str(const string& str) { + mString = str; +} + +streamsize basic_stringbuf::in_avail() { + if (mMode & std::ios_base::in) { + return mString.size(); + } else { + return -1; + } +} + +streamsize basic_stringbuf::xsputn(const char_type* str, streamsize num) { + mString.append(str, num); + return num; +} + + +// stringstream + +stringstream::stringstream(std::ios_base::openmode mode) + : mStringBuf(mode) { + this->init(&mStringBuf); +} + +stringstream::stringstream(const string& str, + std::ios_base::openmode mode) + : mStringBuf(str, mode) { + this->init(&mStringBuf); +} + +stringstream::~stringstream() {} + +ostream& stringstream::put(char c) { + mStringBuf.sputc(c); + return *this; +} + +} // namespace std diff --git a/tests/Android.mk b/tests/Android.mk index ddf3974..3233619 100644 --- a/tests/Android.mk +++ b/tests/Android.mk @@ -73,6 +73,7 @@ sources := \ test_list.cpp \ test_memory.cpp \ test_set.cpp \ + test_sstream.cpp \ test_streambuf.cpp \ test_string.cpp \ test_type_traits.cpp \ diff --git a/tests/test_sstream.cpp b/tests/test_sstream.cpp new file mode 100644 index 0000000..d229fd5 --- /dev/null +++ b/tests/test_sstream.cpp @@ -0,0 +1,118 @@ +/* -*- 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/sstream" +#ifndef ANDROID_ASTL_SSTREAM__ +#error "Wrong header included!!" +#endif +#include "common.h" + +#include <ios_base.h> +#include <string> + +namespace android { +using std::stringbuf; +using std::stringstream; +using std::string; + +bool testConstructor() { + { + string str("Get out of here and get me some money too."); + stringbuf buf1(str); + stringbuf buf2(str, std::ios_base::in); + stringbuf buf3(str, std::ios_base::out); + + EXPECT_TRUE(buf1.str() == str); + EXPECT_TRUE(buf2.str() == str); + EXPECT_TRUE(buf3.str() == str); + } + return true; +} + +bool testInAvail() { + { + string str("Get out of here and get me some money too."); + stringbuf buf1(str); + stringbuf buf2(str, std::ios_base::in); + stringbuf buf3(str, std::ios_base::out); + stringbuf buf4; + + std::streamsize len1 = buf1.in_avail(); + std::streamsize len2 = buf2.in_avail(); + std::streamsize len3 = buf3.in_avail(); + std::streamsize len4 = buf4.in_avail(); + + EXPECT_TRUE(len1 > 0); + EXPECT_TRUE(len2 > 0); + EXPECT_TRUE(len3 == -1); // out only + EXPECT_TRUE(len4 == 0); // out only + } + return true; +} + +bool testNulChar() { + string str("String with \0 in the middle", 27); + stringbuf buf(str); + + EXPECT_TRUE(buf.in_avail() == 27); + EXPECT_TRUE(buf.str().size() == 27); + return true; +} + +bool testPut() { + stringbuf buf; + + buf.sputc('A'); + buf.sputc('B'); + buf.sputc('C'); + buf.sputc('D'); + EXPECT_TRUE(buf.str() == "ABCD"); + + buf.sputn(" alphabet", 9); + EXPECT_TRUE(buf.str() == "ABCD alphabet"); + return true; +} + +bool testStringStream() { + stringstream ss; + + ss << "This is: " << 10 << std::endl; + EXPECT_TRUE(ss.str() == "This is: 10\n"); + return true; +} +} // namespace android + +int main(int argc, char **argv){ + FAIL_UNLESS(testConstructor); + FAIL_UNLESS(testInAvail); + FAIL_UNLESS(testNulChar); + FAIL_UNLESS(testPut); + FAIL_UNLESS(testStringStream); + return kPassed; +} |