Cleanup
[carla.git] / source / modules / water / streams / OutputStream.cpp
blobd3e1466666f1172674cdf2bbc60294f68fa824dc
1 /*
2 ==============================================================================
4 This file is part of the Water library.
5 Copyright (c) 2016 ROLI Ltd.
6 Copyright (C) 2017-2022 Filipe Coelho <falktx@falktx.com>
8 Permission is granted to use this software under the terms of the ISC license
9 http://www.isc.org/downloads/software-support-policy/isc-license/
11 Permission to use, copy, modify, and/or distribute this software for any
12 purpose with or without fee is hereby granted, provided that the above
13 copyright notice and this permission notice appear in all copies.
15 THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
16 TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
18 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
19 USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21 OF THIS SOFTWARE.
23 ==============================================================================
26 #include "OutputStream.h"
27 #include "../files/FileInputStream.h"
28 #include "../memory/ByteOrder.h"
29 #include "../memory/MemoryBlock.h"
30 #include "../text/NewLine.h"
32 namespace water {
34 //==============================================================================
35 OutputStream::OutputStream()
36 : newLineString (NewLine::getDefault())
40 OutputStream::~OutputStream()
44 //==============================================================================
45 bool OutputStream::writeBool (const bool b)
47 return writeByte (b ? (char) 1
48 : (char) 0);
51 bool OutputStream::writeByte (char byte)
53 return write (&byte, 1);
56 bool OutputStream::writeRepeatedByte (uint8 byte, size_t numTimesToRepeat)
58 for (size_t i = 0; i < numTimesToRepeat; ++i)
59 if (! writeByte ((char) byte))
60 return false;
62 return true;
65 bool OutputStream::writeShort (short value)
67 const unsigned short v = ByteOrder::swapIfBigEndian ((unsigned short) value);
68 return write (&v, 2);
71 bool OutputStream::writeShortBigEndian (short value)
73 const unsigned short v = ByteOrder::swapIfLittleEndian ((unsigned short) value);
74 return write (&v, 2);
77 bool OutputStream::writeInt (int value)
79 const unsigned int v = ByteOrder::swapIfBigEndian ((unsigned int) value);
80 return write (&v, 4);
83 bool OutputStream::writeIntBigEndian (int value)
85 const unsigned int v = ByteOrder::swapIfLittleEndian ((unsigned int) value);
86 return write (&v, 4);
89 bool OutputStream::writeCompressedInt (int value)
91 unsigned int un = (value < 0) ? (unsigned int) -value
92 : (unsigned int) value;
94 uint8 data[5];
95 int num = 0;
97 while (un > 0)
99 data[++num] = (uint8) un;
100 un >>= 8;
103 data[0] = (uint8) num;
105 if (value < 0)
106 data[0] |= 0x80;
108 return write (data, (size_t) num + 1);
111 bool OutputStream::writeInt64 (int64 value)
113 const uint64 v = ByteOrder::swapIfBigEndian ((uint64) value);
114 return write (&v, 8);
117 bool OutputStream::writeInt64BigEndian (int64 value)
119 const uint64 v = ByteOrder::swapIfLittleEndian ((uint64) value);
120 return write (&v, 8);
123 bool OutputStream::writeFloat (float value)
125 union { int asInt; float asFloat; } n;
126 n.asFloat = value;
127 return writeInt (n.asInt);
130 bool OutputStream::writeFloatBigEndian (float value)
132 union { int asInt; float asFloat; } n;
133 n.asFloat = value;
134 return writeIntBigEndian (n.asInt);
137 bool OutputStream::writeDouble (double value)
139 union { int64 asInt; double asDouble; } n;
140 n.asDouble = value;
141 return writeInt64 (n.asInt);
144 bool OutputStream::writeDoubleBigEndian (double value)
146 union { int64 asInt; double asDouble; } n;
147 n.asDouble = value;
148 return writeInt64BigEndian (n.asInt);
151 bool OutputStream::writeString (const String& text)
153 return write (text.toRawUTF8(), text.getNumBytesAsUTF8() + 1);
156 bool OutputStream::writeText (const String& text, const bool asUTF16,
157 const bool writeUTF16ByteOrderMark)
159 if (asUTF16)
161 if (writeUTF16ByteOrderMark)
162 write ("\x0ff\x0fe", 2);
164 CharPointer_UTF8 src (text.getCharPointer());
165 bool lastCharWasReturn = false;
167 for (;;)
169 const water_uchar c = src.getAndAdvance();
171 if (c == 0)
172 break;
174 if (c == '\n' && ! lastCharWasReturn)
175 writeShort ((short) '\r');
177 lastCharWasReturn = (c == L'\r');
179 if (! writeShort ((short) c))
180 return false;
183 else
185 const char* src = text.toUTF8();
186 const char* t = src;
188 for (;;)
190 if (*t == '\n')
192 if (t > src)
193 if (! write (src, (size_t) (t - src)))
194 return false;
196 if (! write ("\r\n", 2))
197 return false;
199 src = t + 1;
201 else if (*t == '\r')
203 if (t[1] == '\n')
204 ++t;
206 else if (*t == 0)
208 if (t > src)
209 if (! write (src, (size_t) (t - src)))
210 return false;
212 break;
215 ++t;
219 return true;
222 int64 OutputStream::writeFromInputStream (InputStream& source, int64 numBytesToWrite)
224 if (numBytesToWrite < 0)
225 numBytesToWrite = std::numeric_limits<int64>::max();
227 int64 numWritten = 0;
229 while (numBytesToWrite > 0)
231 char buffer [8192];
232 const int num = source.read (buffer, (int) jmin (numBytesToWrite, (int64) sizeof (buffer)));
234 if (num <= 0)
235 break;
237 write (buffer, (size_t) num);
239 numBytesToWrite -= num;
240 numWritten += num;
243 return numWritten;
246 //==============================================================================
247 void OutputStream::setNewLineString (const String& newLineString_)
249 newLineString = newLineString_;
252 //==============================================================================
253 template <typename IntegerType>
254 static void writeIntToStream (OutputStream& stream, IntegerType number)
256 char buffer [NumberToStringConverters::charsNeededForInt];
257 char* end = buffer + numElementsInArray (buffer);
258 const char* start = NumberToStringConverters::numberToString (end, number);
259 stream.write (start, (size_t) (end - start - 1));
262 OutputStream& operator<< (OutputStream& stream, const int number)
264 writeIntToStream (stream, number);
265 return stream;
268 OutputStream& operator<< (OutputStream& stream, const int64 number)
270 writeIntToStream (stream, number);
271 return stream;
274 OutputStream& operator<< (OutputStream& stream, const double number)
276 return stream << String (number);
279 OutputStream& operator<< (OutputStream& stream, const char character)
281 stream.writeByte (character);
282 return stream;
285 OutputStream& operator<< (OutputStream& stream, const char* const text)
287 stream.write (text, strlen (text));
288 return stream;
291 OutputStream& operator<< (OutputStream& stream, const MemoryBlock& data)
293 if (data.getSize() > 0)
294 stream.write (data.getData(), data.getSize());
296 return stream;
299 OutputStream& operator<< (OutputStream& stream, const File& fileToRead)
301 FileInputStream in (fileToRead);
303 if (in.openedOk())
304 return stream << in;
306 return stream;
309 OutputStream& operator<< (OutputStream& stream, InputStream& streamToRead)
311 stream.writeFromInputStream (streamToRead, -1);
312 return stream;
315 OutputStream& operator<< (OutputStream& stream, const NewLine&)
317 return stream << stream.getNewLineString();