1 use crate::misc::remaining_capacity_as_slice_mut;
2 use crate::misc::remove_lifetime_mut;
3 use crate::varint;
4 use crate::wire_format;
5 use crate::zigzag::encode_zig_zag_32;
6 use crate::zigzag::encode_zig_zag_64;
7 use crate::Message;
8 use crate::ProtobufEnum;
9 use crate::ProtobufResult;
10 use crate::UnknownFields;
11 use crate::UnknownValueRef;
12 use std::io;
13 use std::io::Write;
14 use std::mem;
15
16 /// Equal to the default buffer size of `BufWriter`, so when
17 /// `CodedOutputStream` wraps `BufWriter`, it often skips double buffering.
18 const OUTPUT_STREAM_BUFFER_SIZE: usize = 8 * 1024;
19
20 #[doc(hidden)]
21 pub trait WithCodedOutputStream {
with_coded_output_stream<T, F>(self, cb: F) -> ProtobufResult<T> where F: FnOnce(&mut CodedOutputStream) -> ProtobufResult<T>22 fn with_coded_output_stream<T, F>(self, cb: F) -> ProtobufResult<T>
23 where
24 F: FnOnce(&mut CodedOutputStream) -> ProtobufResult<T>;
25 }
26
27 impl<'a> WithCodedOutputStream for &'a mut (dyn Write + 'a) {
with_coded_output_stream<T, F>(self, cb: F) -> ProtobufResult<T> where F: FnOnce(&mut CodedOutputStream) -> ProtobufResult<T>,28 fn with_coded_output_stream<T, F>(self, cb: F) -> ProtobufResult<T>
29 where
30 F: FnOnce(&mut CodedOutputStream) -> ProtobufResult<T>,
31 {
32 let mut os = CodedOutputStream::new(self);
33 let r = cb(&mut os)?;
34 os.flush()?;
35 Ok(r)
36 }
37 }
38
39 impl<'a> WithCodedOutputStream for &'a mut Vec<u8> {
with_coded_output_stream<T, F>(mut self, cb: F) -> ProtobufResult<T> where F: FnOnce(&mut CodedOutputStream) -> ProtobufResult<T>,40 fn with_coded_output_stream<T, F>(mut self, cb: F) -> ProtobufResult<T>
41 where
42 F: FnOnce(&mut CodedOutputStream) -> ProtobufResult<T>,
43 {
44 let mut os = CodedOutputStream::vec(&mut self);
45 let r = cb(&mut os)?;
46 os.flush()?;
47 Ok(r)
48 }
49 }
50
51 #[doc(hidden)]
with_coded_output_stream_to_bytes<F>(cb: F) -> ProtobufResult<Vec<u8>> where F: FnOnce(&mut CodedOutputStream) -> ProtobufResult<()>,52 pub fn with_coded_output_stream_to_bytes<F>(cb: F) -> ProtobufResult<Vec<u8>>
53 where
54 F: FnOnce(&mut CodedOutputStream) -> ProtobufResult<()>,
55 {
56 let mut v = Vec::new();
57 v.with_coded_output_stream(cb)?;
58 Ok(v)
59 }
60
61 enum OutputTarget<'a> {
62 Write(&'a mut dyn Write, Vec<u8>),
63 Vec(&'a mut Vec<u8>),
64 Bytes,
65 }
66
67 /// Buffered write with handy utilities
68 pub struct CodedOutputStream<'a> {
69 target: OutputTarget<'a>,
70 // alias to buf from target
71 buffer: &'a mut [u8],
72 // within buffer
73 position: usize,
74 }
75
76 impl<'a> CodedOutputStream<'a> {
77 /// Construct from given `Write`.
78 ///
79 /// `CodedOutputStream` is buffered even if `Write` is not
new(writer: &'a mut dyn Write) -> CodedOutputStream<'a>80 pub fn new(writer: &'a mut dyn Write) -> CodedOutputStream<'a> {
81 let buffer_len = OUTPUT_STREAM_BUFFER_SIZE;
82
83 let mut buffer_storage = Vec::with_capacity(buffer_len);
84 unsafe {
85 buffer_storage.set_len(buffer_len);
86 }
87
88 let buffer = unsafe { remove_lifetime_mut(&mut buffer_storage as &mut [u8]) };
89
90 CodedOutputStream {
91 target: OutputTarget::Write(writer, buffer_storage),
92 buffer: buffer,
93 position: 0,
94 }
95 }
96
97 /// `CodedOutputStream` which writes directly to bytes.
98 ///
99 /// Attempt to write more than bytes capacity results in error.
bytes(bytes: &'a mut [u8]) -> CodedOutputStream<'a>100 pub fn bytes(bytes: &'a mut [u8]) -> CodedOutputStream<'a> {
101 CodedOutputStream {
102 target: OutputTarget::Bytes,
103 buffer: bytes,
104 position: 0,
105 }
106 }
107
108 /// `CodedOutputStream` which writes directly to `Vec<u8>`.
109 ///
110 /// Caller should call `flush` at the end to guarantee vec contains
111 /// all written data.
vec(vec: &'a mut Vec<u8>) -> CodedOutputStream<'a>112 pub fn vec(vec: &'a mut Vec<u8>) -> CodedOutputStream<'a> {
113 CodedOutputStream {
114 target: OutputTarget::Vec(vec),
115 buffer: &mut [],
116 position: 0,
117 }
118 }
119
120 /// Check if EOF is reached.
121 ///
122 /// # Panics
123 ///
124 /// If underlying write has no EOF
check_eof(&self)125 pub fn check_eof(&self) {
126 match self.target {
127 OutputTarget::Bytes => {
128 assert_eq!(self.buffer.len() as u64, self.position as u64);
129 }
130 OutputTarget::Write(..) | OutputTarget::Vec(..) => {
131 panic!("must not be called with Writer or Vec");
132 }
133 }
134 }
135
refresh_buffer(&mut self) -> ProtobufResult<()>136 fn refresh_buffer(&mut self) -> ProtobufResult<()> {
137 match self.target {
138 OutputTarget::Write(ref mut write, _) => {
139 write.write_all(&self.buffer[0..self.position as usize])?;
140 self.position = 0;
141 }
142 OutputTarget::Vec(ref mut vec) => unsafe {
143 let vec_len = vec.len();
144 assert!(vec_len + self.position <= vec.capacity());
145 vec.set_len(vec_len + self.position);
146 vec.reserve(1);
147 self.buffer = remove_lifetime_mut(remaining_capacity_as_slice_mut(vec));
148 self.position = 0;
149 },
150 OutputTarget::Bytes => {
151 panic!("refresh_buffer must not be called on CodedOutputStream create from slice");
152 }
153 }
154 Ok(())
155 }
156
157 /// Flush the buffer to underlying write
flush(&mut self) -> ProtobufResult<()>158 pub fn flush(&mut self) -> ProtobufResult<()> {
159 match self.target {
160 OutputTarget::Bytes => Ok(()),
161 OutputTarget::Write(..) | OutputTarget::Vec(..) => {
162 // TODO: must not reserve additional in Vec
163 self.refresh_buffer()
164 }
165 }
166 }
167
168 /// Write a byte
write_raw_byte(&mut self, byte: u8) -> ProtobufResult<()>169 pub fn write_raw_byte(&mut self, byte: u8) -> ProtobufResult<()> {
170 if self.position as usize == self.buffer.len() {
171 self.refresh_buffer()?;
172 }
173 self.buffer[self.position as usize] = byte;
174 self.position += 1;
175 Ok(())
176 }
177
178 /// Write bytes
write_raw_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()>179 pub fn write_raw_bytes(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
180 if bytes.len() <= self.buffer.len() - self.position {
181 let bottom = self.position as usize;
182 let top = bottom + (bytes.len() as usize);
183 self.buffer[bottom..top].copy_from_slice(bytes);
184 self.position += bytes.len();
185 return Ok(());
186 }
187
188 self.refresh_buffer()?;
189
190 assert!(self.position == 0);
191
192 if self.position + bytes.len() < self.buffer.len() {
193 &mut self.buffer[self.position..self.position + bytes.len()].copy_from_slice(bytes);
194 self.position += bytes.len();
195 return Ok(());
196 }
197
198 match self.target {
199 OutputTarget::Bytes => {
200 unreachable!();
201 }
202 OutputTarget::Write(ref mut write, _) => {
203 write.write_all(bytes)?;
204 }
205 OutputTarget::Vec(ref mut vec) => {
206 vec.extend(bytes);
207 unsafe {
208 self.buffer = remove_lifetime_mut(remaining_capacity_as_slice_mut(vec));
209 }
210 }
211 }
212 Ok(())
213 }
214
215 /// Write a tag
write_tag( &mut self, field_number: u32, wire_type: wire_format::WireType, ) -> ProtobufResult<()>216 pub fn write_tag(
217 &mut self,
218 field_number: u32,
219 wire_type: wire_format::WireType,
220 ) -> ProtobufResult<()> {
221 self.write_raw_varint32(wire_format::Tag::make(field_number, wire_type).value())
222 }
223
224 /// Write varint
write_raw_varint32(&mut self, value: u32) -> ProtobufResult<()>225 pub fn write_raw_varint32(&mut self, value: u32) -> ProtobufResult<()> {
226 if self.buffer.len() - self.position >= 5 {
227 // fast path
228 let len = varint::encode_varint32(value, &mut self.buffer[self.position..]);
229 self.position += len;
230 Ok(())
231 } else {
232 // slow path
233 let buf = &mut [0u8; 5];
234 let len = varint::encode_varint32(value, buf);
235 self.write_raw_bytes(&buf[..len])
236 }
237 }
238
239 /// Write varint
write_raw_varint64(&mut self, value: u64) -> ProtobufResult<()>240 pub fn write_raw_varint64(&mut self, value: u64) -> ProtobufResult<()> {
241 if self.buffer.len() - self.position >= 10 {
242 // fast path
243 let len = varint::encode_varint64(value, &mut self.buffer[self.position..]);
244 self.position += len;
245 Ok(())
246 } else {
247 // slow path
248 let buf = &mut [0u8; 10];
249 let len = varint::encode_varint64(value, buf);
250 self.write_raw_bytes(&buf[..len])
251 }
252 }
253
254 /// Write 32-bit integer little endian
write_raw_little_endian32(&mut self, value: u32) -> ProtobufResult<()>255 pub fn write_raw_little_endian32(&mut self, value: u32) -> ProtobufResult<()> {
256 let bytes = unsafe { mem::transmute::<_, [u8; 4]>(value.to_le()) };
257 self.write_raw_bytes(&bytes)
258 }
259
260 /// Write 64-bit integer little endian
write_raw_little_endian64(&mut self, value: u64) -> ProtobufResult<()>261 pub fn write_raw_little_endian64(&mut self, value: u64) -> ProtobufResult<()> {
262 let bytes = unsafe { mem::transmute::<_, [u8; 8]>(value.to_le()) };
263 self.write_raw_bytes(&bytes)
264 }
265
266 /// Write `float`
write_float_no_tag(&mut self, value: f32) -> ProtobufResult<()>267 pub fn write_float_no_tag(&mut self, value: f32) -> ProtobufResult<()> {
268 let bits = unsafe { mem::transmute::<f32, u32>(value) };
269 self.write_raw_little_endian32(bits)
270 }
271
272 /// Write `double`
write_double_no_tag(&mut self, value: f64) -> ProtobufResult<()>273 pub fn write_double_no_tag(&mut self, value: f64) -> ProtobufResult<()> {
274 let bits = unsafe { mem::transmute::<f64, u64>(value) };
275 self.write_raw_little_endian64(bits)
276 }
277
278 /// Write `float` field
write_float(&mut self, field_number: u32, value: f32) -> ProtobufResult<()>279 pub fn write_float(&mut self, field_number: u32, value: f32) -> ProtobufResult<()> {
280 self.write_tag(field_number, wire_format::WireTypeFixed32)?;
281 self.write_float_no_tag(value)?;
282 Ok(())
283 }
284
285 /// Write `double` field
write_double(&mut self, field_number: u32, value: f64) -> ProtobufResult<()>286 pub fn write_double(&mut self, field_number: u32, value: f64) -> ProtobufResult<()> {
287 self.write_tag(field_number, wire_format::WireTypeFixed64)?;
288 self.write_double_no_tag(value)?;
289 Ok(())
290 }
291
292 /// Write varint
write_uint64_no_tag(&mut self, value: u64) -> ProtobufResult<()>293 pub fn write_uint64_no_tag(&mut self, value: u64) -> ProtobufResult<()> {
294 self.write_raw_varint64(value)
295 }
296
297 /// Write varint
write_uint32_no_tag(&mut self, value: u32) -> ProtobufResult<()>298 pub fn write_uint32_no_tag(&mut self, value: u32) -> ProtobufResult<()> {
299 self.write_raw_varint32(value)
300 }
301
302 /// Write varint
write_int64_no_tag(&mut self, value: i64) -> ProtobufResult<()>303 pub fn write_int64_no_tag(&mut self, value: i64) -> ProtobufResult<()> {
304 self.write_raw_varint64(value as u64)
305 }
306
307 /// Write varint
write_int32_no_tag(&mut self, value: i32) -> ProtobufResult<()>308 pub fn write_int32_no_tag(&mut self, value: i32) -> ProtobufResult<()> {
309 self.write_raw_varint64(value as u64)
310 }
311
312 /// Write zigzag varint
write_sint64_no_tag(&mut self, value: i64) -> ProtobufResult<()>313 pub fn write_sint64_no_tag(&mut self, value: i64) -> ProtobufResult<()> {
314 self.write_uint64_no_tag(encode_zig_zag_64(value))
315 }
316
317 /// Write zigzag varint
write_sint32_no_tag(&mut self, value: i32) -> ProtobufResult<()>318 pub fn write_sint32_no_tag(&mut self, value: i32) -> ProtobufResult<()> {
319 self.write_uint32_no_tag(encode_zig_zag_32(value))
320 }
321
322 /// Write `fixed64`
write_fixed64_no_tag(&mut self, value: u64) -> ProtobufResult<()>323 pub fn write_fixed64_no_tag(&mut self, value: u64) -> ProtobufResult<()> {
324 self.write_raw_little_endian64(value)
325 }
326
327 /// Write `fixed32`
write_fixed32_no_tag(&mut self, value: u32) -> ProtobufResult<()>328 pub fn write_fixed32_no_tag(&mut self, value: u32) -> ProtobufResult<()> {
329 self.write_raw_little_endian32(value)
330 }
331
332 /// Write `sfixed64`
write_sfixed64_no_tag(&mut self, value: i64) -> ProtobufResult<()>333 pub fn write_sfixed64_no_tag(&mut self, value: i64) -> ProtobufResult<()> {
334 self.write_raw_little_endian64(value as u64)
335 }
336
337 /// Write `sfixed32`
write_sfixed32_no_tag(&mut self, value: i32) -> ProtobufResult<()>338 pub fn write_sfixed32_no_tag(&mut self, value: i32) -> ProtobufResult<()> {
339 self.write_raw_little_endian32(value as u32)
340 }
341
342 /// Write `bool`
write_bool_no_tag(&mut self, value: bool) -> ProtobufResult<()>343 pub fn write_bool_no_tag(&mut self, value: bool) -> ProtobufResult<()> {
344 self.write_raw_varint32(if value { 1 } else { 0 })
345 }
346
347 /// Write `enum`
write_enum_no_tag(&mut self, value: i32) -> ProtobufResult<()>348 pub fn write_enum_no_tag(&mut self, value: i32) -> ProtobufResult<()> {
349 self.write_int32_no_tag(value)
350 }
351
352 /// Write `enum`
write_enum_obj_no_tag<E>(&mut self, value: E) -> ProtobufResult<()> where E: ProtobufEnum,353 pub fn write_enum_obj_no_tag<E>(&mut self, value: E) -> ProtobufResult<()>
354 where
355 E: ProtobufEnum,
356 {
357 self.write_enum_no_tag(value.value())
358 }
359
360 /// Write unknown value
write_unknown_no_tag(&mut self, unknown: UnknownValueRef) -> ProtobufResult<()>361 pub fn write_unknown_no_tag(&mut self, unknown: UnknownValueRef) -> ProtobufResult<()> {
362 match unknown {
363 UnknownValueRef::Fixed64(fixed64) => self.write_raw_little_endian64(fixed64),
364 UnknownValueRef::Fixed32(fixed32) => self.write_raw_little_endian32(fixed32),
365 UnknownValueRef::Varint(varint) => self.write_raw_varint64(varint),
366 UnknownValueRef::LengthDelimited(bytes) => self.write_bytes_no_tag(bytes),
367 }
368 }
369
370 /// Write `uint64` field
write_uint64(&mut self, field_number: u32, value: u64) -> ProtobufResult<()>371 pub fn write_uint64(&mut self, field_number: u32, value: u64) -> ProtobufResult<()> {
372 self.write_tag(field_number, wire_format::WireTypeVarint)?;
373 self.write_uint64_no_tag(value)?;
374 Ok(())
375 }
376
377 /// Write `uint32` field
write_uint32(&mut self, field_number: u32, value: u32) -> ProtobufResult<()>378 pub fn write_uint32(&mut self, field_number: u32, value: u32) -> ProtobufResult<()> {
379 self.write_tag(field_number, wire_format::WireTypeVarint)?;
380 self.write_uint32_no_tag(value)?;
381 Ok(())
382 }
383
384 /// Write `int64` field
write_int64(&mut self, field_number: u32, value: i64) -> ProtobufResult<()>385 pub fn write_int64(&mut self, field_number: u32, value: i64) -> ProtobufResult<()> {
386 self.write_tag(field_number, wire_format::WireTypeVarint)?;
387 self.write_int64_no_tag(value)?;
388 Ok(())
389 }
390
391 /// Write `int32` field
write_int32(&mut self, field_number: u32, value: i32) -> ProtobufResult<()>392 pub fn write_int32(&mut self, field_number: u32, value: i32) -> ProtobufResult<()> {
393 self.write_tag(field_number, wire_format::WireTypeVarint)?;
394 self.write_int32_no_tag(value)?;
395 Ok(())
396 }
397
398 /// Write `sint64` field
write_sint64(&mut self, field_number: u32, value: i64) -> ProtobufResult<()>399 pub fn write_sint64(&mut self, field_number: u32, value: i64) -> ProtobufResult<()> {
400 self.write_tag(field_number, wire_format::WireTypeVarint)?;
401 self.write_sint64_no_tag(value)?;
402 Ok(())
403 }
404
405 /// Write `sint32` field
write_sint32(&mut self, field_number: u32, value: i32) -> ProtobufResult<()>406 pub fn write_sint32(&mut self, field_number: u32, value: i32) -> ProtobufResult<()> {
407 self.write_tag(field_number, wire_format::WireTypeVarint)?;
408 self.write_sint32_no_tag(value)?;
409 Ok(())
410 }
411
412 /// Write `fixed64` field
write_fixed64(&mut self, field_number: u32, value: u64) -> ProtobufResult<()>413 pub fn write_fixed64(&mut self, field_number: u32, value: u64) -> ProtobufResult<()> {
414 self.write_tag(field_number, wire_format::WireTypeFixed64)?;
415 self.write_fixed64_no_tag(value)?;
416 Ok(())
417 }
418
419 /// Write `fixed32` field
write_fixed32(&mut self, field_number: u32, value: u32) -> ProtobufResult<()>420 pub fn write_fixed32(&mut self, field_number: u32, value: u32) -> ProtobufResult<()> {
421 self.write_tag(field_number, wire_format::WireTypeFixed32)?;
422 self.write_fixed32_no_tag(value)?;
423 Ok(())
424 }
425
426 /// Write `sfixed64` field
write_sfixed64(&mut self, field_number: u32, value: i64) -> ProtobufResult<()>427 pub fn write_sfixed64(&mut self, field_number: u32, value: i64) -> ProtobufResult<()> {
428 self.write_tag(field_number, wire_format::WireTypeFixed64)?;
429 self.write_sfixed64_no_tag(value)?;
430 Ok(())
431 }
432
433 /// Write `sfixed32` field
write_sfixed32(&mut self, field_number: u32, value: i32) -> ProtobufResult<()>434 pub fn write_sfixed32(&mut self, field_number: u32, value: i32) -> ProtobufResult<()> {
435 self.write_tag(field_number, wire_format::WireTypeFixed32)?;
436 self.write_sfixed32_no_tag(value)?;
437 Ok(())
438 }
439
440 /// Write `bool` field
write_bool(&mut self, field_number: u32, value: bool) -> ProtobufResult<()>441 pub fn write_bool(&mut self, field_number: u32, value: bool) -> ProtobufResult<()> {
442 self.write_tag(field_number, wire_format::WireTypeVarint)?;
443 self.write_bool_no_tag(value)?;
444 Ok(())
445 }
446
447 /// Write `enum` field
write_enum(&mut self, field_number: u32, value: i32) -> ProtobufResult<()>448 pub fn write_enum(&mut self, field_number: u32, value: i32) -> ProtobufResult<()> {
449 self.write_tag(field_number, wire_format::WireTypeVarint)?;
450 self.write_enum_no_tag(value)?;
451 Ok(())
452 }
453
454 /// Write `enum` field
write_enum_obj<E>(&mut self, field_number: u32, value: E) -> ProtobufResult<()> where E: ProtobufEnum,455 pub fn write_enum_obj<E>(&mut self, field_number: u32, value: E) -> ProtobufResult<()>
456 where
457 E: ProtobufEnum,
458 {
459 self.write_enum(field_number, value.value())
460 }
461
462 /// Write unknown field
write_unknown( &mut self, field_number: u32, value: UnknownValueRef, ) -> ProtobufResult<()>463 pub fn write_unknown(
464 &mut self,
465 field_number: u32,
466 value: UnknownValueRef,
467 ) -> ProtobufResult<()> {
468 self.write_tag(field_number, value.wire_type())?;
469 self.write_unknown_no_tag(value)?;
470 Ok(())
471 }
472
473 /// Write unknown fields
write_unknown_fields(&mut self, fields: &UnknownFields) -> ProtobufResult<()>474 pub fn write_unknown_fields(&mut self, fields: &UnknownFields) -> ProtobufResult<()> {
475 for (number, values) in fields {
476 for value in values {
477 self.write_unknown(number, value)?;
478 }
479 }
480 Ok(())
481 }
482
483 /// Write bytes
write_bytes_no_tag(&mut self, bytes: &[u8]) -> ProtobufResult<()>484 pub fn write_bytes_no_tag(&mut self, bytes: &[u8]) -> ProtobufResult<()> {
485 self.write_raw_varint32(bytes.len() as u32)?;
486 self.write_raw_bytes(bytes)?;
487 Ok(())
488 }
489
490 /// Write string
write_string_no_tag(&mut self, s: &str) -> ProtobufResult<()>491 pub fn write_string_no_tag(&mut self, s: &str) -> ProtobufResult<()> {
492 self.write_bytes_no_tag(s.as_bytes())
493 }
494
495 /// Write message
write_message_no_tag<M: Message>(&mut self, msg: &M) -> ProtobufResult<()>496 pub fn write_message_no_tag<M: Message>(&mut self, msg: &M) -> ProtobufResult<()> {
497 msg.write_length_delimited_to(self)
498 }
499
500 /// Write `bytes` field
write_bytes(&mut self, field_number: u32, bytes: &[u8]) -> ProtobufResult<()>501 pub fn write_bytes(&mut self, field_number: u32, bytes: &[u8]) -> ProtobufResult<()> {
502 self.write_tag(field_number, wire_format::WireTypeLengthDelimited)?;
503 self.write_bytes_no_tag(bytes)?;
504 Ok(())
505 }
506
507 /// Write `string` field
write_string(&mut self, field_number: u32, s: &str) -> ProtobufResult<()>508 pub fn write_string(&mut self, field_number: u32, s: &str) -> ProtobufResult<()> {
509 self.write_tag(field_number, wire_format::WireTypeLengthDelimited)?;
510 self.write_string_no_tag(s)?;
511 Ok(())
512 }
513
514 /// Write `message` field
write_message<M: Message>(&mut self, field_number: u32, msg: &M) -> ProtobufResult<()>515 pub fn write_message<M: Message>(&mut self, field_number: u32, msg: &M) -> ProtobufResult<()> {
516 self.write_tag(field_number, wire_format::WireTypeLengthDelimited)?;
517 self.write_message_no_tag(msg)?;
518 Ok(())
519 }
520 }
521
522 impl<'a> Write for CodedOutputStream<'a> {
write(&mut self, buf: &[u8]) -> io::Result<usize>523 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
524 self.write_raw_bytes(buf)?;
525 Ok(buf.len())
526 }
527
flush(&mut self) -> io::Result<()>528 fn flush(&mut self) -> io::Result<()> {
529 CodedOutputStream::flush(self).map_err(Into::into)
530 }
531 }
532
533 #[cfg(test)]
534 mod test {
535 use crate::coded_output_stream::CodedOutputStream;
536 use crate::hex::decode_hex;
537 use crate::hex::encode_hex;
538 use crate::wire_format;
539 use crate::ProtobufResult;
540 use std::io::Write;
541 use std::iter;
542
test_write<F>(expected: &str, mut gen: F) where F: FnMut(&mut CodedOutputStream) -> ProtobufResult<()>,543 fn test_write<F>(expected: &str, mut gen: F)
544 where
545 F: FnMut(&mut CodedOutputStream) -> ProtobufResult<()>,
546 {
547 let expected_bytes = decode_hex(expected);
548
549 // write to Write
550 {
551 let mut v = Vec::new();
552 {
553 let mut os = CodedOutputStream::new(&mut v as &mut dyn Write);
554 gen(&mut os).unwrap();
555 os.flush().unwrap();
556 }
557 assert_eq!(encode_hex(&expected_bytes), encode_hex(&v));
558 }
559
560 // write to &[u8]
561 {
562 let mut r = Vec::with_capacity(expected_bytes.len());
563 r.resize(expected_bytes.len(), 0);
564 {
565 let mut os = CodedOutputStream::bytes(&mut r);
566 gen(&mut os).unwrap();
567 os.check_eof();
568 }
569 assert_eq!(encode_hex(&expected_bytes), encode_hex(&r));
570 }
571
572 // write to Vec<u8>
573 {
574 let mut r = Vec::new();
575 r.extend(&[11, 22, 33, 44, 55, 66, 77]);
576 {
577 let mut os = CodedOutputStream::vec(&mut r);
578 gen(&mut os).unwrap();
579 os.flush().unwrap();
580 }
581
582 r.drain(..7);
583 assert_eq!(encode_hex(&expected_bytes), encode_hex(&r));
584 }
585 }
586
587 #[test]
test_output_stream_write_raw_byte()588 fn test_output_stream_write_raw_byte() {
589 test_write("a1", |os| os.write_raw_byte(0xa1));
590 }
591
592 #[test]
test_output_stream_write_tag()593 fn test_output_stream_write_tag() {
594 test_write("08", |os| os.write_tag(1, wire_format::WireTypeVarint));
595 }
596
597 #[test]
test_output_stream_write_raw_bytes()598 fn test_output_stream_write_raw_bytes() {
599 test_write("00 ab", |os| os.write_raw_bytes(&[0x00, 0xab]));
600
601 let expected = iter::repeat("01 02 03 04")
602 .take(2048)
603 .collect::<Vec<_>>()
604 .join(" ");
605 test_write(&expected, |os| {
606 for _ in 0..2048 {
607 os.write_raw_bytes(&[0x01, 0x02, 0x03, 0x04])?;
608 }
609
610 Ok(())
611 });
612 }
613
614 #[test]
test_output_stream_write_raw_varint32()615 fn test_output_stream_write_raw_varint32() {
616 test_write("96 01", |os| os.write_raw_varint32(150));
617 test_write("ff ff ff ff 0f", |os| os.write_raw_varint32(0xffffffff));
618 }
619
620 #[test]
test_output_stream_write_raw_varint64()621 fn test_output_stream_write_raw_varint64() {
622 test_write("96 01", |os| os.write_raw_varint64(150));
623 test_write("ff ff ff ff ff ff ff ff ff 01", |os| {
624 os.write_raw_varint64(0xffffffffffffffff)
625 });
626 }
627
628 #[test]
test_output_stream_write_int32_no_tag()629 fn test_output_stream_write_int32_no_tag() {
630 test_write("ff ff ff ff ff ff ff ff ff 01", |os| {
631 os.write_int32_no_tag(-1)
632 });
633 }
634
635 #[test]
test_output_stream_write_int64_no_tag()636 fn test_output_stream_write_int64_no_tag() {
637 test_write("ff ff ff ff ff ff ff ff ff 01", |os| {
638 os.write_int64_no_tag(-1)
639 });
640 }
641
642 #[test]
test_output_stream_write_raw_little_endian32()643 fn test_output_stream_write_raw_little_endian32() {
644 test_write("f1 e2 d3 c4", |os| os.write_raw_little_endian32(0xc4d3e2f1));
645 }
646
647 #[test]
test_output_stream_write_float_no_tag()648 fn test_output_stream_write_float_no_tag() {
649 test_write("95 73 13 61", |os| os.write_float_no_tag(17e19));
650 }
651
652 #[test]
test_output_stream_write_double_no_tag()653 fn test_output_stream_write_double_no_tag() {
654 test_write("40 d5 ab 68 b3 07 3d 46", |os| {
655 os.write_double_no_tag(23e29)
656 });
657 }
658
659 #[test]
test_output_stream_write_raw_little_endian64()660 fn test_output_stream_write_raw_little_endian64() {
661 test_write("f1 e2 d3 c4 b5 a6 07 f8", |os| {
662 os.write_raw_little_endian64(0xf807a6b5c4d3e2f1)
663 });
664 }
665
666 #[test]
test_output_stream_io_write()667 fn test_output_stream_io_write() {
668 let expected = [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77];
669
670 // write to Write
671 {
672 let mut v = Vec::new();
673 {
674 let mut os = CodedOutputStream::new(&mut v as &mut dyn Write);
675 Write::write(&mut os, &expected).expect("io::Write::write");
676 Write::flush(&mut os).expect("io::Write::flush");
677 }
678 assert_eq!(expected, *v);
679 }
680
681 // write to &[u8]
682 {
683 let mut v = Vec::with_capacity(expected.len());
684 v.resize(expected.len(), 0);
685 {
686 let mut os = CodedOutputStream::bytes(&mut v);
687 Write::write(&mut os, &expected).expect("io::Write::write");
688 Write::flush(&mut os).expect("io::Write::flush");
689 os.check_eof();
690 }
691 assert_eq!(expected, *v);
692 }
693
694 // write to Vec<u8>
695 {
696 let mut v = Vec::new();
697 {
698 let mut os = CodedOutputStream::vec(&mut v);
699 Write::write(&mut os, &expected).expect("io::Write::write");
700 Write::flush(&mut os).expect("io::Write::flush");
701 }
702 assert_eq!(expected, *v);
703 }
704 }
705 }
706