29struct DanglingStreamChecker
31 DanglingStreamChecker() =
default;
33 ~DanglingStreamChecker()
41 jassert (activeStreams.size() == 0);
45 hasBeenDestroyed =
true;
48 Array<void*, CriticalSection> activeStreams;
50 static bool hasBeenDestroyed;
53bool DanglingStreamChecker::hasBeenDestroyed =
false;
54static DanglingStreamChecker danglingStreamChecker;
59OutputStream::OutputStream()
60 : newLineString (
NewLine::getDefault())
63 if (! DanglingStreamChecker::hasBeenDestroyed)
64 danglingStreamChecker.activeStreams.add (
this);
71 if (! DanglingStreamChecker::hasBeenDestroyed)
72 danglingStreamChecker.activeStreams.removeFirstMatchingValue (
this);
85 return write (&
byte, 1);
90 for (
size_t i = 0; i < numTimesToRepeat; ++i)
100 return write (&v, 2);
106 return write (&v, 2);
112 return write (&v, 4);
118 return write (&v, 4);
123 auto un = (value < 0) ? (
unsigned int) -value
124 : (
unsigned int) value;
131 data[++num] = (uint8) un;
135 data[0] = (uint8) num;
140 return write (data, (
size_t) num + 1);
146 return write (&v, 8);
152 return write (&v, 8);
157 union {
int asInt;
float asFloat; } n;
164 union {
int asInt;
float asFloat; } n;
171 union { int64 asInt;
double asDouble; } n;
178 union { int64 asInt;
double asDouble; } n;
187 #if (JUCE_STRING_UTF_TYPE == 8)
194 return write (temp, numBytes);
200 bool replaceLineFeedWithUnix = lf !=
nullptr && lf[0] ==
'\n' && lf[1] == 0;
201 bool replaceLineFeedWithWindows = lf !=
nullptr && lf[0] ==
'\r' && lf[1] ==
'\n' && lf[2] == 0;
204 jassert (lf ==
nullptr || replaceLineFeedWithWindows || replaceLineFeedWithUnix);
208 if (writeUTF16ByteOrderMark)
209 write (
"\x0ff\x0fe", 2);
212 bool lastCharWasReturn =
false;
216 auto c = src.getAndAdvance();
221 if (replaceLineFeedWithWindows)
223 if (c ==
'\n' && ! lastCharWasReturn)
226 lastCharWasReturn = (c == L
'\r');
228 else if (replaceLineFeedWithUnix && c ==
'\r')
241 if (replaceLineFeedWithWindows)
248 if (!
write (src, (
size_t) (t - src)))
251 if (!
write (
"\r\n", 2))
264 if (!
write (src, (
size_t) (t - src)))
273 else if (replaceLineFeedWithUnix)
298 if (numBytesToWrite < 0)
299 numBytesToWrite = std::numeric_limits<int64>::max();
301 int64 numWritten = 0;
303 while (numBytesToWrite > 0)
306 auto num = source.
read (buffer, (
int) jmin (numBytesToWrite, (int64)
sizeof (buffer)));
311 write (buffer, (
size_t) num);
313 numBytesToWrite -= num;
323 newLineString = newLineStringToUse;
327template <
typename IntegerType>
328static void writeIntToStream (
OutputStream& stream, IntegerType number)
330 char buffer[NumberToStringConverters::charsNeededForInt];
331 char* end = buffer + numElementsInArray (buffer);
332 const char* start = NumberToStringConverters::numberToString (end, number);
333 stream.
write (start, (
size_t) (end - start - 1));
336JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const int number)
338 writeIntToStream (stream, number);
342JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const int64 number)
344 writeIntToStream (stream, number);
348JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const double number)
350 return stream << String (number);
353JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const char character)
355 stream.writeByte (character);
359JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const char*
const text)
361 stream.write (text, strlen (text));
365JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const MemoryBlock& data)
367 if (! data.isEmpty())
368 stream.write (data.getData(), data.getSize());
373JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const File& fileToRead)
375 FileInputStream in (fileToRead);
383JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, InputStream& streamToRead)
385 stream.writeFromInputStream (streamToRead, -1);
389JUCE_API OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream,
const NewLine&)
391 return stream << stream.getNewLineString();
static Type swapIfLittleEndian(Type value) noexcept
static Type swapIfBigEndian(Type value) noexcept
virtual bool writeDoubleBigEndian(double value)
virtual bool writeDouble(double value)
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
virtual bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat)
void setNewLineString(const String &newLineString)
virtual bool writeInt64BigEndian(int64 value)
virtual bool writeFloat(float value)
virtual int64 writeFromInputStream(InputStream &source, int64 maxNumBytesToWrite)
virtual bool writeText(const String &text, bool asUTF16, bool writeUTF16ByteOrderMark, const char *lineEndings)
virtual bool writeCompressedInt(int value)
virtual bool writeByte(char byte)
virtual bool writeShort(short value)
virtual bool writeBool(bool boolValue)
virtual bool writeInt64(int64 value)
virtual bool writeIntBigEndian(int value)
virtual bool writeShortBigEndian(short value)
virtual bool writeFloatBigEndian(float value)
virtual bool writeInt(int value)
virtual bool writeString(const String &text)
CharPointerType getCharPointer() const noexcept
const char * toRawUTF8() const
size_t getNumBytesAsUTF8() const noexcept
size_t copyToUTF8(CharPointer_UTF8::CharType *destBuffer, size_t maxBufferSizeBytes) const noexcept