mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Add Beast fork from JUCE commit 265fb0e8ebc26e1469d6edcc68d2ca9acefeb508
This commit is contained in:
320
modules/beast_core/streams/beast_OutputStream.cpp
Normal file
320
modules/beast_core/streams/beast_OutputStream.cpp
Normal file
@@ -0,0 +1,320 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Portions of this file are from JUCE.
|
||||
Copyright (c) 2013 - Raw Material Software Ltd.
|
||||
Please visit http://www.juce.com
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#if BEAST_DEBUG
|
||||
|
||||
struct DanglingStreamChecker
|
||||
{
|
||||
DanglingStreamChecker() {}
|
||||
|
||||
~DanglingStreamChecker()
|
||||
{
|
||||
/*
|
||||
It's always a bad idea to leak any object, but if you're leaking output
|
||||
streams, then there's a good chance that you're failing to flush a file
|
||||
to disk properly, which could result in corrupted data and other similar
|
||||
nastiness..
|
||||
*/
|
||||
bassert (activeStreams.size() == 0);
|
||||
}
|
||||
|
||||
Array<void*, CriticalSection> activeStreams;
|
||||
};
|
||||
|
||||
static DanglingStreamChecker danglingStreamChecker;
|
||||
#endif
|
||||
|
||||
//==============================================================================
|
||||
OutputStream::OutputStream()
|
||||
: newLineString (NewLine::getDefault())
|
||||
{
|
||||
#if BEAST_DEBUG
|
||||
danglingStreamChecker.activeStreams.add (this);
|
||||
#endif
|
||||
}
|
||||
|
||||
OutputStream::~OutputStream()
|
||||
{
|
||||
#if BEAST_DEBUG
|
||||
danglingStreamChecker.activeStreams.removeFirstMatchingValue (this);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void OutputStream::writeBool (const bool b)
|
||||
{
|
||||
writeByte (b ? (char) 1
|
||||
: (char) 0);
|
||||
}
|
||||
|
||||
void OutputStream::writeByte (char byte)
|
||||
{
|
||||
write (&byte, 1);
|
||||
}
|
||||
|
||||
void OutputStream::writeRepeatedByte (uint8 byte, size_t numTimesToRepeat)
|
||||
{
|
||||
for (size_t i = 0; i < numTimesToRepeat; ++i)
|
||||
writeByte ((char) byte);
|
||||
}
|
||||
|
||||
void OutputStream::writeShort (short value)
|
||||
{
|
||||
const unsigned short v = ByteOrder::swapIfBigEndian ((unsigned short) value);
|
||||
write (&v, 2);
|
||||
}
|
||||
|
||||
void OutputStream::writeShortBigEndian (short value)
|
||||
{
|
||||
const unsigned short v = ByteOrder::swapIfLittleEndian ((unsigned short) value);
|
||||
write (&v, 2);
|
||||
}
|
||||
|
||||
void OutputStream::writeInt (int value)
|
||||
{
|
||||
const unsigned int v = ByteOrder::swapIfBigEndian ((unsigned int) value);
|
||||
write (&v, 4);
|
||||
}
|
||||
|
||||
void OutputStream::writeIntBigEndian (int value)
|
||||
{
|
||||
const unsigned int v = ByteOrder::swapIfLittleEndian ((unsigned int) value);
|
||||
write (&v, 4);
|
||||
}
|
||||
|
||||
void OutputStream::writeCompressedInt (int value)
|
||||
{
|
||||
unsigned int un = (value < 0) ? (unsigned int) -value
|
||||
: (unsigned int) value;
|
||||
|
||||
uint8 data[5];
|
||||
int num = 0;
|
||||
|
||||
while (un > 0)
|
||||
{
|
||||
data[++num] = (uint8) un;
|
||||
un >>= 8;
|
||||
}
|
||||
|
||||
data[0] = (uint8) num;
|
||||
|
||||
if (value < 0)
|
||||
data[0] |= 0x80;
|
||||
|
||||
write (data, num + 1);
|
||||
}
|
||||
|
||||
void OutputStream::writeInt64 (int64 value)
|
||||
{
|
||||
const uint64 v = ByteOrder::swapIfBigEndian ((uint64) value);
|
||||
write (&v, 8);
|
||||
}
|
||||
|
||||
void OutputStream::writeInt64BigEndian (int64 value)
|
||||
{
|
||||
const uint64 v = ByteOrder::swapIfLittleEndian ((uint64) value);
|
||||
write (&v, 8);
|
||||
}
|
||||
|
||||
void OutputStream::writeFloat (float value)
|
||||
{
|
||||
union { int asInt; float asFloat; } n;
|
||||
n.asFloat = value;
|
||||
writeInt (n.asInt);
|
||||
}
|
||||
|
||||
void OutputStream::writeFloatBigEndian (float value)
|
||||
{
|
||||
union { int asInt; float asFloat; } n;
|
||||
n.asFloat = value;
|
||||
writeIntBigEndian (n.asInt);
|
||||
}
|
||||
|
||||
void OutputStream::writeDouble (double value)
|
||||
{
|
||||
union { int64 asInt; double asDouble; } n;
|
||||
n.asDouble = value;
|
||||
writeInt64 (n.asInt);
|
||||
}
|
||||
|
||||
void OutputStream::writeDoubleBigEndian (double value)
|
||||
{
|
||||
union { int64 asInt; double asDouble; } n;
|
||||
n.asDouble = value;
|
||||
writeInt64BigEndian (n.asInt);
|
||||
}
|
||||
|
||||
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 size_t numBytes = text.getNumBytesAsUTF8() + 1;
|
||||
HeapBlock<char> temp (numBytes);
|
||||
text.copyToUTF8 (temp, numBytes);
|
||||
write (temp, numBytes);
|
||||
}
|
||||
|
||||
void OutputStream::writeText (const String& text, const bool asUTF16,
|
||||
const bool writeUTF16ByteOrderMark)
|
||||
{
|
||||
if (asUTF16)
|
||||
{
|
||||
if (writeUTF16ByteOrderMark)
|
||||
write ("\x0ff\x0fe", 2);
|
||||
|
||||
String::CharPointerType src (text.getCharPointer());
|
||||
bool lastCharWasReturn = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const beast_wchar c = src.getAndAdvance();
|
||||
|
||||
if (c == 0)
|
||||
break;
|
||||
|
||||
if (c == '\n' && ! lastCharWasReturn)
|
||||
writeShort ((short) '\r');
|
||||
|
||||
lastCharWasReturn = (c == L'\r');
|
||||
writeShort ((short) c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* src = text.toUTF8();
|
||||
const char* t = src;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*t == '\n')
|
||||
{
|
||||
if (t > src)
|
||||
write (src, (int) (t - src));
|
||||
|
||||
write ("\r\n", 2);
|
||||
src = t + 1;
|
||||
}
|
||||
else if (*t == '\r')
|
||||
{
|
||||
if (t[1] == '\n')
|
||||
++t;
|
||||
}
|
||||
else if (*t == 0)
|
||||
{
|
||||
if (t > src)
|
||||
write (src, (int) (t - src));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
++t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int OutputStream::writeFromInputStream (InputStream& source, int64 numBytesToWrite)
|
||||
{
|
||||
if (numBytesToWrite < 0)
|
||||
numBytesToWrite = std::numeric_limits<int64>::max();
|
||||
|
||||
int numWritten = 0;
|
||||
|
||||
while (numBytesToWrite > 0)
|
||||
{
|
||||
char buffer [8192];
|
||||
const int num = source.read (buffer, (int) bmin (numBytesToWrite, (int64) sizeof (buffer)));
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
write (buffer, num);
|
||||
|
||||
numBytesToWrite -= num;
|
||||
numWritten += num;
|
||||
}
|
||||
|
||||
return numWritten;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
void OutputStream::setNewLineString (const String& newLineString_)
|
||||
{
|
||||
newLineString = newLineString_;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const int number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const int64 number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const double number)
|
||||
{
|
||||
return stream << String (number);
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const char character)
|
||||
{
|
||||
stream.writeByte (character);
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const char* const text)
|
||||
{
|
||||
stream.write (text, strlen (text));
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const MemoryBlock& data)
|
||||
{
|
||||
if (data.getSize() > 0)
|
||||
stream.write (data.getData(), data.getSize());
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const File& fileToRead)
|
||||
{
|
||||
FileInputStream in (fileToRead);
|
||||
|
||||
if (in.openedOk())
|
||||
return stream << in;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, InputStream& streamToRead)
|
||||
{
|
||||
stream.writeFromInputStream (streamToRead, -1);
|
||||
return stream;
|
||||
}
|
||||
|
||||
BEAST_API OutputStream& BEAST_CALLTYPE operator<< (OutputStream& stream, const NewLine&)
|
||||
{
|
||||
return stream << stream.getNewLineString();
|
||||
}
|
||||
Reference in New Issue
Block a user