Files
hot-step-cpp-ROCm/engine/vendor/vst3sdk/vstgui4/vstgui/uidescription/cstream.cpp
T
2026-08-16 18:24:52 +07:00

627 lines
15 KiB
C++

// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "cstream.h"
#include "../lib/cresourcedescription.h"
#include "../lib/malloc.h"
#include "../lib/platform/iplatformresourceinputstream.h"
#include "../lib/platform/platformfactory.h"
#include <algorithm>
#include <sstream>
#if WINDOWS
#define fseeko _fseeki64
#define ftello _ftelli64
#endif
namespace VSTGUI {
//-----------------------------------------------------------------------------
CMemoryStream::CMemoryStream (uint32_t initialSize, uint32_t inDelta, bool binaryMode, ByteOrder byteOrder)
: OutputStream (byteOrder)
, InputStream (byteOrder)
, buffer (nullptr)
, bufferSize (0)
, size (0)
, pos (0)
, delta (inDelta)
, binaryMode (binaryMode)
, ownsBuffer (true)
{
resize (initialSize);
}
//-----------------------------------------------------------------------------
CMemoryStream::CMemoryStream (const int8_t* inBuffer, uint32_t bufferSize, bool binaryMode, ByteOrder byteOrder)
: OutputStream (byteOrder)
, InputStream (byteOrder)
, buffer (const_cast<int8_t*> (inBuffer))
, bufferSize (bufferSize)
, size (bufferSize)
, pos (0)
, delta (0)
, binaryMode (binaryMode)
, ownsBuffer (false)
{
}
//-----------------------------------------------------------------------------
CMemoryStream::~CMemoryStream () noexcept
{
if (ownsBuffer && buffer)
std::free (buffer);
}
//-----------------------------------------------------------------------------
bool CMemoryStream::resize (uint32_t inSize)
{
if (bufferSize >= inSize)
return true;
if (ownsBuffer == false)
return false;
uint32_t newSize = bufferSize + delta;
while (newSize < inSize)
newSize += delta;
int8_t* newBuffer = (int8_t*)std::malloc (newSize);
if (newBuffer && buffer)
memcpy (newBuffer, buffer, size);
if (buffer)
std::free (buffer);
buffer = newBuffer;
bufferSize = newSize;
return buffer != nullptr;
}
//-----------------------------------------------------------------------------
uint32_t CMemoryStream::writeRaw (const void* inBuffer, uint32_t inSize)
{
if (!resize (pos + inSize))
return kStreamIOError;
memcpy (buffer + pos, inBuffer, inSize);
pos += inSize;
size = pos;
return inSize;
}
//-----------------------------------------------------------------------------
uint32_t CMemoryStream::readRaw (void* outBuffer, uint32_t outSize)
{
if ((size - pos) <= 0)
return 0;
outSize = std::min<uint32_t> (outSize, size - pos);
memcpy (outBuffer, buffer + pos, outSize);
pos += outSize;
return outSize;
}
//-----------------------------------------------------------------------------
int64_t CMemoryStream::seek (int64_t seekpos, SeekMode mode)
{
int64_t newPos;
switch (mode)
{
case kSeekSet: newPos = seekpos; break;
case kSeekCurrent: newPos = pos + seekpos; break;
case kSeekEnd:
default:
newPos = size - seekpos;
break;
}
if (newPos <= size && newPos > 0)
{
pos = static_cast<uint32_t> (newPos);
return pos;
}
return kStreamSeekError;
}
//-----------------------------------------------------------------------------
bool CMemoryStream::operator>> (std::string& string)
{
if (binaryMode)
{
int32_t identifier;
if (!(*static_cast<InputStream*> (this) >> identifier)) return false;
if (identifier == 'str ')
{
uint32_t length;
if (!(*static_cast<InputStream*> (this) >> length)) return false;
Buffer<int8_t> buf (length);
uint32_t read = readRaw (buf.data (), length);
if (read == length)
string.assign ((const char*)buf.data (), length);
return read == length;
}
}
else
{
int8_t character;
while (readRaw (&character, sizeof (character)) == sizeof (character))
{
if (character == 0)
break;
string.push_back (character);
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool CMemoryStream::operator<< (const std::string& str)
{
if (binaryMode)
{
if (!((*this) << (uint32_t)'str ')) return false;
if (!((*this) << (uint32_t)str.length ())) return false;
}
return writeRaw (str.c_str (), static_cast<uint32_t> (str.length ())) == str.length ();
}
//-----------------------------------------------------------------------------
bool CMemoryStream::end ()
{
if (binaryMode == false)
{
const int8_t zero = 0;
return writeRaw (&zero, 1) == 1;
}
return true;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CFileStream::CFileStream ()
: stream (nullptr)
{
}
//-----------------------------------------------------------------------------
CFileStream::~CFileStream () noexcept
{
if (stream)
{
fclose (stream);
}
}
//-----------------------------------------------------------------------------
bool CFileStream::open (UTF8StringPtr path, int32_t mode, ByteOrder byteOrder)
{
if (stream)
return false;
InputStream::setByteOrder (byteOrder);
OutputStream::setByteOrder (byteOrder);
std::stringstream fmode;
if (mode & kTruncateMode)
{
if (mode & kReadMode && mode & kWriteMode)
fmode << "w+";
else if (mode & kReadMode)
fmode << "r";
else if (mode & kWriteMode)
fmode << "w";
}
else
{
if (mode & kReadMode && mode & kWriteMode)
fmode << "a+";
else if (mode & kWriteMode)
fmode << "a";
else if (mode & kReadMode)
fmode << "r";
else
return false;
}
#if WINDOWS
// always use binary mode so that newlines are not converted
fmode << "b";
#else
if (mode & kBinaryMode)
fmode << "b";
#endif
stream = fopen (path, fmode.str ().c_str ());
openMode = mode;
return stream != nullptr;
}
//------------------------------------------------------------------------
bool CFileStream::isEndOfFile () const
{
if (stream)
{
return feof (stream) != 0;
}
return true;
}
//-----------------------------------------------------------------------------
uint32_t CFileStream::writeRaw (const void* buffer, uint32_t size)
{
if (stream)
{
uint32_t written = static_cast<uint32_t> (fwrite (buffer, size, 1, stream));
return written * size;
}
return kStreamIOError;
}
//-----------------------------------------------------------------------------
uint32_t CFileStream::readRaw (void* buffer, uint32_t size)
{
if (stream)
{
return static_cast<uint32_t> (fread (buffer, 1, size, stream));
}
return kStreamIOError;
}
//-----------------------------------------------------------------------------
int64_t CFileStream::seek (int64_t pos, SeekMode mode)
{
if (stream)
{
int fseekmode;
switch (mode)
{
case kSeekSet: fseekmode = SEEK_SET; break;
case kSeekCurrent: fseekmode = SEEK_CUR; break;
case kSeekEnd:
default:
fseekmode = SEEK_END;
break;
}
if (fseeko (stream, pos, fseekmode) == 0)
return tell ();
}
return kStreamSeekError;
}
//-----------------------------------------------------------------------------
int64_t CFileStream::tell () const
{
if (stream)
{
return ftello (stream);
}
return kStreamSeekError;
}
//-----------------------------------------------------------------------------
void CFileStream::rewind ()
{
if (stream)
{
fseek (stream, 0, SEEK_SET);
}
}
//-----------------------------------------------------------------------------
bool CFileStream::operator>> (std::string& string)
{
int8_t character;
string.clear ();
while (readRaw (&character, sizeof (character)) == sizeof (character))
{
if (character == 0)
break;
string.push_back (character);
}
return true;
}
//-----------------------------------------------------------------------------
bool CFileStream::operator<< (const std::string& str)
{
if (writeRaw (str.c_str (), static_cast<uint32_t> (str.size ())) == str.size ())
{
if (openMode & kBinaryMode)
{
if (!((*this) << (int8_t)0))
return false;
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
CResourceInputStream::CResourceInputStream (ByteOrder byteOrder)
: InputStream (byteOrder)
{
}
//-----------------------------------------------------------------------------
CResourceInputStream::~CResourceInputStream () noexcept
{
}
//-----------------------------------------------------------------------------
bool CResourceInputStream::open (const CResourceDescription& res)
{
if (platformStream)
return false;
platformStream = getPlatformFactory ().createResourceInputStream (res);
return platformStream != nullptr;
}
//-----------------------------------------------------------------------------
uint32_t CResourceInputStream::readRaw (void* buffer, uint32_t size)
{
if (platformStream)
return platformStream->readRaw (buffer, size);
return kStreamIOError;
}
//-----------------------------------------------------------------------------
int64_t CResourceInputStream::seek (int64_t pos, SeekMode mode)
{
if (platformStream)
{
VSTGUI::SeekMode sm = VSTGUI::SeekMode::Set;
switch (mode)
{
case kSeekCurrent: sm = VSTGUI::SeekMode::Current; break;
case kSeekSet: sm = VSTGUI::SeekMode::Set; break;
case kSeekEnd: sm = VSTGUI::SeekMode::End; break;
}
return platformStream->seek (pos, sm);
}
return kStreamSeekError;
}
//-----------------------------------------------------------------------------
int64_t CResourceInputStream::tell () const
{
if (platformStream)
return platformStream->tell ();
return kStreamSeekError;
}
//-----------------------------------------------------------------------------
void CResourceInputStream::rewind ()
{
if (platformStream)
platformStream->seek (0, VSTGUI::SeekMode::Set);
}
//-----------------------------------------------------------------------------
template<typename T>
void endianSwap (T& value)
{
uint32_t size = sizeof (T);
auto low = reinterpret_cast<uint8_t*> (&value);
auto high = low + size - 1;
while (size >= 2)
{
auto tmp = *low;
*low = *high;
*high = tmp;
low += 2;
high -= 2;
size -= 2;
}
}
//-----------------------------------------------------------------------------
template<typename T>
bool writeEndianSwap (const T& value, OutputStream& s)
{
auto tmp = value;
endianSwap (tmp);
return s.writeRaw (&tmp, sizeof (T)) == sizeof (T);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const int8_t& input)
{
return writeRaw (&input, sizeof (int8_t)) == sizeof (int8_t);
}
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const uint8_t& input)
{
return writeRaw (&input, sizeof (uint8_t)) == sizeof (uint8_t);
}
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const int16_t& input)
{
if (byteOrder == kNativeByteOrder)
{
return writeRaw (&input, sizeof (int16_t)) == sizeof (int16_t);
}
return writeEndianSwap (input, *this);
}
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const uint16_t& input)
{
if (byteOrder == kNativeByteOrder)
{
return writeRaw (&input, sizeof (uint16_t)) == sizeof (uint16_t);
}
return writeEndianSwap (input, *this);
}
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const int32_t& input)
{
if (byteOrder == kNativeByteOrder)
{
return writeRaw (&input, sizeof (int32_t)) == sizeof (int32_t);
}
return writeEndianSwap (input, *this);
}
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const uint32_t& input)
{
if (byteOrder == kNativeByteOrder)
{
return writeRaw (&input, sizeof (uint32_t)) == sizeof (uint32_t);
}
return writeEndianSwap (input, *this);
}
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const int64_t& input)
{
if (byteOrder == kNativeByteOrder)
{
return writeRaw (&input, sizeof (int64_t)) == sizeof (int64_t);
}
return writeEndianSwap (input, *this);
}
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const uint64_t& input)
{
if (byteOrder == kNativeByteOrder)
{
return writeRaw (&input, sizeof (uint64_t)) == sizeof (uint64_t);
}
return writeEndianSwap (input, *this);
}
//-----------------------------------------------------------------------------
bool OutputStream::operator<< (const double& input)
{
if (byteOrder == kNativeByteOrder)
{
return writeRaw (&input, sizeof (double)) == sizeof (double);
}
return writeEndianSwap (input, *this);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
bool InputStream::operator>> (int8_t& output)
{
return readRaw (&output, sizeof (int8_t)) == sizeof (int8_t);
}
//-----------------------------------------------------------------------------
bool InputStream::operator>> (uint8_t& output)
{
return readRaw (&output, sizeof (uint8_t)) == sizeof (uint8_t);
}
//-----------------------------------------------------------------------------
bool InputStream::operator>> (int16_t& output)
{
if (readRaw (&output, sizeof (int16_t)) == sizeof (int16_t))
{
if (byteOrder != kNativeByteOrder)
{
endianSwap (output);
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool InputStream::operator>> (uint16_t& output)
{
if (readRaw (&output, sizeof (uint16_t)) == sizeof (uint16_t))
{
if (byteOrder != kNativeByteOrder)
{
endianSwap (output);
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool InputStream::operator>> (int32_t& output)
{
if (readRaw (&output, sizeof (int32_t)) == sizeof (int32_t))
{
if (byteOrder != kNativeByteOrder)
{
endianSwap (output);
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool InputStream::operator>> (uint32_t& output)
{
if (readRaw (&output, sizeof (uint32_t)) == sizeof (uint32_t))
{
if (byteOrder != kNativeByteOrder)
{
endianSwap (output);
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool InputStream::operator>> (int64_t& output)
{
if (readRaw (&output, sizeof (int64_t)) == sizeof (int64_t))
{
if (byteOrder != kNativeByteOrder)
{
endianSwap (output);
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool InputStream::operator>> (uint64_t& output)
{
if (readRaw (&output, sizeof (uint64_t)) == sizeof (uint64_t))
{
if (byteOrder != kNativeByteOrder)
{
endianSwap (output);
}
return true;
}
return false;
}
//-----------------------------------------------------------------------------
bool InputStream::operator>> (double& output)
{
if (readRaw (&output, sizeof (double)) == sizeof (double))
{
if (byteOrder != kNativeByteOrder)
{
endianSwap (output);
}
return true;
}
return false;
}
} // VSTGUI