From 44d38f3d1ae0fd02030e259c4f93a265f91e96fc Mon Sep 17 00:00:00 2001 From: Nicolas Catania Date: Thu, 4 Feb 2010 10:10:46 -0800 Subject: Added support to output int, void* and std::string. --- include/ostream | 12 +++++++++--- include/string | 5 +++++ src/ostream.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/string.cpp | 5 +++++ tests/test_iostream.cpp | 12 ++++++++++++ 5 files changed, 68 insertions(+), 3 deletions(-) diff --git a/include/ostream b/include/ostream index 35ff8dc..f7f2734 100644 --- a/include/ostream +++ b/include/ostream @@ -62,6 +62,7 @@ class ostream: public basic_ios // Synchronize the stream buffer. ostream& flush(); + // Formatted output. /** * Interface for manipulators (e.g std::endl, std::hex in * expression like "std::cout << std::endl"). See iomanip header. @@ -73,11 +74,16 @@ class ostream: public basic_ios } ostream& operator<<(const char_type *str); + ostream& operator<<(int val); + ostream& operator<<(unsigned int val); + ostream& operator<<(const void *p); - /** - * Tries to insert a char. - */ + // This is non standard, used by string. + ostream& write_formatted(const char_type *str, streamsize num); + + // Unformatted output. ostream& put(char_type c); + ostream& write(const char_type *str, streamsize num); }; /** diff --git a/include/string b/include/string index 7c2f474..0f6de29 100644 --- a/include/string +++ b/include/string @@ -36,6 +36,8 @@ namespace std { +class ostream; + // Simple string implementation. Its purpose is to be able to compile code that // uses the STL and requires std::string. // @@ -278,6 +280,9 @@ class string size_type mLength; // len of the string excl. null-terminator. }; +// I/O +ostream& operator<<(ostream& os, const string& str); + } // namespace std #endif // ANDROID_ASTL_STRING__ diff --git a/src/ostream.cpp b/src/ostream.cpp index fff02ef..50d71d4 100644 --- a/src/ostream.cpp +++ b/src/ostream.cpp @@ -44,6 +44,36 @@ ostream& ostream::operator<<(const char_type *str) { return *this; } +// 64 bits int in octal is 22 digits. There is one for the sign and 2 +// for the format specifier + 1 for the terminating \0. A total of 26 +// chars should be enough to hold any integer representation. +static const size_t kNumSize = 26; +ostream& ostream::operator<<(int val) { + const char *fmt = "%d"; + char buf[kNumSize]; + int size = snprintf(buf, kNumSize, fmt, val); + return write(buf, size); +} + +ostream& ostream::operator<<(unsigned int val) { + const char *fmt = "%u"; + char buf[kNumSize]; + int size = snprintf(buf, kNumSize, fmt, val); + return write(buf, size); +} + +ostream& ostream::operator<<(const void *p) { + const char *fmt = "%p"; + char buf[kNumSize]; + int size = snprintf(buf, kNumSize, fmt, p); + return write(buf, size); +} + +ostream& ostream::write_formatted(const char_type *str, streamsize num) { + // TODO: Should format the string according to the flags. + return write(str, num); +} + ostream& ostream::put(char_type c) { if (this->rdbuf()) { this->rdbuf()->sputn(&c, 1); @@ -51,6 +81,13 @@ ostream& ostream::put(char_type c) { return *this; } +ostream& ostream::write(const char_type *str, streamsize num) { + if (this->rdbuf()) { + this->rdbuf()->sputn(str, num); + } + return *this; +} + ostream& ostream::flush() { if (this->rdbuf()) { // TODO: if pubsync returns -1 should mark this stream as diff --git a/src/string.cpp b/src/string.cpp index d0361e6..05f2634 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #ifndef MAX_SIZE_T #define MAX_SIZE_T (~(size_t)0) @@ -552,4 +553,8 @@ string::size_type string::find(const value_type *str, size_type pos) const return static_cast(delta); } +ostream& operator<<(ostream& os, const string& str) { + return os.write_formatted(str.data(), str.size()); +} + } // namespace std diff --git a/tests/test_iostream.cpp b/tests/test_iostream.cpp index a3437a2..53fbb60 100644 --- a/tests/test_iostream.cpp +++ b/tests/test_iostream.cpp @@ -32,6 +32,7 @@ #error "Wrong header included!!" #endif #include "common.h" +#include namespace android { @@ -77,6 +78,16 @@ bool testManip() { return true; } +bool testOutputFormat() { + using std::endl; + using std::cout; + cout << endl << "Int: " << 10 << endl; + cout << "Negative int: " << -10 << endl; + cout << "Unsigned int: " << 0xffffffff << endl; + cout << "Void *: " << static_cast(&std::cout) << endl; + cout << "string: " << std::string("hello world") << endl; + return true; +} } // namespace android int main(int argc, char **argv){ @@ -84,5 +95,6 @@ int main(int argc, char **argv){ FAIL_UNLESS(testOstream); FAIL_UNLESS(testCoutCerr); FAIL_UNLESS(testManip); + FAIL_UNLESS(testOutputFormat); return kPassed; } -- cgit v1.2.3