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