OpenShot Library | OpenShotAudio 0.2.2
juce_MemoryOutputStream.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
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.
15
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.
19
20 ==============================================================================
21*/
22
23namespace juce
24{
25
27 : blockToUse (&internalBlock)
28{
29 internalBlock.setSize (initialSize, false);
30}
31
33 const bool appendToExistingBlockContent)
34 : blockToUse (&memoryBlockToWriteTo)
35{
36 if (appendToExistingBlockContent)
37 position = size = memoryBlockToWriteTo.getSize();
38}
39
40MemoryOutputStream::MemoryOutputStream (void* destBuffer, size_t destBufferSize)
41 : externalData (destBuffer), availableSize (destBufferSize)
42{
43 jassert (externalData != nullptr); // This must be a valid pointer.
44}
45
47{
48 trimExternalBlockSize();
49}
50
52{
53 trimExternalBlockSize();
54}
55
56void MemoryOutputStream::trimExternalBlockSize()
57{
58 if (blockToUse != &internalBlock && blockToUse != nullptr)
59 blockToUse->setSize (size, false);
60}
61
62void MemoryOutputStream::preallocate (const size_t bytesToPreallocate)
63{
64 if (blockToUse != nullptr)
65 blockToUse->ensureSize (bytesToPreallocate + 1);
66}
67
69{
70 position = 0;
71 size = 0;
72}
73
74char* MemoryOutputStream::prepareToWrite (size_t numBytes)
75{
76 jassert ((ssize_t) numBytes >= 0);
77 auto storageNeeded = position + numBytes;
78
79 char* data;
80
81 if (blockToUse != nullptr)
82 {
83 if (storageNeeded >= blockToUse->getSize())
84 blockToUse->ensureSize ((storageNeeded + jmin (storageNeeded / 2, (size_t) (1024 * 1024)) + 32) & ~31u);
85
86 data = static_cast<char*> (blockToUse->getData());
87 }
88 else
89 {
90 if (storageNeeded > availableSize)
91 return nullptr;
92
93 data = static_cast<char*> (externalData);
94 }
95
96 auto* writePointer = data + position;
97 position += numBytes;
98 size = jmax (size, position);
99 return writePointer;
100}
101
102bool MemoryOutputStream::write (const void* const buffer, size_t howMany)
103{
104 if (howMany == 0)
105 return true;
106
107 jassert (buffer != nullptr);
108
109 if (auto* dest = prepareToWrite (howMany))
110 {
111 memcpy (dest, buffer, howMany);
112 return true;
113 }
114
115 return false;
116}
117
118bool MemoryOutputStream::writeRepeatedByte (uint8 byte, size_t howMany)
119{
120 if (howMany == 0)
121 return true;
122
123 if (auto* dest = prepareToWrite (howMany))
124 {
125 memset (dest, byte, howMany);
126 return true;
127 }
128
129 return false;
130}
131
133{
134 if (auto* dest = prepareToWrite (CharPointer_UTF8::getBytesRequiredFor (c)))
135 {
136 CharPointer_UTF8 (dest).write (c);
137 return true;
138 }
139
140 return false;
141}
142
144{
145 return MemoryBlock (getData(), getDataSize());
146}
147
148const void* MemoryOutputStream::getData() const noexcept
149{
150 if (blockToUse == nullptr)
151 return externalData;
152
153 if (blockToUse->getSize() > size)
154 static_cast<char*> (blockToUse->getData()) [size] = 0;
155
156 return blockToUse->getData();
157}
158
159bool MemoryOutputStream::setPosition (int64 newPosition)
160{
161 if (newPosition <= (int64) size)
162 {
163 // ok to seek backwards
164 position = jlimit ((size_t) 0, size, (size_t) newPosition);
165 return true;
166 }
167
168 // can't move beyond the end of the stream..
169 return false;
170}
171
172int64 MemoryOutputStream::writeFromInputStream (InputStream& source, int64 maxNumBytesToWrite)
173{
174 // before writing from an input, see if we can preallocate to make it more efficient..
175 int64 availableData = source.getTotalLength() - source.getPosition();
176
177 if (availableData > 0)
178 {
179 if (maxNumBytesToWrite > availableData || maxNumBytesToWrite < 0)
180 maxNumBytesToWrite = availableData;
181
182 if (blockToUse != nullptr)
183 preallocate (blockToUse->getSize() + (size_t) maxNumBytesToWrite);
184 }
185
186 return OutputStream::writeFromInputStream (source, maxNumBytesToWrite);
187}
188
190{
191 auto* d = static_cast<const char*> (getData());
193}
194
196{
198}
199
200OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const MemoryOutputStream& streamToRead)
201{
202 auto dataSize = streamToRead.getDataSize();
203
204 if (dataSize > 0)
205 stream.write (streamToRead.getData(), dataSize);
206
207 return stream;
208}
209
210} // namespace juce
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
static size_t getBytesRequiredFor(const juce_wchar charToWrite) noexcept
Returns the number of bytes that would be needed to represent the given unicode character in this enc...
void write(const juce_wchar charToWrite) noexcept
Writes a unicode character to this string, and advances this pointer to point to the next position.
The base class for streams that read data.
virtual int64 getPosition()=0
Returns the offset of the next byte that will be read from the stream.
virtual int64 getTotalLength()=0
Returns the total number of bytes available for reading in this stream.
A class to hold a resizable block of raw data.
void ensureSize(const size_t minimumSize, bool initialiseNewSpaceToZero=false)
Increases the block's size only if it's smaller than a given size.
void * getData() noexcept
Returns a void pointer to the data.
void setSize(const size_t newSize, bool initialiseNewSpaceToZero=false)
Resizes the memory block.
size_t getSize() const noexcept
Returns the block's current allocated size, in bytes.
Writes data to an internal memory buffer, which grows as required.
const void * getData() const noexcept
Returns a pointer to the data that has been written to the stream.
~MemoryOutputStream() override
Destructor.
bool setPosition(int64) override
Tries to move the stream's output position.
String toUTF8() const
Returns a String created from the (UTF8) data that has been written to the stream.
String toString() const
Attempts to detect the encoding of the data and convert it to a string.
void flush() override
If the stream is writing to a user-supplied MemoryBlock, this will trim any excess capacity off the b...
size_t getDataSize() const noexcept
Returns the number of bytes of data that have been written to the stream.
bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat) override
Writes a byte to the output stream a given number of times.
void preallocate(size_t bytesToPreallocate)
Increases the internal storage capacity to be able to contain at least the specified amount of data w...
int64 writeFromInputStream(InputStream &, int64 maxNumBytesToWrite) override
Reads data from an input stream and writes it to this stream.
MemoryOutputStream(size_t initialSize=256)
Creates an empty memory stream, ready to be written into.
void reset() noexcept
Resets the stream, clearing any data that has been written to it so far.
bool write(const void *, size_t) override
Writes a block of data to the stream.
bool appendUTF8Char(juce_wchar character)
Appends the utf-8 bytes for a unicode character.
MemoryBlock getMemoryBlock() const
Returns a copy of the stream's data as a memory block.
The base class for streams that write data to some kind of destination.
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
Writes a block of data to the stream.
virtual int64 writeFromInputStream(InputStream &source, int64 maxNumBytesToWrite)
Reads data from an input stream and writes it to this stream.
The JUCE String class!
Definition: juce_String.h:43
static String createStringFromData(const void *data, int size)
Creates a string from data in an unknown format.