VST3: fetch midi mappings all at once, use it for note/sound-off
[carla.git] / source / modules / juce_core / streams / juce_MemoryOutputStream.cpp
blobe43b8465cef3dce88022792d129bfe66db3425b9
1 /*
2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
10 The code included in this file is provided under the terms of the ISC license
11 http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12 To use, copy, modify, and/or distribute this software for any purpose with or
13 without fee is hereby granted provided that the above copyright notice and
14 this permission notice appear in all copies.
16 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18 DISCLAIMED.
20 ==============================================================================
23 namespace juce
26 MemoryOutputStream::MemoryOutputStream (const size_t initialSize)
27 : blockToUse (&internalBlock)
29 internalBlock.setSize (initialSize, false);
32 MemoryOutputStream::MemoryOutputStream (MemoryBlock& memoryBlockToWriteTo,
33 const bool appendToExistingBlockContent)
34 : blockToUse (&memoryBlockToWriteTo)
36 if (appendToExistingBlockContent)
37 position = size = memoryBlockToWriteTo.getSize();
40 MemoryOutputStream::MemoryOutputStream (void* destBuffer, size_t destBufferSize)
41 : externalData (destBuffer), availableSize (destBufferSize)
43 jassert (externalData != nullptr); // This must be a valid pointer.
46 MemoryOutputStream::~MemoryOutputStream()
48 trimExternalBlockSize();
51 void MemoryOutputStream::flush()
53 trimExternalBlockSize();
56 void MemoryOutputStream::trimExternalBlockSize()
58 if (blockToUse != &internalBlock && blockToUse != nullptr)
59 blockToUse->setSize (size, false);
62 void MemoryOutputStream::preallocate (const size_t bytesToPreallocate)
64 if (blockToUse != nullptr)
65 blockToUse->ensureSize (bytesToPreallocate + 1);
68 void MemoryOutputStream::reset() noexcept
70 position = 0;
71 size = 0;
74 char* MemoryOutputStream::prepareToWrite (size_t numBytes)
76 jassert ((ssize_t) numBytes >= 0);
77 auto storageNeeded = position + numBytes;
79 char* data;
81 if (blockToUse != nullptr)
83 if (storageNeeded >= blockToUse->getSize())
84 blockToUse->ensureSize ((storageNeeded + jmin (storageNeeded / 2, (size_t) (1024 * 1024)) + 32) & ~31u);
86 data = static_cast<char*> (blockToUse->getData());
88 else
90 if (storageNeeded > availableSize)
91 return nullptr;
93 data = static_cast<char*> (externalData);
96 auto* writePointer = data + position;
97 position += numBytes;
98 size = jmax (size, position);
99 return writePointer;
102 bool MemoryOutputStream::write (const void* const buffer, size_t howMany)
104 if (howMany == 0)
105 return true;
107 jassert (buffer != nullptr);
109 if (auto* dest = prepareToWrite (howMany))
111 memcpy (dest, buffer, howMany);
112 return true;
115 return false;
118 bool MemoryOutputStream::writeRepeatedByte (uint8 byte, size_t howMany)
120 if (howMany == 0)
121 return true;
123 if (auto* dest = prepareToWrite (howMany))
125 memset (dest, byte, howMany);
126 return true;
129 return false;
132 bool MemoryOutputStream::appendUTF8Char (juce_wchar c)
134 if (auto* dest = prepareToWrite (CharPointer_UTF8::getBytesRequiredFor (c)))
136 CharPointer_UTF8 (dest).write (c);
137 return true;
140 return false;
143 MemoryBlock MemoryOutputStream::getMemoryBlock() const
145 return MemoryBlock (getData(), getDataSize());
148 const void* MemoryOutputStream::getData() const noexcept
150 if (blockToUse == nullptr)
151 return externalData;
153 if (blockToUse->getSize() > size)
154 static_cast<char*> (blockToUse->getData()) [size] = 0;
156 return blockToUse->getData();
159 bool MemoryOutputStream::setPosition (int64 newPosition)
161 if (newPosition <= (int64) size)
163 // ok to seek backwards
164 position = jlimit ((size_t) 0, size, (size_t) newPosition);
165 return true;
168 // can't move beyond the end of the stream..
169 return false;
172 int64 MemoryOutputStream::writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite)
174 // before writing from an input, see if we can preallocate to make it more efficient..
175 int64 availableData = source.getTotalLength() - source.getPosition();
177 if (availableData > 0)
179 if (maxNumBytesToWrite > availableData || maxNumBytesToWrite < 0)
180 maxNumBytesToWrite = availableData;
182 if (blockToUse != nullptr)
183 preallocate (blockToUse->getSize() + (size_t) maxNumBytesToWrite);
186 return OutputStream::writeFromInputStream (source, maxNumBytesToWrite);
189 String MemoryOutputStream::toUTF8() const
191 auto* d = static_cast<const char*> (getData());
192 return String (CharPointer_UTF8 (d), CharPointer_UTF8 (d + getDataSize()));
195 String MemoryOutputStream::toString() const
197 return String::createStringFromData (getData(), (int) getDataSize());
200 OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead)
202 auto dataSize = streamToRead.getDataSize();
204 if (dataSize > 0)
205 stream.write (streamToRead.getData(), dataSize);
207 return stream;
210 } // namespace juce