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
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
20 ==============================================================================
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
74 char* MemoryOutputStream::prepareToWrite (size_t numBytes
)
76 jassert ((ssize_t
) numBytes
>= 0);
77 auto storageNeeded
= position
+ numBytes
;
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());
90 if (storageNeeded
> availableSize
)
93 data
= static_cast<char*> (externalData
);
96 auto* writePointer
= data
+ position
;
98 size
= jmax (size
, position
);
102 bool MemoryOutputStream::write (const void* const buffer
, size_t howMany
)
107 jassert (buffer
!= nullptr);
109 if (auto* dest
= prepareToWrite (howMany
))
111 memcpy (dest
, buffer
, howMany
);
118 bool MemoryOutputStream::writeRepeatedByte (uint8 byte
, size_t howMany
)
123 if (auto* dest
= prepareToWrite (howMany
))
125 memset (dest
, byte
, howMany
);
132 bool MemoryOutputStream::appendUTF8Char (juce_wchar c
)
134 if (auto* dest
= prepareToWrite (CharPointer_UTF8::getBytesRequiredFor (c
)))
136 CharPointer_UTF8 (dest
).write (c
);
143 MemoryBlock
MemoryOutputStream::getMemoryBlock() const
145 return MemoryBlock (getData(), getDataSize());
148 const void* MemoryOutputStream::getData() const noexcept
150 if (blockToUse
== nullptr)
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
);
168 // can't move beyond the end of the stream..
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();
205 stream
.write (streamToRead
.getData(), dataSize
);