OpenShot Library | libopenshot-audio  0.1.9
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 
23 namespace juce
24 {
25 
26 MemoryOutputStream::MemoryOutputStream (const size_t initialSize)
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 
40 MemoryOutputStream::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 
56 void MemoryOutputStream::trimExternalBlockSize()
57 {
58  if (blockToUse != &internalBlock && blockToUse != nullptr)
59  blockToUse->setSize (size, false);
60 }
61 
62 void 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 
74 char* 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 
102 bool 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 
118 bool 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 
148 const 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 
159 bool 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 
172 int64 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());
192  return String (CharPointer_UTF8 (d), CharPointer_UTF8 (d + getDataSize()));
193 }
194 
196 {
198 }
199 
200 OutputStream& 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
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...
size_t getSize() const noexcept
Returns the block&#39;s current allocated size, in bytes.
void preallocate(size_t bytesToPreallocate)
Increases the internal storage capacity to be able to contain at least the specified amount of data w...
virtual int64 getTotalLength()=0
Returns the total number of bytes available for reading in this stream.
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
Writes a block of data to the stream.
void ensureSize(const size_t minimumSize, bool initialiseNewSpaceToZero=false)
Increases the block&#39;s size only if it&#39;s smaller than a given size.
The base class for streams that read data.
int64 writeFromInputStream(InputStream &, int64 maxNumBytesToWrite) override
Reads data from an input stream and writes it to this stream.
MemoryBlock getMemoryBlock() const
Returns a copy of the stream&#39;s data as a memory block.
bool setPosition(int64) override
Tries to move the stream&#39;s output position.
The JUCE String class!
Definition: juce_String.h:42
static String createStringFromData(const void *data, int size)
Creates a string from data in an unknown format.
void flush() override
If the stream is writing to a user-supplied MemoryBlock, this will trim any excess capacity off the b...
virtual int64 getPosition()=0
Returns the offset of the next byte that will be read from the stream.
void * getData() const noexcept
Returns a void pointer to the data.
const void * getData() const noexcept
Returns a pointer to the data that has 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.
bool write(const void *, size_t) override
Writes a block of data to the stream.
~MemoryOutputStream() override
Destructor.
The base class for streams that write data to some kind of destination.
size_t getDataSize() const noexcept
Returns the number of bytes of data that have been written to the stream.
void reset() noexcept
Resets the stream, clearing any data that has been written to it so far.
MemoryOutputStream(size_t initialSize=256)
Creates an empty memory stream, ready to be written into.
virtual int64 writeFromInputStream(InputStream &source, int64 maxNumBytesToWrite)
Reads data from an input stream and writes it to this stream.
bool appendUTF8Char(juce_wchar character)
Appends the utf-8 bytes for a unicode character.
String toUTF8() const
Returns a String created from the (UTF8) data that has been written to the stream.
Writes data to an internal memory buffer, which grows as required.
A class to hold a resizable block of raw data.
String toString() const
Attempts to detect the encoding of the data and convert it to a string.
void setSize(const size_t newSize, bool initialiseNewSpaceToZero=false)
Resizes the memory block.
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
void write(const juce_wchar charToWrite) noexcept
Writes a unicode character to this string, and advances this pointer to point to the next position...