1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
//! Counted I/O helpers for protocol codecs.
//!
//! These functions provide the completion guarantees of [`Read::read_exact`]
//! and [`Write::write_all`] while attaching codec metadata and byte progress to
//! any [`CodecError`] they return.
use ;
use crate;
/// Fills `buffer` from `reader` and tracks progress for codec errors.
///
/// `codec` identifies the codec performing the read. `bytes_processed` is the
/// number of bytes that codec processed before this buffer; bytes read into
/// `buffer` are added to that base when an error is reported.
///
/// Operations interrupted with [`io::ErrorKind::Interrupted`] are retried. If
/// the reader reaches the end of its input before filling `buffer`, the result
/// is a [`CodecErrorKind::UnexpectedEof`] error.
///
/// # Example
///
/// ```
/// use mcproto_codec::{
/// error::CodecKind,
/// io::read_exact_counted,
/// };
///
/// let mut input = [0x12, 0x34].as_slice();
/// let mut bytes = [0; 2];
/// read_exact_counted(&mut input, &mut bytes, CodecKind::Short, 0)?;
/// assert_eq!(bytes, [0x12, 0x34]);
///
/// # Ok::<(), mcproto_codec::error::CodecError>(())
/// ```
///
/// # Errors
///
/// Returns a [`CodecError`] if the reader reaches an unexpected end of input
/// or reports another I/O error.
///
/// [`CodecErrorKind::UnexpectedEof`]: crate::error::CodecErrorKind::UnexpectedEof
Sized>
/// Writes all of `buffer` to `writer` and tracks progress for codec errors.
///
/// `codec` identifies the codec performing the write. `bytes_processed` is the
/// number of bytes that codec processed before this buffer; bytes written from
/// `buffer` are added to that base when an error is reported.
///
/// Operations interrupted with [`io::ErrorKind::Interrupted`] are retried. A
/// successful write of zero bytes while data remains is reported as an
/// [`io::ErrorKind::WriteZero`] source error.
///
/// # Example
///
/// ```
/// use mcproto_codec::{
/// error::CodecKind,
/// io::write_all_counted,
/// };
///
/// let mut output = Vec::new();
/// write_all_counted(&mut output, &[0x12, 0x34], CodecKind::Short, 0)?;
/// assert_eq!(output, [0x12, 0x34]);
///
/// # Ok::<(), mcproto_codec::error::CodecError>(())
/// ```
///
/// # Errors
///
/// Returns a [`CodecError`] if the writer cannot accept the complete buffer.
Sized>