]> git.proxmox.com Git - rustc.git/blame - vendor/rustc-ap-rustc_serialize/src/opaque.rs
Update upstream source from tag 'upstream/1.52.1+dfsg1'
[rustc.git] / vendor / rustc-ap-rustc_serialize / src / opaque.rs
CommitLineData
f20569fa
XL
1use crate::leb128::{self, max_leb128_len};
2use crate::serialize;
3use std::borrow::Cow;
4use std::fs::File;
5use std::io::{self, Write};
6use std::mem::MaybeUninit;
7use std::path::Path;
8use std::ptr;
9
10// -----------------------------------------------------------------------------
11// Encoder
12// -----------------------------------------------------------------------------
13
14pub type EncodeResult = Result<(), !>;
15
16pub struct Encoder {
17 pub data: Vec<u8>,
18}
19
20impl Encoder {
21 pub fn new(data: Vec<u8>) -> Encoder {
22 Encoder { data }
23 }
24
25 pub fn into_inner(self) -> Vec<u8> {
26 self.data
27 }
28
29 #[inline]
30 pub fn position(&self) -> usize {
31 self.data.len()
32 }
33
34 #[inline]
35 pub fn emit_raw_bytes(&mut self, s: &[u8]) {
36 self.data.extend_from_slice(s);
37 }
38}
39
40macro_rules! write_leb128 {
41 ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{
42 const MAX_ENCODED_LEN: usize = max_leb128_len!($int_ty);
43 let old_len = $enc.data.len();
44
45 if MAX_ENCODED_LEN > $enc.data.capacity() - old_len {
46 $enc.data.reserve(MAX_ENCODED_LEN);
47 }
48
49 // SAFETY: The above check and `reserve` ensures that there is enough
50 // room to write the encoded value to the vector's internal buffer.
51 unsafe {
52 let buf = &mut *($enc.data.as_mut_ptr().add(old_len)
53 as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN]);
54 let encoded = leb128::$fun(buf, $value);
55 $enc.data.set_len(old_len + encoded.len());
56 }
57
58 Ok(())
59 }};
60}
61
62impl serialize::Encoder for Encoder {
63 type Error = !;
64
65 #[inline]
66 fn emit_unit(&mut self) -> EncodeResult {
67 Ok(())
68 }
69
70 #[inline]
71 fn emit_usize(&mut self, v: usize) -> EncodeResult {
72 write_leb128!(self, v, usize, write_usize_leb128)
73 }
74
75 #[inline]
76 fn emit_u128(&mut self, v: u128) -> EncodeResult {
77 write_leb128!(self, v, u128, write_u128_leb128)
78 }
79
80 #[inline]
81 fn emit_u64(&mut self, v: u64) -> EncodeResult {
82 write_leb128!(self, v, u64, write_u64_leb128)
83 }
84
85 #[inline]
86 fn emit_u32(&mut self, v: u32) -> EncodeResult {
87 write_leb128!(self, v, u32, write_u32_leb128)
88 }
89
90 #[inline]
91 fn emit_u16(&mut self, v: u16) -> EncodeResult {
92 write_leb128!(self, v, u16, write_u16_leb128)
93 }
94
95 #[inline]
96 fn emit_u8(&mut self, v: u8) -> EncodeResult {
97 self.data.push(v);
98 Ok(())
99 }
100
101 #[inline]
102 fn emit_isize(&mut self, v: isize) -> EncodeResult {
103 write_leb128!(self, v, isize, write_isize_leb128)
104 }
105
106 #[inline]
107 fn emit_i128(&mut self, v: i128) -> EncodeResult {
108 write_leb128!(self, v, i128, write_i128_leb128)
109 }
110
111 #[inline]
112 fn emit_i64(&mut self, v: i64) -> EncodeResult {
113 write_leb128!(self, v, i64, write_i64_leb128)
114 }
115
116 #[inline]
117 fn emit_i32(&mut self, v: i32) -> EncodeResult {
118 write_leb128!(self, v, i32, write_i32_leb128)
119 }
120
121 #[inline]
122 fn emit_i16(&mut self, v: i16) -> EncodeResult {
123 write_leb128!(self, v, i16, write_i16_leb128)
124 }
125
126 #[inline]
127 fn emit_i8(&mut self, v: i8) -> EncodeResult {
128 let as_u8: u8 = unsafe { std::mem::transmute(v) };
129 self.emit_u8(as_u8)
130 }
131
132 #[inline]
133 fn emit_bool(&mut self, v: bool) -> EncodeResult {
134 self.emit_u8(if v { 1 } else { 0 })
135 }
136
137 #[inline]
138 fn emit_f64(&mut self, v: f64) -> EncodeResult {
139 let as_u64: u64 = v.to_bits();
140 self.emit_u64(as_u64)
141 }
142
143 #[inline]
144 fn emit_f32(&mut self, v: f32) -> EncodeResult {
145 let as_u32: u32 = v.to_bits();
146 self.emit_u32(as_u32)
147 }
148
149 #[inline]
150 fn emit_char(&mut self, v: char) -> EncodeResult {
151 self.emit_u32(v as u32)
152 }
153
154 #[inline]
155 fn emit_str(&mut self, v: &str) -> EncodeResult {
156 self.emit_usize(v.len())?;
157 self.emit_raw_bytes(v.as_bytes());
158 Ok(())
159 }
160}
161
162pub type FileEncodeResult = Result<(), io::Error>;
163
164// `FileEncoder` encodes data to file via fixed-size buffer.
165//
166// When encoding large amounts of data to a file, using `FileEncoder` may be
167// preferred over using `Encoder` to encode to a `Vec`, and then writing the
168// `Vec` to file, as the latter uses as much memory as there is encoded data,
169// while the former uses the fixed amount of memory allocated to the buffer.
170// `FileEncoder` also has the advantage of not needing to reallocate as data
171// is appended to it, but the disadvantage of requiring more error handling,
172// which has some runtime overhead.
173pub struct FileEncoder {
174 // The input buffer. For adequate performance, we need more control over
175 // buffering than `BufWriter` offers. If `BufWriter` ever offers a raw
176 // buffer access API, we can use it, and remove `buf` and `buffered`.
177 buf: Box<[MaybeUninit<u8>]>,
178 buffered: usize,
179 flushed: usize,
180 file: File,
181}
182
183impl FileEncoder {
184 pub fn new<P: AsRef<Path>>(path: P) -> io::Result<Self> {
185 const DEFAULT_BUF_SIZE: usize = 8192;
186 FileEncoder::with_capacity(path, DEFAULT_BUF_SIZE)
187 }
188
189 pub fn with_capacity<P: AsRef<Path>>(path: P, capacity: usize) -> io::Result<Self> {
190 // Require capacity at least as large as the largest LEB128 encoding
191 // here, so that we don't have to check or handle this on every write.
192 assert!(capacity >= max_leb128_len());
193
194 // Require capacity small enough such that some capacity checks can be
195 // done using guaranteed non-overflowing add rather than sub, which
196 // shaves an instruction off those code paths (on x86 at least).
197 assert!(capacity <= usize::MAX - max_leb128_len());
198
199 let file = File::create(path)?;
200
201 Ok(FileEncoder { buf: Box::new_uninit_slice(capacity), buffered: 0, flushed: 0, file })
202 }
203
204 #[inline]
205 pub fn position(&self) -> usize {
206 // Tracking position this way instead of having a `self.position` field
207 // means that we don't have to update the position on every write call.
208 self.flushed + self.buffered
209 }
210
211 #[inline]
212 pub fn emit_raw_bytes(&mut self, s: &[u8]) -> FileEncodeResult {
213 self.write_all(s)
214 }
215
216 pub fn flush(&mut self) -> FileEncodeResult {
217 // This is basically a copy of `BufWriter::flush`. If `BufWriter` ever
218 // offers a raw buffer access API, we can use it, and remove this.
219
220 /// Helper struct to ensure the buffer is updated after all the writes
221 /// are complete. It tracks the number of written bytes and drains them
222 /// all from the front of the buffer when dropped.
223 struct BufGuard<'a> {
224 buffer: &'a mut [u8],
225 encoder_buffered: &'a mut usize,
226 encoder_flushed: &'a mut usize,
227 flushed: usize,
228 }
229
230 impl<'a> BufGuard<'a> {
231 fn new(
232 buffer: &'a mut [u8],
233 encoder_buffered: &'a mut usize,
234 encoder_flushed: &'a mut usize,
235 ) -> Self {
236 assert_eq!(buffer.len(), *encoder_buffered);
237 Self { buffer, encoder_buffered, encoder_flushed, flushed: 0 }
238 }
239
240 /// The unwritten part of the buffer
241 fn remaining(&self) -> &[u8] {
242 &self.buffer[self.flushed..]
243 }
244
245 /// Flag some bytes as removed from the front of the buffer
246 fn consume(&mut self, amt: usize) {
247 self.flushed += amt;
248 }
249
250 /// true if all of the bytes have been written
251 fn done(&self) -> bool {
252 self.flushed >= *self.encoder_buffered
253 }
254 }
255
256 impl Drop for BufGuard<'_> {
257 fn drop(&mut self) {
258 if self.flushed > 0 {
259 if self.done() {
260 *self.encoder_flushed += *self.encoder_buffered;
261 *self.encoder_buffered = 0;
262 } else {
263 self.buffer.copy_within(self.flushed.., 0);
264 *self.encoder_flushed += self.flushed;
265 *self.encoder_buffered -= self.flushed;
266 }
267 }
268 }
269 }
270
271 let mut guard = BufGuard::new(
272 unsafe { MaybeUninit::slice_assume_init_mut(&mut self.buf[..self.buffered]) },
273 &mut self.buffered,
274 &mut self.flushed,
275 );
276
277 while !guard.done() {
278 match self.file.write(guard.remaining()) {
279 Ok(0) => {
280 return Err(io::Error::new(
281 io::ErrorKind::WriteZero,
282 "failed to write the buffered data",
283 ));
284 }
285 Ok(n) => guard.consume(n),
286 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
287 Err(e) => return Err(e),
288 }
289 }
290
291 Ok(())
292 }
293
294 #[inline]
295 fn capacity(&self) -> usize {
296 self.buf.len()
297 }
298
299 #[inline]
300 fn write_one(&mut self, value: u8) -> FileEncodeResult {
301 // We ensure this during `FileEncoder` construction.
302 debug_assert!(self.capacity() >= 1);
303
304 let mut buffered = self.buffered;
305
306 if std::intrinsics::unlikely(buffered >= self.capacity()) {
307 self.flush()?;
308 buffered = 0;
309 }
310
311 // SAFETY: The above check and `flush` ensures that there is enough
312 // room to write the input to the buffer.
313 unsafe {
314 *MaybeUninit::slice_as_mut_ptr(&mut self.buf).add(buffered) = value;
315 }
316
317 self.buffered = buffered + 1;
318
319 Ok(())
320 }
321
322 #[inline]
323 fn write_all(&mut self, buf: &[u8]) -> FileEncodeResult {
324 let capacity = self.capacity();
325 let buf_len = buf.len();
326
327 if std::intrinsics::likely(buf_len <= capacity) {
328 let mut buffered = self.buffered;
329
330 if std::intrinsics::unlikely(buf_len > capacity - buffered) {
331 self.flush()?;
332 buffered = 0;
333 }
334
335 // SAFETY: The above check and `flush` ensures that there is enough
336 // room to write the input to the buffer.
337 unsafe {
338 let src = buf.as_ptr();
339 let dst = MaybeUninit::slice_as_mut_ptr(&mut self.buf).add(buffered);
340 ptr::copy_nonoverlapping(src, dst, buf_len);
341 }
342
343 self.buffered = buffered + buf_len;
344
345 Ok(())
346 } else {
347 self.write_all_unbuffered(buf)
348 }
349 }
350
351 fn write_all_unbuffered(&mut self, mut buf: &[u8]) -> FileEncodeResult {
352 if self.buffered > 0 {
353 self.flush()?;
354 }
355
356 // This is basically a copy of `Write::write_all` but also updates our
357 // `self.flushed`. It's necessary because `Write::write_all` does not
358 // return the number of bytes written when an error is encountered, and
359 // without that, we cannot accurately update `self.flushed` on error.
360 while !buf.is_empty() {
361 match self.file.write(buf) {
362 Ok(0) => {
363 return Err(io::Error::new(
364 io::ErrorKind::WriteZero,
365 "failed to write whole buffer",
366 ));
367 }
368 Ok(n) => {
369 buf = &buf[n..];
370 self.flushed += n;
371 }
372 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
373 Err(e) => return Err(e),
374 }
375 }
376
377 Ok(())
378 }
379}
380
381impl Drop for FileEncoder {
382 fn drop(&mut self) {
383 let _result = self.flush();
384 }
385}
386
387macro_rules! file_encoder_write_leb128 {
388 ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{
389 const MAX_ENCODED_LEN: usize = max_leb128_len!($int_ty);
390
391 // We ensure this during `FileEncoder` construction.
392 debug_assert!($enc.capacity() >= MAX_ENCODED_LEN);
393
394 let mut buffered = $enc.buffered;
395
396 // This can't overflow. See assertion in `FileEncoder::with_capacity`.
397 if std::intrinsics::unlikely(buffered + MAX_ENCODED_LEN > $enc.capacity()) {
398 $enc.flush()?;
399 buffered = 0;
400 }
401
402 // SAFETY: The above check and flush ensures that there is enough
403 // room to write the encoded value to the buffer.
404 let buf = unsafe {
405 &mut *($enc.buf.as_mut_ptr().add(buffered) as *mut [MaybeUninit<u8>; MAX_ENCODED_LEN])
406 };
407
408 let encoded = leb128::$fun(buf, $value);
409 $enc.buffered = buffered + encoded.len();
410
411 Ok(())
412 }};
413}
414
415impl serialize::Encoder for FileEncoder {
416 type Error = io::Error;
417
418 #[inline]
419 fn emit_unit(&mut self) -> FileEncodeResult {
420 Ok(())
421 }
422
423 #[inline]
424 fn emit_usize(&mut self, v: usize) -> FileEncodeResult {
425 file_encoder_write_leb128!(self, v, usize, write_usize_leb128)
426 }
427
428 #[inline]
429 fn emit_u128(&mut self, v: u128) -> FileEncodeResult {
430 file_encoder_write_leb128!(self, v, u128, write_u128_leb128)
431 }
432
433 #[inline]
434 fn emit_u64(&mut self, v: u64) -> FileEncodeResult {
435 file_encoder_write_leb128!(self, v, u64, write_u64_leb128)
436 }
437
438 #[inline]
439 fn emit_u32(&mut self, v: u32) -> FileEncodeResult {
440 file_encoder_write_leb128!(self, v, u32, write_u32_leb128)
441 }
442
443 #[inline]
444 fn emit_u16(&mut self, v: u16) -> FileEncodeResult {
445 file_encoder_write_leb128!(self, v, u16, write_u16_leb128)
446 }
447
448 #[inline]
449 fn emit_u8(&mut self, v: u8) -> FileEncodeResult {
450 self.write_one(v)
451 }
452
453 #[inline]
454 fn emit_isize(&mut self, v: isize) -> FileEncodeResult {
455 file_encoder_write_leb128!(self, v, isize, write_isize_leb128)
456 }
457
458 #[inline]
459 fn emit_i128(&mut self, v: i128) -> FileEncodeResult {
460 file_encoder_write_leb128!(self, v, i128, write_i128_leb128)
461 }
462
463 #[inline]
464 fn emit_i64(&mut self, v: i64) -> FileEncodeResult {
465 file_encoder_write_leb128!(self, v, i64, write_i64_leb128)
466 }
467
468 #[inline]
469 fn emit_i32(&mut self, v: i32) -> FileEncodeResult {
470 file_encoder_write_leb128!(self, v, i32, write_i32_leb128)
471 }
472
473 #[inline]
474 fn emit_i16(&mut self, v: i16) -> FileEncodeResult {
475 file_encoder_write_leb128!(self, v, i16, write_i16_leb128)
476 }
477
478 #[inline]
479 fn emit_i8(&mut self, v: i8) -> FileEncodeResult {
480 let as_u8: u8 = unsafe { std::mem::transmute(v) };
481 self.emit_u8(as_u8)
482 }
483
484 #[inline]
485 fn emit_bool(&mut self, v: bool) -> FileEncodeResult {
486 self.emit_u8(if v { 1 } else { 0 })
487 }
488
489 #[inline]
490 fn emit_f64(&mut self, v: f64) -> FileEncodeResult {
491 let as_u64: u64 = v.to_bits();
492 self.emit_u64(as_u64)
493 }
494
495 #[inline]
496 fn emit_f32(&mut self, v: f32) -> FileEncodeResult {
497 let as_u32: u32 = v.to_bits();
498 self.emit_u32(as_u32)
499 }
500
501 #[inline]
502 fn emit_char(&mut self, v: char) -> FileEncodeResult {
503 self.emit_u32(v as u32)
504 }
505
506 #[inline]
507 fn emit_str(&mut self, v: &str) -> FileEncodeResult {
508 self.emit_usize(v.len())?;
509 self.emit_raw_bytes(v.as_bytes())
510 }
511}
512
513// -----------------------------------------------------------------------------
514// Decoder
515// -----------------------------------------------------------------------------
516
517pub struct Decoder<'a> {
518 pub data: &'a [u8],
519 position: usize,
520}
521
522impl<'a> Decoder<'a> {
523 #[inline]
524 pub fn new(data: &'a [u8], position: usize) -> Decoder<'a> {
525 Decoder { data, position }
526 }
527
528 #[inline]
529 pub fn position(&self) -> usize {
530 self.position
531 }
532
533 #[inline]
534 pub fn set_position(&mut self, pos: usize) {
535 self.position = pos
536 }
537
538 #[inline]
539 pub fn advance(&mut self, bytes: usize) {
540 self.position += bytes;
541 }
542
543 #[inline]
544 pub fn read_raw_bytes(&mut self, s: &mut [MaybeUninit<u8>]) -> Result<(), String> {
545 let start = self.position;
546 let end = start + s.len();
547 assert!(end <= self.data.len());
548
549 // SAFETY: Both `src` and `dst` point to at least `s.len()` elements:
550 // `src` points to at least `s.len()` elements by above assert, and
551 // `dst` points to `s.len()` elements by derivation from `s`.
552 unsafe {
553 let src = self.data.as_ptr().add(start);
554 let dst = s.as_mut_ptr() as *mut u8;
555 ptr::copy_nonoverlapping(src, dst, s.len());
556 }
557
558 self.position = end;
559
560 Ok(())
561 }
562}
563
564macro_rules! read_leb128 {
565 ($dec:expr, $fun:ident) => {{
566 let (value, bytes_read) = leb128::$fun(&$dec.data[$dec.position..]);
567 $dec.position += bytes_read;
568 Ok(value)
569 }};
570}
571
572impl<'a> serialize::Decoder for Decoder<'a> {
573 type Error = String;
574
575 #[inline]
576 fn read_nil(&mut self) -> Result<(), Self::Error> {
577 Ok(())
578 }
579
580 #[inline]
581 fn read_u128(&mut self) -> Result<u128, Self::Error> {
582 read_leb128!(self, read_u128_leb128)
583 }
584
585 #[inline]
586 fn read_u64(&mut self) -> Result<u64, Self::Error> {
587 read_leb128!(self, read_u64_leb128)
588 }
589
590 #[inline]
591 fn read_u32(&mut self) -> Result<u32, Self::Error> {
592 read_leb128!(self, read_u32_leb128)
593 }
594
595 #[inline]
596 fn read_u16(&mut self) -> Result<u16, Self::Error> {
597 read_leb128!(self, read_u16_leb128)
598 }
599
600 #[inline]
601 fn read_u8(&mut self) -> Result<u8, Self::Error> {
602 let value = self.data[self.position];
603 self.position += 1;
604 Ok(value)
605 }
606
607 #[inline]
608 fn read_usize(&mut self) -> Result<usize, Self::Error> {
609 read_leb128!(self, read_usize_leb128)
610 }
611
612 #[inline]
613 fn read_i128(&mut self) -> Result<i128, Self::Error> {
614 read_leb128!(self, read_i128_leb128)
615 }
616
617 #[inline]
618 fn read_i64(&mut self) -> Result<i64, Self::Error> {
619 read_leb128!(self, read_i64_leb128)
620 }
621
622 #[inline]
623 fn read_i32(&mut self) -> Result<i32, Self::Error> {
624 read_leb128!(self, read_i32_leb128)
625 }
626
627 #[inline]
628 fn read_i16(&mut self) -> Result<i16, Self::Error> {
629 read_leb128!(self, read_i16_leb128)
630 }
631
632 #[inline]
633 fn read_i8(&mut self) -> Result<i8, Self::Error> {
634 let as_u8 = self.data[self.position];
635 self.position += 1;
636 unsafe { Ok(::std::mem::transmute(as_u8)) }
637 }
638
639 #[inline]
640 fn read_isize(&mut self) -> Result<isize, Self::Error> {
641 read_leb128!(self, read_isize_leb128)
642 }
643
644 #[inline]
645 fn read_bool(&mut self) -> Result<bool, Self::Error> {
646 let value = self.read_u8()?;
647 Ok(value != 0)
648 }
649
650 #[inline]
651 fn read_f64(&mut self) -> Result<f64, Self::Error> {
652 let bits = self.read_u64()?;
653 Ok(f64::from_bits(bits))
654 }
655
656 #[inline]
657 fn read_f32(&mut self) -> Result<f32, Self::Error> {
658 let bits = self.read_u32()?;
659 Ok(f32::from_bits(bits))
660 }
661
662 #[inline]
663 fn read_char(&mut self) -> Result<char, Self::Error> {
664 let bits = self.read_u32()?;
665 Ok(std::char::from_u32(bits).unwrap())
666 }
667
668 #[inline]
669 fn read_str(&mut self) -> Result<Cow<'_, str>, Self::Error> {
670 let len = self.read_usize()?;
671 let s = std::str::from_utf8(&self.data[self.position..self.position + len]).unwrap();
672 self.position += len;
673 Ok(Cow::Borrowed(s))
674 }
675
676 #[inline]
677 fn error(&mut self, err: &str) -> Self::Error {
678 err.to_string()
679 }
680}
681
682// Specializations for contiguous byte sequences follow. The default implementations for slices
683// encode and decode each element individually. This isn't necessary for `u8` slices when using
684// opaque encoders and decoders, because each `u8` is unchanged by encoding and decoding.
685// Therefore, we can use more efficient implementations that process the entire sequence at once.
686
687// Specialize encoding byte slices. This specialization also applies to encoding `Vec<u8>`s, etc.,
688// since the default implementations call `encode` on their slices internally.
689impl serialize::Encodable<Encoder> for [u8] {
690 fn encode(&self, e: &mut Encoder) -> EncodeResult {
691 serialize::Encoder::emit_usize(e, self.len())?;
692 e.emit_raw_bytes(self);
693 Ok(())
694 }
695}
696
697impl serialize::Encodable<FileEncoder> for [u8] {
698 fn encode(&self, e: &mut FileEncoder) -> FileEncodeResult {
699 serialize::Encoder::emit_usize(e, self.len())?;
700 e.emit_raw_bytes(self)
701 }
702}
703
704// Specialize decoding `Vec<u8>`. This specialization also applies to decoding `Box<[u8]>`s, etc.,
705// since the default implementations call `decode` to produce a `Vec<u8>` internally.
706impl<'a> serialize::Decodable<Decoder<'a>> for Vec<u8> {
707 fn decode(d: &mut Decoder<'a>) -> Result<Self, String> {
708 let len = serialize::Decoder::read_usize(d)?;
709
710 let mut v = Vec::with_capacity(len);
711 let buf = &mut v.spare_capacity_mut()[..len];
712 d.read_raw_bytes(buf)?;
713
714 unsafe {
715 v.set_len(len);
716 }
717
718 Ok(v)
719 }
720}