1 | // |
2 | // BinaryWriter.cpp |
3 | // |
4 | // Library: Foundation |
5 | // Package: Streams |
6 | // Module: BinaryReaderWriter |
7 | // |
8 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
9 | // and Contributors. |
10 | // |
11 | // SPDX-License-Identifier: BSL-1.0 |
12 | // |
13 | |
14 | |
15 | #include "Poco/BinaryWriter.h" |
16 | #include "Poco/TextEncoding.h" |
17 | #include "Poco/TextConverter.h" |
18 | #include <cstring> |
19 | |
20 | |
21 | namespace Poco { |
22 | |
23 | |
24 | BinaryWriter::BinaryWriter(std::ostream& ostr, StreamByteOrder order): |
25 | _ostr(ostr), |
26 | _pTextConverter(0) |
27 | { |
28 | #if defined(POCO_ARCH_BIG_ENDIAN) |
29 | _flipBytes = (order == LITTLE_ENDIAN_BYTE_ORDER); |
30 | #else |
31 | _flipBytes = (order == BIG_ENDIAN_BYTE_ORDER); |
32 | #endif |
33 | } |
34 | |
35 | |
36 | BinaryWriter::BinaryWriter(std::ostream& ostr, TextEncoding& encoding, StreamByteOrder order): |
37 | _ostr(ostr), |
38 | _pTextConverter(new TextConverter(Poco::TextEncoding::global(), encoding)) |
39 | { |
40 | #if defined(POCO_ARCH_BIG_ENDIAN) |
41 | _flipBytes = (order == LITTLE_ENDIAN_BYTE_ORDER); |
42 | #else |
43 | _flipBytes = (order == BIG_ENDIAN_BYTE_ORDER); |
44 | #endif |
45 | } |
46 | |
47 | |
48 | BinaryWriter::~BinaryWriter() |
49 | { |
50 | delete _pTextConverter; |
51 | } |
52 | |
53 | |
54 | BinaryWriter& BinaryWriter::operator << (bool value) |
55 | { |
56 | return write(value, false); |
57 | } |
58 | |
59 | |
60 | BinaryWriter& BinaryWriter::operator << (char value) |
61 | { |
62 | return write(value, false); |
63 | } |
64 | |
65 | |
66 | BinaryWriter& BinaryWriter::operator << (unsigned char value) |
67 | { |
68 | return write(value, false); |
69 | } |
70 | |
71 | |
72 | BinaryWriter& BinaryWriter::operator << (signed char value) |
73 | { |
74 | return write(value, false); |
75 | } |
76 | |
77 | |
78 | BinaryWriter& BinaryWriter::operator << (short value) |
79 | { |
80 | return write(value, _flipBytes); |
81 | } |
82 | |
83 | |
84 | BinaryWriter& BinaryWriter::operator << (unsigned short value) |
85 | { |
86 | return write(value, _flipBytes); |
87 | } |
88 | |
89 | |
90 | BinaryWriter& BinaryWriter::operator << (int value) |
91 | { |
92 | return write(value, _flipBytes); |
93 | } |
94 | |
95 | |
96 | BinaryWriter& BinaryWriter::operator << (unsigned int value) |
97 | { |
98 | return write(value, _flipBytes); |
99 | } |
100 | |
101 | |
102 | #ifndef POCO_LONG_IS_64_BIT |
103 | |
104 | |
105 | BinaryWriter& BinaryWriter::operator << (long value) |
106 | { |
107 | #if defined(POCO_LONG_IS_64_BIT) |
108 | return write((Int64) value, _flipBytes); |
109 | #else |
110 | return write((Int32) value, _flipBytes); |
111 | #endif |
112 | } |
113 | |
114 | |
115 | BinaryWriter& BinaryWriter::operator << (unsigned long value) |
116 | { |
117 | #if defined(POCO_LONG_IS_64_BIT) |
118 | return write((UInt64) value, _flipBytes); |
119 | #else |
120 | return write((UInt32) value, _flipBytes); |
121 | #endif |
122 | } |
123 | |
124 | |
125 | #endif // POCO_LONG_IS_64_BIT |
126 | |
127 | |
128 | BinaryWriter& BinaryWriter::operator << (float value) |
129 | { |
130 | return write(value, _flipBytes); |
131 | } |
132 | |
133 | |
134 | BinaryWriter& BinaryWriter::operator << (double value) |
135 | { |
136 | return write(value, _flipBytes); |
137 | } |
138 | |
139 | |
140 | |
141 | BinaryWriter& BinaryWriter::operator << (Int64 value) |
142 | { |
143 | return write(value, _flipBytes); |
144 | } |
145 | |
146 | |
147 | BinaryWriter& BinaryWriter::operator << (UInt64 value) |
148 | { |
149 | return write(value, _flipBytes); |
150 | } |
151 | |
152 | |
153 | BinaryWriter& BinaryWriter::operator << (const std::string& value) |
154 | { |
155 | return write(value.c_str(), value.length()); |
156 | } |
157 | |
158 | |
159 | BinaryWriter& BinaryWriter::operator << (const char* value) |
160 | { |
161 | return write(value, std::strlen(value)); |
162 | } |
163 | |
164 | |
165 | void BinaryWriter::write7BitEncoded(UInt32 value) |
166 | { |
167 | write7BitEncoded<UInt32>(value); |
168 | } |
169 | |
170 | |
171 | #if defined(POCO_HAVE_INT64) |
172 | |
173 | |
174 | void BinaryWriter::write7BitEncoded(UInt64 value) |
175 | { |
176 | write7BitEncoded<UInt64>(value); |
177 | } |
178 | |
179 | |
180 | #endif |
181 | |
182 | |
183 | void BinaryWriter::writeRaw(const std::string& rawData) |
184 | { |
185 | _ostr.write(rawData.data(), (std::streamsize) rawData.length()); |
186 | } |
187 | |
188 | |
189 | void BinaryWriter::writeRaw(const char* buffer, std::streamsize length) |
190 | { |
191 | _ostr.write(buffer, length); |
192 | } |
193 | |
194 | |
195 | void BinaryWriter::writeBOM() |
196 | { |
197 | UInt16 value = 0xFEFF; |
198 | if (_flipBytes) value = ByteOrder::flipBytes(value); |
199 | _ostr.write((const char*) &value, sizeof(value)); |
200 | } |
201 | |
202 | |
203 | void BinaryWriter::flush() |
204 | { |
205 | _ostr.flush(); |
206 | } |
207 | |
208 | |
209 | BinaryWriter& BinaryWriter::write(const char* value, std::size_t length) |
210 | { |
211 | poco_check_ptr (value); |
212 | |
213 | if (_pTextConverter) |
214 | { |
215 | std::string converted; |
216 | _pTextConverter->convert(value, static_cast<int>(length), converted); |
217 | UInt32 convertedLength = (UInt32) converted.length(); |
218 | write7BitEncoded(convertedLength); |
219 | _ostr.write(converted.data(), convertedLength); |
220 | } |
221 | else |
222 | { |
223 | UInt32 lengthUInt32 = static_cast<UInt32>(length); |
224 | write7BitEncoded(lengthUInt32); |
225 | _ostr.write(value, lengthUInt32); |
226 | } |
227 | return *this; |
228 | } |
229 | |
230 | |
231 | } // namespace Poco |
232 | |