From 9f201da3c58b4df7b2b8aa6adbb5989bea6d59fd Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Mon, 22 Feb 2010 11:37:43 +0000 Subject: [PATCH] Tidied up a few OutputStream operators. --- juce_amalgamated.cpp | 104 ++++++++++----------------- juce_amalgamated.h | 43 ++++++----- src/io/streams/juce_OutputStream.cpp | 94 ++++++++---------------- src/io/streams/juce_OutputStream.h | 87 ++++++++-------------- src/text/juce_String.cpp | 12 ++++ src/text/juce_String.h | 25 ++++--- 6 files changed, 145 insertions(+), 220 deletions(-) diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 007f87c6a1..0366ec5b24 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -5407,7 +5407,7 @@ void juce_CheckForDanglingStreams() }; #endif -OutputStream::OutputStream() throw() +OutputStream::OutputStream() { #if JUCE_DEBUG const ScopedLock sl (activeStreamLock); @@ -5522,75 +5522,15 @@ void OutputStream::writeDoubleBigEndian (double value) void OutputStream::writeString (const String& text) { + // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind + // if lots of large, persistent strings were to be written to streams). const int numBytes = text.getNumBytesAsUTF8() + 1; HeapBlock temp (numBytes); text.copyToUTF8 (temp, numBytes); write (temp, numBytes); } -void OutputStream::printf (const char* pf, ...) -{ - unsigned int bufSize = 256; - HeapBlock buf (bufSize); - - for (;;) - { - va_list list; - va_start (list, pf); - - const int num = CharacterFunctions::vprintf (buf, bufSize, pf, list); - - va_end (list); - - if (num > 0) - { - write (buf, num); - break; - } - else if (num == 0) - { - break; - } - - bufSize += 256; - buf.malloc (bufSize); - } -} - -OutputStream& OutputStream::operator<< (const int number) -{ - const String s (number); - write (s.toUTF8(), s.getNumBytesAsUTF8()); - return *this; -} - -OutputStream& OutputStream::operator<< (const double number) -{ - const String s (number); - write (s.toUTF8(), s.getNumBytesAsUTF8()); - return *this; -} - -OutputStream& OutputStream::operator<< (const char character) -{ - writeByte (character); - return *this; -} - -OutputStream& OutputStream::operator<< (const char* const text) -{ - write (text, (int) strlen (text)); - return *this; -} - -OutputStream& OutputStream::operator<< (const String& text) -{ - write (text.toUTF8(), text.getNumBytesAsUTF8()); - return *this; -} - -void OutputStream::writeText (const String& text, - const bool asUnicode, +void OutputStream::writeText (const String& text, const bool asUnicode, const bool writeUnicodeHeaderBytes) { if (asUnicode) @@ -5643,8 +5583,7 @@ void OutputStream::writeText (const String& text, } } -int OutputStream::writeFromInputStream (InputStream& source, - int numBytesToWrite) +int OutputStream::writeFromInputStream (InputStream& source, int numBytesToWrite) { if (numBytesToWrite < 0) numBytesToWrite = 0x7fffffff; @@ -5669,6 +5608,28 @@ int OutputStream::writeFromInputStream (InputStream& source, return numWritten; } +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const int number) +{ + return stream << String (number); +} + +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number) +{ + return stream << String (number); +} + +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char character) +{ + stream.writeByte (character); + return stream; +} + +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char* const text) +{ + stream.write (text, (int) strlen (text)); + return stream; +} + END_JUCE_NAMESPACE /*** End of inlined file: juce_OutputStream.cpp ***/ @@ -11141,6 +11102,17 @@ String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const double number) return string1 += String (number); } +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text) +{ + // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind + // if lots of large, persistent strings were to be written to streams). + const int numBytes = text.getNumBytesAsUTF8(); + HeapBlock temp (numBytes); + text.copyToUTF8 (temp, numBytes); + stream.write (temp, numBytes); + return stream; +} + int String::indexOfChar (const tchar character) const throw() { const tchar* t = text->text; diff --git a/juce_amalgamated.h b/juce_amalgamated.h index add2598d70..4a3e7abd3f 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -1062,6 +1062,8 @@ public: #endif // __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__ /*** End of inlined file: juce_CharacterFunctions.h ***/ +class OutputStream; + class JUCE_API String { public: @@ -1408,12 +1410,6 @@ String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const unsigned long nu String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const float number); String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const double number); -template -std::basic_ostream & operator<< (std::basic_ostream & stream, const String& stringToWrite) -{ - return stream << stringToWrite.toUTF8(); -} - bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const String& string2) throw(); bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const char* string2) throw(); bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const juce_wchar* string2) throw(); @@ -1425,6 +1421,14 @@ bool JUCE_PUBLIC_FUNCTION operator< (const String& string1, const String& stri bool JUCE_PUBLIC_FUNCTION operator>= (const String& string1, const String& string2) throw(); bool JUCE_PUBLIC_FUNCTION operator<= (const String& string1, const String& string2) throw(); +template +std::basic_ostream & operator<< (std::basic_ostream & stream, const String& stringToWrite) +{ + return stream << stringToWrite.toUTF8(); +} + +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text); + #endif // __JUCE_STRING_JUCEHEADER__ /*** End of inlined file: juce_String.h ***/ @@ -2793,6 +2797,10 @@ protected: class JUCE_API OutputStream { +protected: + + OutputStream(); + public: virtual ~OutputStream(); @@ -2837,27 +2845,18 @@ public: const bool asUnicode, const bool writeUnicodeHeaderBytes); - virtual void printf (const char* format, ...); - - virtual int writeFromInputStream (InputStream& source, - int maxNumBytesToWrite); - - virtual OutputStream& operator<< (const int number); - - virtual OutputStream& operator<< (const double number); + virtual int writeFromInputStream (InputStream& source, int maxNumBytesToWrite); - virtual OutputStream& operator<< (const char character); - - virtual OutputStream& operator<< (const char* const text); + juce_UseDebuggingNewOperator +}; - virtual OutputStream& operator<< (const String& text); +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const int number); - juce_UseDebuggingNewOperator +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number); -protected: +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char character); - OutputStream() throw(); -}; +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char* const text); #endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__ /*** End of inlined file: juce_OutputStream.h ***/ diff --git a/src/io/streams/juce_OutputStream.cpp b/src/io/streams/juce_OutputStream.cpp index 7067dee3ec..1aeda725ae 100644 --- a/src/io/streams/juce_OutputStream.cpp +++ b/src/io/streams/juce_OutputStream.cpp @@ -51,7 +51,7 @@ void juce_CheckForDanglingStreams() #endif //============================================================================== -OutputStream::OutputStream() throw() +OutputStream::OutputStream() { #if JUCE_DEBUG const ScopedLock sl (activeStreamLock); @@ -167,75 +167,15 @@ void OutputStream::writeDoubleBigEndian (double value) void OutputStream::writeString (const String& text) { + // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind + // if lots of large, persistent strings were to be written to streams). const int numBytes = text.getNumBytesAsUTF8() + 1; HeapBlock temp (numBytes); text.copyToUTF8 (temp, numBytes); write (temp, numBytes); } -void OutputStream::printf (const char* pf, ...) -{ - unsigned int bufSize = 256; - HeapBlock buf (bufSize); - - for (;;) - { - va_list list; - va_start (list, pf); - - const int num = CharacterFunctions::vprintf (buf, bufSize, pf, list); - - va_end (list); - - if (num > 0) - { - write (buf, num); - break; - } - else if (num == 0) - { - break; - } - - bufSize += 256; - buf.malloc (bufSize); - } -} - -OutputStream& OutputStream::operator<< (const int number) -{ - const String s (number); - write (s.toUTF8(), s.getNumBytesAsUTF8()); - return *this; -} - -OutputStream& OutputStream::operator<< (const double number) -{ - const String s (number); - write (s.toUTF8(), s.getNumBytesAsUTF8()); - return *this; -} - -OutputStream& OutputStream::operator<< (const char character) -{ - writeByte (character); - return *this; -} - -OutputStream& OutputStream::operator<< (const char* const text) -{ - write (text, (int) strlen (text)); - return *this; -} - -OutputStream& OutputStream::operator<< (const String& text) -{ - write (text.toUTF8(), text.getNumBytesAsUTF8()); - return *this; -} - -void OutputStream::writeText (const String& text, - const bool asUnicode, +void OutputStream::writeText (const String& text, const bool asUnicode, const bool writeUnicodeHeaderBytes) { if (asUnicode) @@ -288,8 +228,7 @@ void OutputStream::writeText (const String& text, } } -int OutputStream::writeFromInputStream (InputStream& source, - int numBytesToWrite) +int OutputStream::writeFromInputStream (InputStream& source, int numBytesToWrite) { if (numBytesToWrite < 0) numBytesToWrite = 0x7fffffff; @@ -314,5 +253,28 @@ int OutputStream::writeFromInputStream (InputStream& source, return numWritten; } +//============================================================================== +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const int number) +{ + return stream << String (number); +} + +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number) +{ + return stream << String (number); +} + +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char character) +{ + stream.writeByte (character); + return stream; +} + +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char* const text) +{ + stream.write (text, (int) strlen (text)); + return stream; +} + END_JUCE_NAMESPACE diff --git a/src/io/streams/juce_OutputStream.h b/src/io/streams/juce_OutputStream.h index 42baeb81f5..87f2978748 100644 --- a/src/io/streams/juce_OutputStream.h +++ b/src/io/streams/juce_OutputStream.h @@ -41,6 +41,10 @@ */ class JUCE_API OutputStream { +protected: + //============================================================================== + OutputStream(); + public: /** Destructor. @@ -88,87 +92,69 @@ public: */ virtual void writeByte (char byte); - /** Writes a boolean to the stream. - - This is encoded as a byte - either 1 or 0. - + /** Writes a boolean to the stream as a single byte. + This is encoded as a binary byte (not as text) with a value of 1 or 0. @see InputStream::readBool */ virtual void writeBool (bool boolValue); /** Writes a 16-bit integer to the stream in a little-endian byte order. - This will write two bytes to the stream: (value & 0xff), then (value >> 8). - @see InputStream::readShort */ virtual void writeShort (short value); /** Writes a 16-bit integer to the stream in a big-endian byte order. - This will write two bytes to the stream: (value >> 8), then (value & 0xff). - @see InputStream::readShortBigEndian */ virtual void writeShortBigEndian (short value); /** Writes a 32-bit integer to the stream in a little-endian byte order. - @see InputStream::readInt */ virtual void writeInt (int value); /** Writes a 32-bit integer to the stream in a big-endian byte order. - @see InputStream::readIntBigEndian */ virtual void writeIntBigEndian (int value); /** Writes a 64-bit integer to the stream in a little-endian byte order. - @see InputStream::readInt64 */ virtual void writeInt64 (int64 value); /** Writes a 64-bit integer to the stream in a big-endian byte order. - @see InputStream::readInt64BigEndian */ virtual void writeInt64BigEndian (int64 value); - /** Writes a 32-bit floating point value to the stream. - + /** Writes a 32-bit floating point value to the stream in a binary format. The binary 32-bit encoding of the float is written as a little-endian int. - @see InputStream::readFloat */ virtual void writeFloat (float value); - /** Writes a 32-bit floating point value to the stream. - + /** Writes a 32-bit floating point value to the stream in a binary format. The binary 32-bit encoding of the float is written as a big-endian int. - @see InputStream::readFloatBigEndian */ virtual void writeFloatBigEndian (float value); - /** Writes a 64-bit floating point value to the stream. - + /** Writes a 64-bit floating point value to the stream in a binary format. The eight raw bytes of the double value are written out as a little-endian 64-bit int. - @see InputStream::readDouble */ virtual void writeDouble (double value); - /** Writes a 64-bit floating point value to the stream. - + /** Writes a 64-bit floating point value to the stream in a binary format. The eight raw bytes of the double value are written out as a big-endian 64-bit int. - @see InputStream::readDoubleBigEndian */ virtual void writeDoubleBigEndian (double value); - /** Writes a condensed encoding of a 32-bit integer. + /** Writes a condensed binary encoding of a 32-bit integer. If you're storing a lot of integers which are unlikely to have very large values, this can save a lot of space, because values under 0xff will only take up 2 bytes, @@ -180,23 +166,23 @@ public: */ virtual void writeCompressedInt (int value); - /** Stores a string in the stream. + /** Stores a string in the stream in a binary format. This isn't the method to use if you're trying to append text to the end of a - text-file! It's intended for storing a string for later retrieval - by InputStream::readString. + text-file! It's intended for storing a string so that it can be retrieved later + by InputStream::readString(). - It writes the string to the stream as UTF8, with a null character terminating it. + It writes the string to the stream as UTF8, including the null termination character. - For appending text to a file, instead use writeText, printf, or operator<< + For appending text to a file, instead use writeText, or operator<< - @see InputStream::readString, writeText, printf, operator<< + @see InputStream::readString, writeText, operator<< */ virtual void writeString (const String& text); /** Writes a string of text to the stream. - It can either write it as 8-bit system-encoded characters, or as unicode, and + It can either write it as UTF8 characters or as unicode, and can also add unicode header bytes (0xff, 0xfe) to indicate the endianness (this should only be done at the start of a file). @@ -206,12 +192,6 @@ public: const bool asUnicode, const bool writeUnicodeHeaderBytes); - /** Writes a string of text to the stream. - - @see writeText - */ - virtual void printf (const char* format, ...); - /** Reads data from an input stream and writes it to this stream. @param source the stream to read from @@ -219,32 +199,25 @@ public: less than zero, it will keep reading until the input is exhausted) */ - virtual int writeFromInputStream (InputStream& source, - int maxNumBytesToWrite); + virtual int writeFromInputStream (InputStream& source, int maxNumBytesToWrite); //============================================================================== - /** Writes a number to the stream as 8-bit characters in the default system encoding. */ - virtual OutputStream& operator<< (const int number); - - /** Writes a number to the stream as 8-bit characters in the default system encoding. */ - virtual OutputStream& operator<< (const double number); + juce_UseDebuggingNewOperator +}; - /** Writes a character to the stream. */ - virtual OutputStream& operator<< (const char character); +//============================================================================== +/** Writes a number to a stream as 8-bit characters in the default system encoding. */ +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const int number); - /** Writes a null-terminated string to the stream. */ - virtual OutputStream& operator<< (const char* const text); +/** Writes a number to a stream as 8-bit characters in the default system encoding. */ +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const double number); - /** Writes a null-terminated text string to the stream, converting it to UTF8. */ - virtual OutputStream& operator<< (const String& text); +/** Writes a character to a stream. */ +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char character); - //============================================================================== - juce_UseDebuggingNewOperator +/** Writes a null-terminated text string to a stream. */ +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const char* const text); -protected: - //============================================================================== - OutputStream() throw(); -}; #endif // __JUCE_OUTPUTSTREAM_JUCEHEADER__ diff --git a/src/text/juce_String.cpp b/src/text/juce_String.cpp index d4099b5367..dc88348760 100644 --- a/src/text/juce_String.cpp +++ b/src/text/juce_String.cpp @@ -39,6 +39,7 @@ BEGIN_JUCE_NAMESPACE #include "juce_String.h" #include "../core/juce_Atomic.h" +#include "../io/streams/juce_OutputStream.h" #ifdef _MSC_VER #pragma warning (pop) @@ -771,6 +772,17 @@ String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const double number) return string1 += String (number); } +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text) +{ + // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind + // if lots of large, persistent strings were to be written to streams). + const int numBytes = text.getNumBytesAsUTF8(); + HeapBlock temp (numBytes); + text.copyToUTF8 (temp, numBytes); + stream.write (temp, numBytes); + return stream; +} + //============================================================================== int String::indexOfChar (const tchar character) const throw() { diff --git a/src/text/juce_String.h b/src/text/juce_String.h index 58a1cdc627..2ae490d3f1 100644 --- a/src/text/juce_String.h +++ b/src/text/juce_String.h @@ -27,6 +27,7 @@ #define __JUCE_STRING_JUCEHEADER__ #include "juce_CharacterFunctions.h" +class OutputStream; //============================================================================== @@ -1090,6 +1091,7 @@ const String JUCE_PUBLIC_FUNCTION operator+ (String string1, char characterTo /** Concatenates two strings. */ const String JUCE_PUBLIC_FUNCTION operator+ (String string1, juce_wchar characterToAppend); +//============================================================================== /** Appends a character at the end of a string. */ String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const char characterToAppend); /** Appends a character at the end of a string. */ @@ -1116,15 +1118,7 @@ String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const float num /** Appends a decimal number at the end of a string. */ String& JUCE_PUBLIC_FUNCTION operator<< (String& string1, const double number); -/** This streaming override allows you to pass a juce String directly into std output streams. - This is very handy for writing strings to std::cout, std::cerr, etc. -*/ -template -std::basic_ostream & operator<< (std::basic_ostream & stream, const String& stringToWrite) -{ - return stream << stringToWrite.toUTF8(); -} - +//============================================================================== /** Case-sensitive comparison of two strings. */ bool JUCE_PUBLIC_FUNCTION operator== (const String& string1, const String& string2) throw(); /** Case-sensitive comparison of two strings. */ @@ -1146,5 +1140,18 @@ bool JUCE_PUBLIC_FUNCTION operator>= (const String& string1, const String& stri /** Case-sensitive comparison of two strings. */ bool JUCE_PUBLIC_FUNCTION operator<= (const String& string1, const String& string2) throw(); +//============================================================================== +/** This streaming override allows you to pass a juce String directly into std output streams. + This is very handy for writing strings to std::cout, std::cerr, etc. +*/ +template +std::basic_ostream & operator<< (std::basic_ostream & stream, const String& stringToWrite) +{ + return stream << stringToWrite.toUTF8(); +} + +/** Writes a string to an OutputStream as UTF8. */ +OutputStream& JUCE_PUBLIC_FUNCTION operator<< (OutputStream& stream, const String& text); + #endif // __JUCE_STRING_JUCEHEADER__