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
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"
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
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
))
65 bool OutputStream::writeShort (short value
)
67 const unsigned short v
= ByteOrder::swapIfBigEndian ((unsigned short) value
);
71 bool OutputStream::writeShortBigEndian (short value
)
73 const unsigned short v
= ByteOrder::swapIfLittleEndian ((unsigned short) value
);
77 bool OutputStream::writeInt (int value
)
79 const unsigned int v
= ByteOrder::swapIfBigEndian ((unsigned int) value
);
83 bool OutputStream::writeIntBigEndian (int value
)
85 const unsigned int v
= ByteOrder::swapIfLittleEndian ((unsigned int) value
);
89 bool OutputStream::writeCompressedInt (int value
)
91 unsigned int un
= (value
< 0) ? (unsigned int) -value
92 : (unsigned int) value
;
99 data
[++num
] = (uint8
) un
;
103 data
[0] = (uint8
) num
;
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
;
127 return writeInt (n
.asInt
);
130 bool OutputStream::writeFloatBigEndian (float value
)
132 union { int asInt
; float asFloat
; } n
;
134 return writeIntBigEndian (n
.asInt
);
137 bool OutputStream::writeDouble (double value
)
139 union { int64 asInt
; double asDouble
; } n
;
141 return writeInt64 (n
.asInt
);
144 bool OutputStream::writeDoubleBigEndian (double value
)
146 union { int64 asInt
; double asDouble
; } n
;
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
)
161 if (writeUTF16ByteOrderMark
)
162 write ("\x0ff\x0fe", 2);
164 CharPointer_UTF8
src (text
.getCharPointer());
165 bool lastCharWasReturn
= false;
169 const water_uchar c
= src
.getAndAdvance();
174 if (c
== '\n' && ! lastCharWasReturn
)
175 writeShort ((short) '\r');
177 lastCharWasReturn
= (c
== L
'\r');
179 if (! writeShort ((short) c
))
185 const char* src
= text
.toUTF8();
193 if (! write (src
, (size_t) (t
- src
)))
196 if (! write ("\r\n", 2))
209 if (! write (src
, (size_t) (t
- src
)))
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)
232 const int num
= source
.read (buffer
, (int) jmin (numBytesToWrite
, (int64
) sizeof (buffer
)));
237 write (buffer
, (size_t) num
);
239 numBytesToWrite
-= num
;
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
);
268 OutputStream
& operator<< (OutputStream
& stream
, const int64 number
)
270 writeIntToStream (stream
, number
);
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
);
285 OutputStream
& operator<< (OutputStream
& stream
, const char* const text
)
287 stream
.write (text
, strlen (text
));
291 OutputStream
& operator<< (OutputStream
& stream
, const MemoryBlock
& data
)
293 if (data
.getSize() > 0)
294 stream
.write (data
.getData(), data
.getSize());
299 OutputStream
& operator<< (OutputStream
& stream
, const File
& fileToRead
)
301 FileInputStream
in (fileToRead
);
309 OutputStream
& operator<< (OutputStream
& stream
, InputStream
& streamToRead
)
311 stream
.writeFromInputStream (streamToRead
, -1);
315 OutputStream
& operator<< (OutputStream
& stream
, const NewLine
&)
317 return stream
<< stream
.getNewLineString();