LMMS
Loading...
Searching...
No Matches
juce_OutputStream.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
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
26#if JUCE_DEBUG
27
28//==============================================================================
29struct DanglingStreamChecker
30{
31 DanglingStreamChecker() = default;
32
33 ~DanglingStreamChecker()
34 {
35 /*
36 It's always a bad idea to leak any object, but if you're leaking output
37 streams, then there's a good chance that you're failing to flush a file
38 to disk properly, which could result in corrupted data and other similar
39 nastiness..
40 */
41 jassert (activeStreams.size() == 0);
42
43 // We need to flag when this helper struct has been destroyed to prevent some
44 // nasty order-of-static-destruction issues
45 hasBeenDestroyed = true;
46 }
47
48 Array<void*, CriticalSection> activeStreams;
49
50 static bool hasBeenDestroyed;
51};
52
53bool DanglingStreamChecker::hasBeenDestroyed = false;
54static DanglingStreamChecker danglingStreamChecker;
55
56#endif
57
58//==============================================================================
60 : newLineString (NewLine::getDefault())
61{
62 #if JUCE_DEBUG
63 if (! DanglingStreamChecker::hasBeenDestroyed)
64 danglingStreamChecker.activeStreams.add (this);
65 #endif
66}
67
69{
70 #if JUCE_DEBUG
71 if (! DanglingStreamChecker::hasBeenDestroyed)
72 danglingStreamChecker.activeStreams.removeFirstMatchingValue (this);
73 #endif
74}
75
76//==============================================================================
78{
79 return writeByte (b ? (char) 1
80 : (char) 0);
81}
82
84{
85 return write (&byte, 1);
86}
87
88bool OutputStream::writeRepeatedByte (uint8 byte, size_t numTimesToRepeat)
89{
90 for (size_t i = 0; i < numTimesToRepeat; ++i)
91 if (! writeByte ((char) byte))
92 return false;
93
94 return true;
95}
96
98{
100 return write (&v, 2);
101}
102
104{
106 return write (&v, 2);
107}
108
110{
112 return write (&v, 4);
113}
114
116{
118 return write (&v, 4);
119}
120
122{
123 auto un = (value < 0) ? (unsigned int) -value
124 : (unsigned int) value;
125
126 uint8 data[5];
127 int num = 0;
128
129 while (un > 0)
130 {
131 data[++num] = (uint8) un;
132 un >>= 8;
133 }
134
135 data[0] = (uint8) num;
136
137 if (value < 0)
138 data[0] |= 0x80;
139
140 return write (data, (size_t) num + 1);
141}
142
144{
146 return write (&v, 8);
147}
148
154
156{
157 union { int asInt; float asFloat; } n;
158 n.asFloat = value;
159 return writeInt (n.asInt);
160}
161
163{
164 union { int asInt; float asFloat; } n;
165 n.asFloat = value;
166 return writeIntBigEndian (n.asInt);
167}
168
170{
171 union { int64 asInt; double asDouble; } n;
172 n.asDouble = value;
173 return writeInt64 (n.asInt);
174}
175
177{
178 union { int64 asInt; double asDouble; } n;
179 n.asDouble = value;
180 return writeInt64BigEndian (n.asInt);
181}
182
184{
185 auto numBytes = text.getNumBytesAsUTF8() + 1;
186
187 #if (JUCE_STRING_UTF_TYPE == 8)
188 return write (text.toRawUTF8(), numBytes);
189 #else
190 // (This avoids using toUTF8() to prevent the memory bloat that it would leave behind
191 // if lots of large, persistent strings were to be written to streams).
192 HeapBlock<char> temp (numBytes);
193 text.copyToUTF8 (temp, numBytes);
194 return write (temp, numBytes);
195 #endif
196}
197
198bool OutputStream::writeText (const String& text, bool asUTF16, bool writeUTF16ByteOrderMark, const char* lf)
199{
200 bool replaceLineFeedWithUnix = lf != nullptr && lf[0] == '\n' && lf[1] == 0;
201 bool replaceLineFeedWithWindows = lf != nullptr && lf[0] == '\r' && lf[1] == '\n' && lf[2] == 0;
202
203 // The line-feed passed in must be either nullptr, or "\n" or "\r\n"
204 jassert (lf == nullptr || replaceLineFeedWithWindows || replaceLineFeedWithUnix);
205
206 if (asUTF16)
207 {
208 if (writeUTF16ByteOrderMark)
209 write ("\x0ff\x0fe", 2);
210
211 auto src = text.getCharPointer();
212 bool lastCharWasReturn = false;
213
214 for (;;)
215 {
216 auto c = src.getAndAdvance();
217
218 if (c == 0)
219 break;
220
221 if (replaceLineFeedWithWindows)
222 {
223 if (c == '\n' && ! lastCharWasReturn)
224 writeShort ((short) '\r');
225
226 lastCharWasReturn = (c == L'\r');
227 }
228 else if (replaceLineFeedWithUnix && c == '\r')
229 {
230 continue;
231 }
232
233 if (! writeShort ((short) c))
234 return false;
235 }
236 }
237 else
238 {
239 const char* src = text.toRawUTF8();
240
241 if (replaceLineFeedWithWindows)
242 {
243 for (auto t = src;;)
244 {
245 if (*t == '\n')
246 {
247 if (t > src)
248 if (! write (src, (size_t) (t - src)))
249 return false;
250
251 if (! write ("\r\n", 2))
252 return false;
253
254 src = t + 1;
255 }
256 else if (*t == '\r')
257 {
258 if (t[1] == '\n')
259 ++t;
260 }
261 else if (*t == 0)
262 {
263 if (t > src)
264 if (! write (src, (size_t) (t - src)))
265 return false;
266
267 break;
268 }
269
270 ++t;
271 }
272 }
273 else if (replaceLineFeedWithUnix)
274 {
275 for (;;)
276 {
277 auto c = *src++;
278
279 if (c == 0)
280 break;
281
282 if (c != '\r')
283 if (! writeByte (c))
284 return false;
285 }
286 }
287 else
288 {
289 return write (src, text.getNumBytesAsUTF8());
290 }
291 }
292
293 return true;
294}
295
297{
298 if (numBytesToWrite < 0)
299 numBytesToWrite = std::numeric_limits<int64>::max();
300
301 int64 numWritten = 0;
302
303 while (numBytesToWrite > 0)
304 {
305 char buffer[8192];
306 auto num = source.read (buffer, (int) jmin (numBytesToWrite, (int64) sizeof (buffer)));
307
308 if (num <= 0)
309 break;
310
311 write (buffer, (size_t) num);
312
313 numBytesToWrite -= num;
314 numWritten += num;
315 }
316
317 return numWritten;
318}
319
320//==============================================================================
321void OutputStream::setNewLineString (const String& newLineStringToUse)
322{
323 newLineString = newLineStringToUse;
324}
325
326//==============================================================================
327template <typename IntegerType>
328static void writeIntToStream (OutputStream& stream, IntegerType number)
329{
331 char* end = buffer + numElementsInArray (buffer);
332 const char* start = NumberToStringConverters::numberToString (end, number);
333 stream.write (start, (size_t) (end - start - 1));
334}
335
337{
338 writeIntToStream (stream, number);
339 return stream;
340}
341
343{
344 writeIntToStream (stream, number);
345 return stream;
346}
347
349{
350 return stream << String (number);
351}
352
354{
355 stream.writeByte (character);
356 return stream;
357}
358
360{
361 stream.write (text, strlen (text));
362 return stream;
363}
364
366{
367 if (! data.isEmpty())
368 stream.write (data.getData(), data.getSize());
369
370 return stream;
371}
372
374{
375 FileInputStream in (fileToRead);
376
377 if (in.openedOk())
378 return stream << in;
379
380 return stream;
381}
382
384{
385 stream.writeFromInputStream (streamToRead, -1);
386 return stream;
387}
388
390{
391 return stream << stream.getNewLineString();
392}
393
394} // namespace juce
ostream & operator<<(ostream &out, const MidiEvent &ev)
Definition InMgr.cpp:9
static uint16 swapIfLittleEndian(uint16 value) noexcept
Definition ByteOrder.h:227
static uint16 swapIfBigEndian(uint16 value) noexcept
Definition ByteOrder.h:218
Definition juce_File.h:45
Definition juce_FileInputStream.h:35
Definition juce_HeapBlock.h:87
Definition juce_InputStream.h:37
virtual int read(void *destBuffer, int maxBytesToRead)=0
Definition juce_MemoryBlock.h:33
Definition juce_NewLine.h:40
Definition juce_OutputStream.h:38
virtual bool writeDoubleBigEndian(double value)
Definition juce_OutputStream.cpp:176
virtual ~OutputStream()
Definition juce_OutputStream.cpp:68
virtual bool writeDouble(double value)
Definition juce_OutputStream.cpp:169
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
virtual bool writeRepeatedByte(uint8 byte, size_t numTimesToRepeat)
Definition juce_OutputStream.cpp:88
void setNewLineString(const String &newLineString)
Definition juce_OutputStream.cpp:321
OutputStream()
Definition juce_OutputStream.cpp:59
virtual bool writeInt64BigEndian(int64 value)
Definition juce_OutputStream.cpp:149
virtual bool writeFloat(float value)
Definition juce_OutputStream.cpp:155
virtual int64 writeFromInputStream(InputStream &source, int64 maxNumBytesToWrite)
Definition juce_OutputStream.cpp:296
String newLineString
Definition juce_OutputStream.h:235
virtual bool writeText(const String &text, bool asUTF16, bool writeUTF16ByteOrderMark, const char *lineEndings)
Definition juce_OutputStream.cpp:198
virtual bool writeCompressedInt(int value)
Definition juce_OutputStream.cpp:121
virtual bool writeByte(char byte)
Definition juce_OutputStream.cpp:83
virtual bool writeShort(short value)
Definition juce_OutputStream.cpp:97
virtual bool writeBool(bool boolValue)
Definition juce_OutputStream.cpp:77
virtual bool writeInt64(int64 value)
Definition juce_OutputStream.cpp:143
virtual bool writeIntBigEndian(int value)
Definition juce_OutputStream.cpp:115
virtual bool writeShortBigEndian(short value)
Definition juce_OutputStream.cpp:103
virtual bool writeFloatBigEndian(float value)
Definition juce_OutputStream.cpp:162
virtual bool writeInt(int value)
Definition juce_OutputStream.cpp:109
const String & getNewLineString() const noexcept
Definition juce_OutputStream.h:231
virtual bool writeString(const String &text)
Definition juce_OutputStream.cpp:183
Definition juce_String.h:53
struct huft * t
Definition inflate.c:943
unsigned v[N_MAX]
Definition inflate.c:1584
register unsigned i
Definition inflate.c:1575
static PuglViewHint int value
Definition pugl.h:1708
virtual ASIOError start()=0
JSAMPIMAGE data
Definition jpeglib.h:945
#define jassert(expression)
#define JUCE_CALLTYPE
#define JUCE_API
Definition juce_StandardHeader.h:152
float in
Definition lilv_test.c:1460
static char * numberToString(char *t, int64 n) noexcept
Definition juce_String.cpp:393
@ charsNeededForInt
Definition juce_String.cpp:373
Definition carla_juce.cpp:31
unsigned short uint16
Definition juce_MathsFunctions.h:41
unsigned long long uint64
Definition juce_MathsFunctions.h:56
constexpr Type jmin(Type a, Type b)
Definition juce_MathsFunctions.h:106
unsigned int uint32
Definition juce_MathsFunctions.h:45
RangedDirectoryIterator end(const RangedDirectoryIterator &)
Definition juce_RangedDirectoryIterator.h:184
long long int64
Definition juce_MathsFunctions.h:54
static void writeIntToStream(OutputStream &stream, IntegerType number)
Definition juce_OutputStream.cpp:328
unsigned char uint8
Definition juce_MathsFunctions.h:37
constexpr int numElementsInArray(Type(&)[N]) noexcept
Definition juce_MathsFunctions.h:344
const char * text
Definition swell-functions.h:167
int n
Definition crypt.c:458
return c
Definition crypt.c:175
b
Definition crypt.c:628
typedef int(UZ_EXP MsgFn)()