1use super::super::cmp::CanonicalOrd;
7use super::super::wire::{FormError, ParseError};
8use super::absolute::Name;
9use super::label::{Label, LabelTypeError};
10use super::relative::RelativeName;
11use super::traits::{FlattenInto, ToLabelIter, ToName};
12use core::{cmp, fmt, hash};
13use octseq::builder::{
14 BuilderAppendError, EmptyBuilder, FreezeBuilder, FromBuilder,
15 OctetsBuilder,
16};
17use octseq::octets::Octets;
18use octseq::parse::Parser;
19
20#[derive(Clone, Copy)]
50pub struct ParsedName<Octs> {
51 octets: Octs,
56
57 pos: usize,
59
60 name_len: u16,
64
65 compressed: bool,
69}
70
71impl<Octs> ParsedName<Octs> {
72 pub fn is_compressed(&self) -> bool {
74 self.compressed
75 }
76
77 pub fn is_root(&self) -> bool {
79 self.name_len == 1
80 }
81
82 fn parser(&self) -> Parser<Octs>
84 where
85 Octs: AsRef<[u8]>,
86 {
87 let mut res = Parser::from_ref(&self.octets);
88 res.advance(self.pos).expect("illegal pos in ParsedName");
89 res
90 }
91
92 pub fn ref_octets(&self) -> ParsedName<&Octs> {
94 ParsedName {
95 octets: &self.octets,
96 pos: self.pos,
97 name_len: self.name_len,
98 compressed: self.compressed,
99 }
100 }
101}
102
103impl<'a, Octs: Octets + ?Sized> ParsedName<&'a Octs> {
104 #[must_use]
105 pub fn deref_octets(&self) -> ParsedName<Octs::Range<'a>> {
106 ParsedName {
107 octets: self.octets.range(..),
108 pos: self.pos,
109 name_len: self.name_len,
110 compressed: self.compressed,
111 }
112 }
113}
114
115impl<Octs: AsRef<[u8]>> ParsedName<Octs> {
118 pub fn iter(&self) -> ParsedNameIter {
120 ParsedNameIter::new(self.octets.as_ref(), self.pos, self.name_len)
121 }
122
123 pub fn iter_suffixes(&self) -> ParsedSuffixIter<Octs> {
129 ParsedSuffixIter::new(self)
130 }
131
132 pub fn label_count(&self) -> usize {
134 self.iter().count()
135 }
136
137 pub fn first(&self) -> &Label {
139 self.iter().next().unwrap()
140 }
141
142 pub fn last(&self) -> &'static Label {
148 Label::root()
149 }
150
151 pub fn starts_with<N: ToLabelIter>(&self, base: &N) -> bool {
153 <Self as ToLabelIter>::starts_with(self, base)
154 }
155
156 pub fn ends_with<N: ToLabelIter>(&self, base: &N) -> bool {
158 <Self as ToLabelIter>::ends_with(self, base)
159 }
160
161 pub fn split_first(&mut self) -> Option<RelativeName<Octs::Range<'_>>>
167 where
168 Octs: Octets,
169 {
170 if self.name_len == 1 {
171 return None;
172 }
173 let mut name_len = self.name_len;
174 let range = {
175 let mut parser = self.parser();
176 let len = loop {
177 match LabelType::peek(&parser).unwrap() {
178 LabelType::Normal(0) => {
179 unreachable!()
180 }
181 LabelType::Normal(label_len) => break label_len + 1,
182 LabelType::Compressed(pos) => {
183 parser.seek(pos).unwrap();
184 }
185 }
186 };
187 name_len -= len;
188 parser.pos()..parser.pos() + usize::from(len)
189 };
190 self.pos = range.end;
191 self.name_len = name_len;
192 Some(unsafe {
193 RelativeName::from_octets_unchecked(self.octets.range(range))
194 })
195 }
196
197 pub fn parent(&mut self) -> bool {
202 if self.name_len == 1 {
203 return false;
204 }
205 let (pos, len) = {
206 let mut parser = self.parser();
207 let len = loop {
208 match LabelType::peek(&parser).unwrap() {
209 LabelType::Normal(0) => {
210 unreachable!()
211 }
212 LabelType::Normal(label_len) => break label_len + 1,
213 LabelType::Compressed(pos) => {
214 parser.seek(pos).unwrap();
215 }
216 }
217 };
218 (parser.pos() + usize::from(len), len)
219 };
220 self.name_len -= len;
221 self.pos = pos;
222 true
223 }
224}
225
226impl<Octs> ParsedName<Octs> {
227 pub fn parse<'a, Src: Octets<Range<'a> = Octs> + ?Sized>(
228 parser: &mut Parser<'a, Src>,
229 ) -> Result<Self, ParseError> {
230 ParsedName::parse_ref(parser).map(|res| res.deref_octets())
231 }
232}
233
234impl<'a, Octs: AsRef<[u8]> + ?Sized> ParsedName<&'a Octs> {
235 pub fn parse_ref(
236 parser: &mut Parser<'a, Octs>,
237 ) -> Result<Self, ParseError> {
238 let mut name_len = 0;
239 let mut pos = parser.pos();
240
241 let mut ptr = loop {
246 match LabelType::parse(parser)? {
247 LabelType::Normal(0) => {
248 name_len += 1;
250 return Ok(ParsedName {
251 octets: parser.octets_ref(),
252 pos,
253 name_len,
254 compressed: false,
255 });
256 }
257 LabelType::Normal(label_len) => {
258 parser.advance(usize::from(label_len))?;
259 name_len += label_len + 1;
260 if name_len >= 255 {
261 return Err(ParsedDnameError::LongName.into());
262 }
263 }
264 LabelType::Compressed(ptr) => {
265 break ptr;
266 }
267 }
268 };
269
270 let mut parser = *parser;
280 let mut compressed = true;
281 loop {
282 if ptr >= parser.pos() - 2 {
287 return Err(ParsedDnameError::ExcessiveCompression.into());
288 }
289
290 if name_len == 0 {
293 pos = ptr;
294 compressed = false;
295 }
296
297 parser.seek(ptr)?;
299
300 loop {
301 match LabelType::parse(&mut parser)? {
302 LabelType::Normal(0) => {
303 name_len += 1;
305 return Ok(ParsedName {
306 octets: parser.octets_ref(),
307 pos,
308 name_len,
309 compressed,
310 });
311 }
312 LabelType::Normal(label_len) => {
313 parser.advance(usize::from(label_len))?;
314 name_len += label_len + 1;
315 if name_len >= 255 {
316 return Err(ParsedDnameError::LongName.into());
317 }
318 }
319 LabelType::Compressed(new_ptr) => {
320 ptr = new_ptr;
321 compressed = true;
322 break;
323 }
324 }
325 }
326 }
327 }
328}
329
330impl ParsedName<()> {
331 pub fn skip<Src: AsRef<[u8]> + ?Sized>(
340 parser: &mut Parser<Src>,
341 ) -> Result<(), ParseError> {
342 let mut len = 0;
343 loop {
344 match LabelType::parse(parser) {
345 Ok(LabelType::Normal(0)) => {
346 len += 1;
347 if len > 255 {
348 return Err(ParsedDnameError::LongName.into());
349 }
350 return Ok(());
351 }
352 Ok(LabelType::Normal(label_len)) => {
353 parser.advance(label_len.into())?;
354 len += label_len + 1;
355 if len > 255 {
356 return Err(ParsedDnameError::LongName.into());
357 }
358 }
359 Ok(LabelType::Compressed(_)) => return Ok(()),
360 Err(err) => return Err(err),
361 }
362 }
363 }
364}
365
366impl<Octs: AsRef<[u8]>> From<Name<Octs>> for ParsedName<Octs> {
369 fn from(name: Name<Octs>) -> ParsedName<Octs> {
370 let name_len = name.compose_len();
371 ParsedName {
372 octets: name.into_octets(),
373 pos: 0,
374 name_len,
375 compressed: false,
376 }
377 }
378}
379
380impl<Octs, Target> FlattenInto<Name<Target>> for ParsedName<Octs>
383where
384 Octs: Octets,
385 Target: FromBuilder,
386 <Target as FromBuilder>::Builder: EmptyBuilder,
387{
388 type AppendError = BuilderAppendError<Target>;
389
390 fn try_flatten_into(self) -> Result<Name<Target>, Self::AppendError> {
391 let mut builder =
392 Target::Builder::with_capacity(self.compose_len().into());
393 if let Some(slice) = self.as_flat_slice() {
394 builder.append_slice(slice)?;
395 } else {
396 self.iter_labels()
397 .try_for_each(|label| label.compose(&mut builder))?;
398 }
399 Ok(unsafe { Name::from_octets_unchecked(builder.freeze()) })
400 }
401}
402
403impl<Octs, N> PartialEq<N> for ParsedName<Octs>
406where
407 Octs: AsRef<[u8]>,
408 N: ToName + ?Sized,
409{
410 fn eq(&self, other: &N) -> bool {
411 self.name_eq(other)
412 }
413}
414
415impl<Octs: AsRef<[u8]>> Eq for ParsedName<Octs> {}
416
417impl<Octs, N> PartialOrd<N> for ParsedName<Octs>
420where
421 Octs: AsRef<[u8]>,
422 N: ToName + ?Sized,
423{
424 fn partial_cmp(&self, other: &N) -> Option<cmp::Ordering> {
425 Some(self.name_cmp(other))
426 }
427}
428
429impl<Octs: AsRef<[u8]>> Ord for ParsedName<Octs> {
430 fn cmp(&self, other: &Self) -> cmp::Ordering {
431 self.name_cmp(other)
432 }
433}
434
435impl<Octs, N> CanonicalOrd<N> for ParsedName<Octs>
436where
437 Octs: AsRef<[u8]>,
438 N: ToName + ?Sized,
439{
440 fn canonical_cmp(&self, other: &N) -> cmp::Ordering {
441 self.name_cmp(other)
442 }
443}
444
445impl<Octs: AsRef<[u8]>> hash::Hash for ParsedName<Octs> {
448 fn hash<H: hash::Hasher>(&self, state: &mut H) {
449 for item in self.iter() {
450 item.hash(state)
451 }
452 }
453}
454
455impl<Octs: AsRef<[u8]>> ToLabelIter for ParsedName<Octs> {
458 type LabelIter<'s>
459 = ParsedNameIter<'s>
460 where
461 Octs: 's;
462
463 fn iter_labels(&self) -> Self::LabelIter<'_> {
464 self.iter()
465 }
466
467 fn compose_len(&self) -> u16 {
468 self.name_len
469 }
470}
471
472impl<Octs: AsRef<[u8]>> ToName for ParsedName<Octs> {
473 fn as_flat_slice(&self) -> Option<&[u8]> {
474 if self.compressed {
475 None
476 } else {
477 Some(
478 &self.octets.as_ref()
479 [self.pos..self.pos + usize::from(self.name_len)],
480 )
481 }
482 }
483}
484
485impl<'a, Octs> IntoIterator for &'a ParsedName<Octs>
488where
489 Octs: AsRef<[u8]>,
490{
491 type Item = &'a Label;
492 type IntoIter = ParsedNameIter<'a>;
493
494 fn into_iter(self) -> Self::IntoIter {
495 self.iter()
496 }
497}
498
499impl<Octs: AsRef<[u8]>> fmt::Display for ParsedName<Octs> {
502 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
507 let mut iter = self.iter();
508 write!(f, "{}", iter.next().unwrap())?;
509 for label in iter {
510 if !label.is_root() {
511 write!(f, ".{}", label)?
512 }
513 }
514 Ok(())
515 }
516}
517
518impl<Octs: AsRef<[u8]>> fmt::Debug for ParsedName<Octs> {
519 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
520 write!(f, "ParsedName({}.)", self)
521 }
522}
523
524#[cfg(feature = "serde")]
527impl<Octs: AsRef<[u8]>> serde::Serialize for ParsedName<Octs> {
528 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
529 where
530 S: serde::Serializer,
531 {
532 serializer.collect_str(self)
533 }
534}
535
536#[derive(Clone)]
540pub struct ParsedNameIter<'a> {
541 slice: &'a [u8],
542 pos: usize,
543 len: u16,
544}
545
546impl<'a> ParsedNameIter<'a> {
547 pub(crate) fn new(slice: &'a [u8], pos: usize, len: u16) -> Self {
551 ParsedNameIter { slice, pos, len }
552 }
553
554 fn get_label(&mut self) -> &'a Label {
561 let end = loop {
562 let ltype = self.slice[self.pos];
563 self.pos += 1;
564 match ltype {
565 0..=0x3F => break self.pos + (ltype as usize),
566 0xC0..=0xFF => {
567 self.pos = (self.slice[self.pos] as usize)
568 | (((ltype as usize) & 0x3F) << 8);
569 }
570 _ => panic!("bad label"),
571 }
572 };
573 let res = unsafe {
574 Label::from_slice_unchecked(&self.slice[self.pos..end])
575 };
576 self.pos = end;
577 self.len -= res.compose_len();
578 res
579 }
580}
581
582impl<'a> Iterator for ParsedNameIter<'a> {
583 type Item = &'a Label;
584
585 fn next(&mut self) -> Option<&'a Label> {
586 if self.len == 0 {
587 return None;
588 }
589 Some(self.get_label())
590 }
591}
592
593impl<'a> DoubleEndedIterator for ParsedNameIter<'a> {
594 fn next_back(&mut self) -> Option<&'a Label> {
595 if self.len == 0 {
596 return None;
597 }
598 let mut tmp = self.clone();
599 let label = loop {
600 let label = tmp.get_label();
601 if tmp.len == 0 {
602 break label;
603 }
604 };
605 self.len -= label.compose_len();
606 Some(label)
607 }
608}
609
610#[derive(Clone)]
614pub struct ParsedSuffixIter<'a, Octs: ?Sized> {
615 name: Option<ParsedName<&'a Octs>>,
616}
617
618impl<'a, Octs> ParsedSuffixIter<'a, Octs> {
619 fn new(name: &'a ParsedName<Octs>) -> Self {
621 ParsedSuffixIter {
622 name: Some(name.ref_octets()),
623 }
624 }
625}
626
627impl<'a, Octs: Octets + ?Sized> Iterator for ParsedSuffixIter<'a, Octs> {
628 type Item = ParsedName<Octs::Range<'a>>;
629
630 fn next(&mut self) -> Option<Self::Item> {
631 let name = match self.name {
632 Some(ref mut name) => name,
633 None => return None,
634 };
635 let res = name.deref_octets();
636 if !name.parent() {
637 self.name = None
638 }
639 Some(res)
640 }
641}
642
643#[derive(Clone, Copy, Debug, Eq, PartialEq)]
647enum LabelType {
648 Normal(u16),
650
651 Compressed(usize),
653}
654
655impl LabelType {
656 pub fn parse<Octs: AsRef<[u8]> + ?Sized>(
658 parser: &mut Parser<Octs>,
659 ) -> Result<Self, ParseError> {
660 let ltype = parser.parse_u8()?;
661 match ltype {
662 0..=0x3F => Ok(LabelType::Normal(ltype.into())),
663 0xC0..=0xFF => {
664 let res = usize::from(parser.parse_u8()?);
665 let res = res | ((usize::from(ltype) & 0x3F) << 8);
666 Ok(LabelType::Compressed(res))
667 }
668 _ => Err(ParseError::Form(FormError::new("invalid label type"))),
669 }
670 }
671
672 pub fn peek<Ref: AsRef<[u8]> + ?Sized>(
674 parser: &Parser<Ref>,
675 ) -> Result<Self, ParseError> {
676 let ltype = parser.peek(1)?[0];
677 match ltype {
678 0..=0x3F => Ok(LabelType::Normal(ltype.into())),
679 0xC0..=0xFF => {
680 let res = usize::from(parser.peek(2)?[1]);
681 let res = res | ((usize::from(ltype) & 0x3F) << 8);
682 Ok(LabelType::Compressed(res))
683 }
684 _ => Err(ParseError::Form(FormError::new("invalid label type"))),
685 }
686 }
687}
688
689#[derive(Clone, Copy, Debug, Eq, PartialEq)]
696enum ParsedDnameError {
697 BadLabel(LabelTypeError),
699
700 LongName,
702
703 ExcessiveCompression,
705}
706
707impl fmt::Display for ParsedDnameError {
708 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
709 FormError::from(*self).fmt(f)
710 }
711}
712
713#[cfg(feature = "std")]
714impl std::error::Error for ParsedDnameError {}
715
716impl From<LabelTypeError> for ParsedDnameError {
717 fn from(err: LabelTypeError) -> Self {
718 ParsedDnameError::BadLabel(err)
719 }
720}
721
722impl From<ParsedDnameError> for FormError {
723 fn from(err: ParsedDnameError) -> FormError {
724 match err {
725 ParsedDnameError::BadLabel(_) => {
726 FormError::new("invalid label type")
727 }
728 ParsedDnameError::LongName => FormError::new("long domain name"),
729 ParsedDnameError::ExcessiveCompression => {
730 FormError::new("too many compression pointers")
731 }
732 }
733 }
734}
735
736impl From<ParsedDnameError> for ParseError {
737 fn from(err: ParsedDnameError) -> ParseError {
738 ParseError::Form(err.into())
739 }
740}
741
742#[cfg(test)]
745mod test {
746 use super::*;
747
748 macro_rules! name {
749 (root) => {
750 name!(b"123\0", 3, 1, false)
751 };
752 (flat) => {
753 name!(b"\x03www\x07example\x03com\0\xc0\0", 0, 17, false)
754 };
755 (copy) => {
756 name!(b"\x03www\x07example\x03com\0\xc0\0", 17, 17, false)
757 };
758 (once) => {
759 name!(b"\x03com\0\x03www\x07example\xC0\0", 5, 17, true)
760 };
761 (twice) => {
762 name!(b"\x03com\0\x07example\xc0\0\x03www\xc0\x05", 15, 17, true)
763 };
764
765 ($bytes:expr, $start:expr, $len:expr, $compressed:expr) => {{
766 let mut parser = Parser::from_ref($bytes.as_ref());
767 parser.advance($start).unwrap();
768 ParsedName {
769 octets: $bytes.as_ref(),
770 pos: $start,
771 name_len: $len,
772 compressed: $compressed,
773 }
774 }};
775 }
776
777 static WECR: &[u8] = b"\x03www\x07example\x03com\0";
778
779 #[test]
780 fn len() {
781 assert_eq!(name!(root).compose_len(), 1);
782 assert_eq!(name!(flat).compose_len(), 17);
783 assert_eq!(name!(once).compose_len(), 17);
784 assert_eq!(name!(twice).compose_len(), 17);
785 }
786
787 #[test]
788 fn is_compressed() {
789 assert!(!name!(root).is_compressed());
790 assert!(!name!(flat).is_compressed());
791 assert!(name!(once).is_compressed());
792 assert!(name!(twice).is_compressed());
793 }
794
795 #[test]
796 fn is_root() {
797 assert!(name!(root).is_root());
798 assert!(!name!(flat).is_root());
799 assert!(!name!(once).is_root());
800 assert!(!name!(twice).is_root());
801 }
802
803 #[test]
804 fn iter() {
805 use crate::base::name::absolute::test::cmp_iter;
806
807 let labels: &[&[u8]] = &[b"www", b"example", b"com", b""];
808 cmp_iter(name!(root).iter(), &[b""]);
809 cmp_iter(name!(flat).iter(), labels);
810 cmp_iter(name!(once).iter(), labels);
811 cmp_iter(name!(twice).iter(), labels);
812 }
813
814 #[test]
815 fn iter_back() {
816 use crate::base::name::absolute::test::cmp_iter_back;
817
818 let labels: &[&[u8]] = &[b"", b"com", b"example", b"www"];
819 cmp_iter_back(name!(root).iter(), &[b""]);
820 cmp_iter_back(name!(flat).iter(), labels);
821 cmp_iter_back(name!(once).iter(), labels);
822 cmp_iter_back(name!(twice).iter(), labels);
823 }
824
825 fn cmp_iter_suffixes<'a, I>(iter: I, labels: &[&[u8]])
826 where
827 I: Iterator<Item = ParsedName<&'a [u8]>>,
828 {
829 for (name, labels) in iter.zip(labels) {
830 let mut iter = name.iter();
831 let labels = Name::from_slice(labels).unwrap();
832 let mut labels_iter = labels.iter();
833 loop {
834 match (iter.next(), labels_iter.next()) {
835 (Some(left), Some(right)) => assert_eq!(left, right),
836 (None, None) => break,
837 (_, None) => panic!("extra items in iterator"),
838 (None, _) => panic!("missing items in iterator"),
839 }
840 }
841 }
842 }
843
844 #[test]
845 fn iter_suffixes() {
846 let suffixes: &[&[u8]] = &[
847 b"\x03www\x07example\x03com\0",
848 b"\x07example\x03com\0",
849 b"\x03com\0",
850 b"\0",
851 ];
852 cmp_iter_suffixes(name!(root).iter_suffixes(), &[b"\0"]);
853 cmp_iter_suffixes(name!(flat).iter_suffixes(), suffixes);
854 cmp_iter_suffixes(name!(once).iter_suffixes(), suffixes);
855 cmp_iter_suffixes(name!(twice).iter_suffixes(), suffixes);
856 }
857
858 #[test]
859 fn label_count() {
860 assert_eq!(name!(root).label_count(), 1);
861 assert_eq!(name!(flat).label_count(), 4);
862 assert_eq!(name!(once).label_count(), 4);
863 assert_eq!(name!(twice).label_count(), 4);
864 }
865
866 #[test]
867 fn first() {
868 assert_eq!(name!(root).first().as_slice(), b"");
869 assert_eq!(name!(flat).first().as_slice(), b"www");
870 assert_eq!(name!(once).first().as_slice(), b"www");
871 assert_eq!(name!(twice).first().as_slice(), b"www");
872 }
873
874 #[test]
875 fn starts_with() {
876 let root = name!(root);
877 let flat_wec = name!(flat);
878 let once_wec = name!(once);
879 let twice_wec = name!(twice);
880
881 let test = Name::root_ref();
882 assert!(root.starts_with(&test));
883 assert!(!flat_wec.starts_with(&test));
884 assert!(!once_wec.starts_with(&test));
885 assert!(!twice_wec.starts_with(&test));
886
887 let test = RelativeName::empty_ref();
888 assert!(root.starts_with(&test));
889 assert!(flat_wec.starts_with(&test));
890 assert!(once_wec.starts_with(&test));
891 assert!(twice_wec.starts_with(&test));
892
893 let test = RelativeName::from_slice(b"\x03www").unwrap();
894 assert!(!root.starts_with(&test));
895 assert!(flat_wec.starts_with(&test));
896 assert!(once_wec.starts_with(&test));
897 assert!(twice_wec.starts_with(&test));
898
899 let test = RelativeName::from_slice(b"\x03www\x07example").unwrap();
900 assert!(!root.starts_with(&test));
901 assert!(flat_wec.starts_with(&test));
902 assert!(once_wec.starts_with(&test));
903 assert!(twice_wec.starts_with(&test));
904
905 let test =
906 RelativeName::from_slice(b"\x03www\x07example\x03com").unwrap();
907 assert!(!root.starts_with(&test));
908 assert!(flat_wec.starts_with(&test));
909 assert!(once_wec.starts_with(&test));
910 assert!(twice_wec.starts_with(&test));
911
912 let test = Name::from_slice(b"\x03www\x07example\x03com\0").unwrap();
913 assert!(!root.starts_with(&test));
914 assert!(flat_wec.starts_with(&test));
915 assert!(once_wec.starts_with(&test));
916 assert!(twice_wec.starts_with(&test));
917
918 let test = RelativeName::from_slice(b"\x07example\x03com").unwrap();
919 assert!(!root.starts_with(&test));
920 assert!(!flat_wec.starts_with(&test));
921 assert!(!once_wec.starts_with(&test));
922 assert!(!twice_wec.starts_with(&test));
923
924 let test = RelativeName::from_octets(b"\x03www".as_ref())
925 .unwrap()
926 .chain(
927 RelativeName::from_octets(b"\x07example".as_ref()).unwrap(),
928 )
929 .unwrap();
930 assert!(!root.starts_with(&test));
931 assert!(flat_wec.starts_with(&test));
932 assert!(once_wec.starts_with(&test));
933 assert!(twice_wec.starts_with(&test));
934
935 let test = test
936 .chain(RelativeName::from_octets(b"\x03com".as_ref()).unwrap())
937 .unwrap();
938 assert!(!root.starts_with(&test));
939 assert!(flat_wec.starts_with(&test));
940 assert!(once_wec.starts_with(&test));
941 assert!(twice_wec.starts_with(&test));
942 }
943
944 #[test]
945 fn ends_with() {
946 let root = name!(root);
947 let flat_wec = name!(flat);
948 let once_wec = name!(once);
949 let twice_wec = name!(twice);
950 let wecr = Name::from_octets(b"\x03www\x07example\x03com\0".as_ref())
951 .unwrap();
952
953 for name in wecr.iter_suffixes() {
954 if name.is_root() {
955 assert!(root.ends_with(&name))
956 } else {
957 assert!(!root.ends_with(&name))
958 }
959 assert!(flat_wec.ends_with(&name));
960 assert!(once_wec.ends_with(&name));
961 assert!(twice_wec.ends_with(&name));
962 }
963 }
964
965 #[test]
966 #[cfg(feature = "std")]
967 fn split_first() {
968 fn split_first_wec(mut name: ParsedName<&[u8]>) {
969 assert_eq!(
970 name.to_vec().as_slice(),
971 b"\x03www\x07example\x03com\0"
972 );
973 assert_eq!(
974 name.split_first().unwrap().as_slice(),
975 b"\x03www".as_ref()
976 );
977 assert_eq!(name.to_vec().as_slice(), b"\x07example\x03com\0");
978 assert_eq!(
979 name.split_first().unwrap().as_slice(),
980 b"\x07example".as_ref()
981 );
982 assert_eq!(name.to_vec().as_slice(), b"\x03com\0");
983 assert_eq!(
984 name.split_first().unwrap().as_slice(),
985 b"\x03com".as_ref()
986 );
987 assert_eq!(name.to_vec().as_slice(), b"\0");
988 assert_eq!(name.split_first(), None);
989 assert_eq!(name.split_first(), None);
990 }
991
992 split_first_wec(name!(flat));
993 split_first_wec(name!(once));
994 split_first_wec(name!(twice));
995 }
996
997 #[test]
998 #[cfg(feature = "std")]
999 fn parent() {
1000 fn parent_wec(mut name: ParsedName<&[u8]>) {
1001 assert_eq!(
1002 name.to_vec().as_slice(),
1003 b"\x03www\x07example\x03com\0"
1004 );
1005 assert!(name.parent());
1006 assert_eq!(name.to_vec().as_slice(), b"\x07example\x03com\0");
1007 assert!(name.parent());
1008 assert_eq!(name.to_vec().as_slice(), b"\x03com\0");
1009 assert!(name.parent());
1010 assert_eq!(name.to_vec().as_slice(), b"\0");
1011 assert!(!name.parent());
1012 assert!(!name.parent());
1013 }
1014
1015 parent_wec(name!(flat));
1016 parent_wec(name!(once));
1017 parent_wec(name!(twice));
1018 }
1019
1020 #[test]
1021 #[cfg(feature = "std")]
1022 fn parse_and_skip() {
1023 use std::vec::Vec;
1024
1025 fn name_eq(parsed: ParsedName<&[u8]>, name: ParsedName<&[u8]>) {
1026 assert_eq!(parsed.octets, name.octets);
1027 assert_eq!(parsed.pos, name.pos);
1028 assert_eq!(parsed.name_len, name.name_len);
1029 assert_eq!(parsed.compressed, name.compressed);
1030 }
1031
1032 fn parse(
1033 mut parser: Parser<&[u8]>,
1034 equals: ParsedName<&[u8]>,
1035 compose_len: usize,
1036 ) {
1037 let end = parser.pos() + compose_len;
1038 name_eq(ParsedName::parse(&mut parser).unwrap(), equals);
1039 assert_eq!(parser.pos(), end);
1040 }
1041
1042 fn skip(name: ParsedName<&[u8]>, len: usize) {
1043 let mut parser = name.parser();
1044 let pos = parser.pos();
1045 assert_eq!(ParsedName::skip(&mut parser), Ok(()));
1046 assert_eq!(parser.pos(), pos + len);
1047 }
1048
1049 fn p(slice: &[u8], pos: usize) -> Parser<[u8]> {
1050 let mut res = Parser::from_ref(slice);
1051 res.advance(pos).unwrap();
1052 res
1053 }
1054
1055 parse(name!(root).parser(), name!(root), 1);
1057 parse(name!(flat).parser(), name!(flat), 17);
1058 parse(name!(copy).parser(), name!(flat), 2);
1059 parse(name!(once).parser(), name!(once), 14);
1060 parse(name!(twice).parser(), name!(twice), 6);
1061 skip(name!(root), 1);
1062 skip(name!(flat), 17);
1063 skip(name!(copy), 2);
1064 skip(name!(once), 14);
1065 skip(name!(twice), 6);
1066
1067 let mut parser = p(b"\x03www\x07exam", 0);
1069 assert_eq!(
1070 ParsedName::parse(&mut parser.clone()),
1071 Err(ParseError::ShortInput)
1072 );
1073 assert_eq!(
1074 ParsedName::skip(&mut parser),
1075 Err(ParseError::ShortInput)
1076 );
1077
1078 let mut parser = p(b"\x03www\x07example", 0);
1080 assert_eq!(
1081 ParsedName::parse(&mut parser.clone()),
1082 Err(ParseError::ShortInput)
1083 );
1084 assert_eq!(
1085 ParsedName::skip(&mut parser),
1086 Err(ParseError::ShortInput)
1087 );
1088
1089 let mut parser = p(b"\x03www\xc0\xee12", 0);
1091 assert!(ParsedName::parse(&mut parser.clone()).is_err());
1092 assert_eq!(ParsedName::skip(&mut parser), Ok(()));
1093 assert_eq!(parser.remaining(), 2);
1094
1095 assert!(ParsedName::parse(&mut p(b"\x03www\xc0\x0412", 4)).is_err());
1097
1098 assert!(ParsedName::parse(&mut p(b"\x03www\xc0\x0612", 4)).is_err());
1100
1101 let mut parser = p(b"\x03www\x07example\xbffoo", 0);
1103 assert!(ParsedName::parse(&mut parser.clone()).is_err());
1104 assert!(ParsedName::skip(&mut parser).is_err());
1105
1106 let mut buf = Vec::from(&b"\x03123\0"[..]);
1108 for _ in 0..25 {
1109 buf.extend_from_slice(b"\x09123456789");
1110 }
1111 buf.extend_from_slice(b"\xc0\x0012");
1112 let mut parser = Parser::from_ref(buf.as_slice());
1113 parser.advance(5).unwrap();
1114 let name = ParsedName::parse(&mut parser.clone()).unwrap();
1115 assert_eq!(name.compose_len(), 255);
1116 assert_eq!(ParsedName::skip(&mut parser), Ok(()));
1117 assert_eq!(parser.remaining(), 2);
1118
1119 let mut buf = Vec::from(&b"\x041234\x00"[..]);
1121 for _ in 0..25 {
1122 buf.extend_from_slice(b"\x09123456789");
1123 }
1124 buf.extend_from_slice(b"\xc0\x0012");
1125 let mut parser = Parser::from_ref(buf.as_slice());
1126 parser.advance(6).unwrap();
1127 assert!(ParsedName::parse(&mut parser.clone()).is_err());
1128 assert_eq!(ParsedName::skip(&mut parser), Ok(()));
1129 assert_eq!(parser.remaining(), 2);
1130
1131 let mut parser = p(b"\x03www\xc0\x0012", 0);
1133 assert!(ParsedName::parse(&mut parser.clone()).is_err());
1134 assert_eq!(ParsedName::skip(&mut parser), Ok(()));
1135 assert_eq!(parser.remaining(), 2);
1136
1137 let mut parser = p(b"\xc0\x0012", 0);
1139 assert!(ParsedName::parse(&mut parser.clone()).is_err());
1140 assert_eq!(ParsedName::skip(&mut parser), Ok(()));
1141 assert_eq!(parser.remaining(), 2);
1142
1143 let mut parser = p(b"\xc0\x02\xc0\x0012", 2);
1145 assert!(ParsedName::parse(&mut parser.clone()).is_err());
1146 assert_eq!(ParsedName::skip(&mut parser), Ok(()));
1147 assert_eq!(parser.remaining(), 2);
1148 }
1149
1150 #[test]
1151 #[cfg(feature = "std")]
1152 fn compose() {
1153 use octseq::builder::infallible;
1154 use std::vec::Vec;
1155
1156 fn step(name: ParsedName<&[u8]>, result: &[u8]) {
1157 let mut buf = Vec::new();
1158 infallible(name.compose(&mut buf));
1159 assert_eq!(buf.as_slice(), result);
1160 }
1161
1162 step(name!(root), b"\x00");
1163 step(name!(flat), WECR);
1164 step(name!(once), WECR);
1165 step(name!(twice), WECR);
1166 }
1167
1168 #[test]
1171 fn as_flat_slice() {
1172 assert_eq!(name!(root).as_flat_slice(), Some(b"\x00".as_ref()));
1173 assert_eq!(name!(flat).as_flat_slice(), Some(WECR));
1174 assert_eq!(name!(once).as_flat_slice(), None);
1175 assert_eq!(name!(twice).as_flat_slice(), None);
1176 }
1177
1178 #[test]
1179 fn eq() {
1180 fn step<N: ToName + fmt::Debug>(name: N) {
1181 assert_eq!(name!(flat), &name);
1182 assert_eq!(name!(once), &name);
1183 assert_eq!(name!(twice), &name);
1184 }
1185
1186 fn ne_step<N: ToName + fmt::Debug>(name: N) {
1187 assert_ne!(name!(flat), &name);
1188 assert_ne!(name!(once), &name);
1189 assert_ne!(name!(twice), &name);
1190 }
1191
1192 step(name!(flat));
1193 step(name!(once));
1194 step(name!(twice));
1195
1196 step(Name::from_slice(b"\x03www\x07example\x03com\x00").unwrap());
1197 step(Name::from_slice(b"\x03wWw\x07EXAMPLE\x03com\x00").unwrap());
1198 step(
1199 RelativeName::from_octets(b"\x03www\x07example\x03com")
1200 .unwrap()
1201 .chain_root(),
1202 );
1203 step(
1204 RelativeName::from_octets(b"\x03www\x07example")
1205 .unwrap()
1206 .chain(Name::from_octets(b"\x03com\x00").unwrap())
1207 .unwrap(),
1208 );
1209
1210 ne_step(Name::from_slice(b"\x03ww4\x07EXAMPLE\x03com\x00").unwrap());
1211 }
1212
1213 }