1use crate::message::Message;
2use bytecodec::bytes::{BytesDecoder, BytesEncoder, RemainingBytesDecoder};
3use bytecodec::combinator::{Length, Peekable};
4use bytecodec::fixnum::{U16beDecoder, U16beEncoder};
5use bytecodec::{ByteCount, Decode, Encode, Eos, ErrorKind, Result, SizedEncode, TryTaggedDecode};
6use std::fmt;
7
8use crate::{rfc5389, rfc5766};
9
10#[derive(Debug)]
11pub enum MyAttribute {
12 Rfc5389(rfc5389::Attribute),
13 Rfc5766(rfc5766::Attribute),
14}
15
16#[derive(Debug, Default)]
17pub struct MyAttributeDecoder {
18 rfc5389: rfc5389::AttributeDecoder,
19 rfc5766: rfc5766::AttributeDecoder,
20 index: usize,
21}
22impl Decode for MyAttributeDecoder {
23 type Item = MyAttribute;
24
25 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
26 match self.index {
27 1 => track!(self.rfc5389.decode(buf, eos)),
28 2 => track!(self.rfc5766.decode(buf, eos)),
29 _ => track_panic!(ErrorKind::InconsistentState),
30 }
31 }
32
33 fn finish_decoding(&mut self) -> Result<Self::Item> {
34 let item = match self.index {
35 1 => track!(self.rfc5389.finish_decoding()).map(MyAttribute::Rfc5389)?,
36 2 => track!(self.rfc5766.finish_decoding()).map(MyAttribute::Rfc5766)?,
37 _ => track_panic!(ErrorKind::InconsistentState),
38 };
39 self.index = 0;
40 Ok(item)
41 }
42
43 fn requiring_bytes(&self) -> ByteCount {
44 match self.index {
45 1 => self.rfc5389.requiring_bytes(),
46 2 => self.rfc5766.requiring_bytes(),
47 _ => ByteCount::Finite(0),
48 }
49 }
50
51 fn is_idle(&self) -> bool {
52 match self.index {
53 1 => self.rfc5389.is_idle(),
54 2 => self.rfc5766.is_idle(),
55 _ => true,
56 }
57 }
58}
59impl TryTaggedDecode for MyAttributeDecoder {
60 type Tag = AttributeType;
61
62 fn try_start_decoding(&mut self, tag: Self::Tag) -> Result<bool> {
63 track_assert_eq!(self.index, 0, ErrorKind::InconsistentState);
64 if track!(self.rfc5389.try_start_decoding(tag))? {
65 self.index = 1;
66 Ok(true)
67 } else if track!(self.rfc5766.try_start_decoding(tag))? {
68 self.index = 2;
69 Ok(true)
70 } else {
71 Ok(false)
72 }
73 }
74}
75
76#[derive(Debug, Default)]
77pub struct MyAttributeEncoder {
78 rfc5389: rfc5389::AttributeEncoder,
79 rfc5766: rfc5766::AttributeEncoder,
80}
81impl Encode for MyAttributeEncoder {
82 type Item = MyAttribute;
83
84 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
85 let mut offset = 0;
86 bytecodec_try_encode!(self.rfc5389, offset, buf, eos);
87 bytecodec_try_encode!(self.rfc5766, offset, buf, eos);
88 Ok(offset)
89 }
90
91 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
92 track_assert!(self.is_idle(), ErrorKind::EncoderFull);
93 match item {
94 MyAttribute::Rfc5389(item) => track!(self.rfc5389.start_encoding(item)),
95 MyAttribute::Rfc5766(item) => track!(self.rfc5766.start_encoding(item)),
96 }
97 }
98
99 fn requiring_bytes(&self) -> ByteCount {
100 self.rfc5389
101 .requiring_bytes()
102 .add_for_encoding(self.rfc5766.requiring_bytes())
103 }
104
105 fn is_idle(&self) -> bool {
106 self.rfc5389.is_idle() && self.rfc5766.is_idle()
107 }
108}
109impl SizedEncode for MyAttributeEncoder {
110 fn exact_requiring_bytes(&self) -> u64 {
111 self.rfc5389.exact_requiring_bytes() + self.rfc5766.exact_requiring_bytes()
112 }
113}
114
115pub trait Attribute: Sized + Clone {
129 type Decoder: Default + TryTaggedDecode<Tag = AttributeType, Item = Self>;
131
132 type Encoder: Default + SizedEncode<Item = Self>;
134
135 fn get_type(&self) -> AttributeType;
137
138 #[allow(unused_variables)]
145 fn before_encode<A: Attribute>(&mut self, message: &Message<A>) -> Result<()> {
146 Ok(())
147 }
148
149 #[allow(unused_variables)]
153 fn after_decode<A: Attribute>(&mut self, message: &Message<A>) -> Result<()> {
154 Ok(())
155 }
156}
157
158#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash)]
181pub struct AttributeType(u16);
182impl AttributeType {
183 pub fn new(codepoint: u16) -> Self {
185 AttributeType(codepoint)
186 }
187
188 pub fn as_u16(self) -> u16 {
190 self.0
191 }
192
193 pub fn is_comprehension_required(self) -> bool {
195 self.0 < 0x8000
196 }
197
198 pub fn is_comprehension_optional(self) -> bool {
200 !self.is_comprehension_required()
201 }
202}
203impl From<u16> for AttributeType {
204 fn from(f: u16) -> Self {
205 Self::new(f)
206 }
207}
208
209#[derive(Debug, Clone)]
211pub struct RawAttribute {
212 attr_type: AttributeType,
213 value: Vec<u8>,
214}
215impl RawAttribute {
216 pub fn new(attr_type: AttributeType, value: Vec<u8>) -> Self {
218 RawAttribute { attr_type, value }
219 }
220
221 pub fn value(&self) -> &[u8] {
223 &self.value
224 }
225
226 pub fn into_value(self) -> Vec<u8> {
228 self.value
229 }
230}
231impl Attribute for RawAttribute {
232 type Decoder = RawAttributeDecoder;
233 type Encoder = RawAttributeEncoder;
234
235 fn get_type(&self) -> AttributeType {
236 self.attr_type
237 }
238}
239
240#[derive(Debug, Default)]
242pub struct RawAttributeDecoder {
243 attr_type: Option<AttributeType>,
244 value: RemainingBytesDecoder,
245}
246impl RawAttributeDecoder {
247 pub fn new() -> Self {
249 Self::default()
250 }
251}
252impl Decode for RawAttributeDecoder {
253 type Item = RawAttribute;
254
255 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
256 track!(self.value.decode(buf, eos))
257 }
258
259 fn finish_decoding(&mut self) -> Result<Self::Item> {
260 let attr_type = track_assert_some!(self.attr_type.take(), ErrorKind::InconsistentState);
261 let value = track!(self.value.finish_decoding())?;
262 Ok(RawAttribute { attr_type, value })
263 }
264
265 fn requiring_bytes(&self) -> ByteCount {
266 self.value.requiring_bytes()
267 }
268
269 fn is_idle(&self) -> bool {
270 self.value.is_idle()
271 }
272}
273impl TryTaggedDecode for RawAttributeDecoder {
274 type Tag = AttributeType;
275
276 fn try_start_decoding(&mut self, attr_type: Self::Tag) -> Result<bool> {
277 self.attr_type = Some(attr_type);
278 Ok(true)
279 }
280}
281
282#[derive(Debug, Default)]
284pub struct RawAttributeEncoder {
285 value: BytesEncoder,
286}
287impl RawAttributeEncoder {
288 pub fn new() -> Self {
290 Self::default()
291 }
292}
293impl Encode for RawAttributeEncoder {
294 type Item = RawAttribute;
295
296 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
297 track!(self.value.encode(buf, eos))
298 }
299
300 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
301 track!(self.value.start_encoding(item.into_value()))
302 }
303
304 fn requiring_bytes(&self) -> ByteCount {
305 ByteCount::Finite(self.exact_requiring_bytes())
306 }
307
308 fn is_idle(&self) -> bool {
309 self.value.is_idle()
310 }
311}
312impl SizedEncode for RawAttributeEncoder {
313 fn exact_requiring_bytes(&self) -> u64 {
314 self.value.exact_requiring_bytes()
315 }
316}
317
318#[derive(Debug, Clone)]
319pub enum LosslessAttribute<T> {
320 Known {
321 inner: T,
322 padding: Option<Padding>,
323 },
324 Unknown {
325 inner: RawAttribute,
326 padding: Option<Padding>,
327 },
328}
329impl<T: Attribute> LosslessAttribute<T> {
330 pub fn new(inner: T) -> Self {
331 LosslessAttribute::Known {
332 inner,
333 padding: None,
334 }
335 }
336
337 pub fn as_known(&self) -> Option<&T> {
338 match self {
339 LosslessAttribute::Known { inner, .. } => Some(inner),
340 LosslessAttribute::Unknown { .. } => None,
341 }
342 }
343
344 pub fn as_unknown(&self) -> Option<&RawAttribute> {
345 match self {
346 LosslessAttribute::Known { .. } => None,
347 LosslessAttribute::Unknown { inner, .. } => Some(inner),
348 }
349 }
350
351 pub fn get_type(&self) -> AttributeType {
352 match self {
353 LosslessAttribute::Known { inner, .. } => inner.get_type(),
354 LosslessAttribute::Unknown { inner, .. } => inner.get_type(),
355 }
356 }
357
358 pub fn before_encode<A: Attribute>(&mut self, message: &Message<A>) -> Result<()> {
359 match self {
360 LosslessAttribute::Known { inner, .. } => inner.before_encode(message),
361 LosslessAttribute::Unknown { inner, .. } => inner.before_encode(message),
362 }
363 }
364
365 pub fn after_decode<A: Attribute>(&mut self, message: &Message<A>) -> Result<()> {
366 match self {
367 LosslessAttribute::Known { inner, .. } => inner.after_decode(message),
368 LosslessAttribute::Unknown { inner, .. } => inner.after_decode(message),
369 }
370 }
371}
372
373pub struct LosslessAttributeDecoder<T: Attribute> {
374 get_type: U16beDecoder,
375 value_len: Peekable<U16beDecoder>,
376 is_known: bool,
377 known_value: Length<T::Decoder>,
378 unknown_value: Length<RawAttributeDecoder>,
379 padding: BytesDecoder<Padding>,
380}
381impl<T: Attribute> fmt::Debug for LosslessAttributeDecoder<T> {
382 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
383 write!(f, "LosslessAttributeDecoder {{ .. }}")
384 }
385}
386impl<T: Attribute> Default for LosslessAttributeDecoder<T> {
387 fn default() -> Self {
388 LosslessAttributeDecoder {
389 get_type: Default::default(),
390 value_len: Default::default(),
391 is_known: false,
392 known_value: Default::default(),
393 unknown_value: Default::default(),
394 padding: Default::default(),
395 }
396 }
397}
398impl<T: Attribute> Decode for LosslessAttributeDecoder<T> {
399 type Item = LosslessAttribute<T>;
400
401 fn decode(&mut self, buf: &[u8], eos: Eos) -> Result<usize> {
402 let mut offset = 0;
403 if !self.value_len.is_idle() {
404 bytecodec_try_decode!(self.get_type, offset, buf, eos);
405 bytecodec_try_decode!(self.value_len, offset, buf, eos);
406
407 let attr_type = AttributeType(track!(self.get_type.finish_decoding())?);
408 let value_len = *self.value_len.peek().expect("never fails");
409
410 self.is_known = track!(self.known_value.inner_mut().try_start_decoding(attr_type))?;
411 if self.is_known {
412 track!(self.known_value.set_expected_bytes(u64::from(value_len)))?;
413 } else {
414 track!(self.unknown_value.inner_mut().try_start_decoding(attr_type))?; track!(self.unknown_value.set_expected_bytes(u64::from(value_len)))?;
416 }
417 self.padding.set_bytes(Padding::new(value_len as usize));
418 }
419 if self.is_known {
420 bytecodec_try_decode!(self.known_value, offset, buf, eos);
421 } else {
422 bytecodec_try_decode!(self.unknown_value, offset, buf, eos);
423 }
424 bytecodec_try_decode!(self.padding, offset, buf, eos);
425 Ok(offset)
426 }
427
428 fn finish_decoding(&mut self) -> Result<Self::Item> {
429 let _ = track!(self.value_len.finish_decoding())?;
430 let padding = track!(self.padding.finish_decoding())?;
431 if self.is_known {
432 let value = track!(self.known_value.finish_decoding())?;
433 Ok(LosslessAttribute::Known {
434 inner: value,
435 padding: Some(padding),
436 })
437 } else {
438 let value = track!(self.unknown_value.finish_decoding())?;
439 Ok(LosslessAttribute::Unknown {
440 inner: value,
441 padding: Some(padding),
442 })
443 }
444 }
445
446 fn requiring_bytes(&self) -> ByteCount {
447 if self.value_len.is_idle() {
448 if self.is_known {
449 self.known_value
450 .requiring_bytes()
451 .add_for_decoding(self.padding.requiring_bytes())
452 } else {
453 self.unknown_value
454 .requiring_bytes()
455 .add_for_decoding(self.padding.requiring_bytes())
456 }
457 } else {
458 self.get_type
459 .requiring_bytes()
460 .add_for_decoding(self.value_len.requiring_bytes())
461 }
462 }
463
464 fn is_idle(&self) -> bool {
465 self.value_len.is_idle()
466 && if self.is_known {
467 self.known_value.is_idle()
468 } else {
469 self.unknown_value.is_idle()
470 }
471 && self.padding.is_idle()
472 }
473}
474
475pub struct LosslessAttributeEncoder<T: Attribute> {
476 get_type: U16beEncoder,
477 value_len: U16beEncoder,
478 known_value: T::Encoder,
479 unknown_value: RawAttributeEncoder,
480 padding: BytesEncoder<Padding>,
481}
482impl<T: Attribute> fmt::Debug for LosslessAttributeEncoder<T> {
483 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
484 write!(f, "LosslessAttributeEncoder {{ .. }}")
485 }
486}
487impl<T: Attribute> Default for LosslessAttributeEncoder<T> {
488 fn default() -> Self {
489 LosslessAttributeEncoder {
490 get_type: Default::default(),
491 value_len: Default::default(),
492 known_value: Default::default(),
493 unknown_value: Default::default(),
494 padding: Default::default(),
495 }
496 }
497}
498impl<T: Attribute> Encode for LosslessAttributeEncoder<T> {
499 type Item = LosslessAttribute<T>;
500
501 fn encode(&mut self, buf: &mut [u8], eos: Eos) -> Result<usize> {
502 let mut offset = 0;
503 bytecodec_try_encode!(self.get_type, offset, buf, eos);
504 bytecodec_try_encode!(self.value_len, offset, buf, eos);
505 bytecodec_try_encode!(self.known_value, offset, buf, eos);
506 bytecodec_try_encode!(self.unknown_value, offset, buf, eos);
507 bytecodec_try_encode!(self.padding, offset, buf, eos);
508 Ok(offset)
509 }
510
511 fn start_encoding(&mut self, item: Self::Item) -> Result<()> {
512 track!(self.get_type.start_encoding(item.get_type().as_u16()))?;
513 let padding = match item {
514 LosslessAttribute::Known { inner, padding } => {
515 track!(self.known_value.start_encoding(inner))?;
516 padding
517 }
518 LosslessAttribute::Unknown { inner, padding } => {
519 track!(self.unknown_value.start_encoding(inner))?;
520 padding
521 }
522 };
523
524 let value_len =
525 self.known_value.exact_requiring_bytes() + self.unknown_value.exact_requiring_bytes();
526 track_assert!(value_len < 0x10000, ErrorKind::InvalidInput; value_len);
527
528 let padding = padding.unwrap_or_else(|| Padding::new(value_len as usize));
529 track!(self.value_len.start_encoding(value_len as u16))?;
530 track!(self.padding.start_encoding(padding))?;
531 Ok(())
532 }
533
534 fn requiring_bytes(&self) -> ByteCount {
535 ByteCount::Finite(self.exact_requiring_bytes())
536 }
537
538 fn is_idle(&self) -> bool {
539 self.value_len.is_idle()
540 && self.known_value.is_idle()
541 && self.unknown_value.is_idle()
542 && self.padding.is_idle()
543 }
544}
545impl<T: Attribute> SizedEncode for LosslessAttributeEncoder<T> {
546 fn exact_requiring_bytes(&self) -> u64 {
547 self.get_type.exact_requiring_bytes()
548 + self.value_len.exact_requiring_bytes()
549 + self.known_value.exact_requiring_bytes()
550 + self.unknown_value.exact_requiring_bytes()
551 + self.padding.exact_requiring_bytes()
552 }
553}
554
555#[derive(Default, Clone)]
556pub struct Padding {
557 buf: [u8; 3],
558 len: usize,
559}
560impl Padding {
561 fn new(value_len: usize) -> Self {
562 let len = (4 - value_len % 4) % 4;
563 Padding { buf: [0; 3], len }
564 }
565}
566impl fmt::Debug for Padding {
567 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
568 write!(f, "Padding({:?})", self.as_ref())
569 }
570}
571impl AsRef<[u8]> for Padding {
572 fn as_ref(&self) -> &[u8] {
573 &self.buf[..self.len]
574 }
575}
576impl AsMut<[u8]> for Padding {
577 fn as_mut(&mut self) -> &mut [u8] {
578 &mut self.buf[..self.len]
579 }
580}