1use core::{mem::MaybeUninit, slice, str};
7use std::{cmp::Ordering, fmt, io, iter::FusedIterator};
8
9use bytes::{BufMut, Bytes};
10
11use super::fixed_arr::serialize;
12pub use super::{Array, ArrayStr, DecodeError, Result};
13
14#[derive(Debug, Clone)]
31pub struct Decoder<'a> {
32 rem: Option<u8>,
34 src: &'a [[u8; 2]],
36}
37
38impl<'a> Decoder<'a> {
39 pub const fn new(src: &'a [u8]) -> Self {
45 let (rem, src) = src.as_rchunks();
46 Self { rem: rem.first().copied(), src }
47 }
48
49 pub const fn skip_0x(self) -> Self {
63 match (self.rem, self.src) {
64 (Some(b'0'), [[b'x' | b'X', x], rest @ ..]) => Self { rem: Some(*x), src: rest },
65 (None, [[b'0', b'x' | b'X'], rest @ ..]) => Self { rem: None, src: rest },
66 _ => self,
67 }
68 }
69
70 pub const fn skip_leading_zeros(mut self) -> Self {
83 if let Some(v) = self.rem {
84 if v == b'0' {
85 self.rem = None;
86 } else {
87 return self;
88 }
89 }
90
91 loop {
92 match self.src {
93 [[b'0', b'0'], rest @ ..] => {
94 self.src = rest;
95 continue;
96 },
97 [[b'0', x], rest @ ..] => {
98 self.rem = Some(*x);
99 self.src = rest;
100 },
101 _ => {},
102 }
103 break self;
104 }
105 }
106
107 pub fn into_vec(self) -> Result<Vec<u8>> {
111 let len = self.len();
112 let mut buf = Vec::<u8>::with_capacity(len);
113 let base = buf.spare_capacity_mut();
114 let mut di = 0;
115
116 if let Some(rem) = self.rem {
118 let n = parse_nibble(rem).ok_or(DecodeError::InvalidCharacter(rem))?;
119 unsafe { base.get_unchecked_mut(di) }.write(n);
121 di += 1;
122 }
123
124 let mut si = 0;
126 while si + 8 <= self.src.len() {
127 for _ in 0..8 {
128 let b = parse_byte(self.src[si])?;
129 unsafe { base.get_unchecked_mut(di) }.write(b);
131 di += 1;
132 si += 1;
133 }
134 }
135
136 for &[h, l] in &self.src[si..] {
138 let b = parse_byte([h, l])?;
139 unsafe { base.get_unchecked_mut(di) }.write(b);
141 di += 1;
142 }
143
144 debug_assert_eq!(di, len);
145 unsafe { buf.set_len(len) };
149 Ok(buf)
150 }
151
152 pub fn into_bytes(self) -> Result<Bytes> {
154 self.into_vec().map(Bytes::from)
155 }
156
157 pub fn into_slice(mut self, mut buf: &mut [u8]) -> Result<usize> {
159 let mut n = if let Some(rem) = self.rem {
161 let Some(d) = buf.split_off_first_mut() else {
162 return Ok(0);
163 };
164 *d = parse_nibble(rem).ok_or(DecodeError::InvalidCharacter(rem))?;
165 1
166 } else {
167 0
168 };
169
170 while let Some(d) = buf.split_off_first_mut()
172 && let Some(&hl) = self.src.split_off_first()
173 {
174 *d = parse_byte(hl)?;
175 n += 1;
176 }
177 Ok(n)
178 }
179
180 pub fn into_array<const K: usize>(self) -> Result<[u8; K]> {
182 let mut buf = [0u8; K];
183 let n = self.into_slice(&mut buf)?;
184 if n != K {
185 return Err(DecodeError::InputTooShort);
186 }
187 Ok(buf)
188 }
189
190 #[inline]
195 pub fn into_buf<B: BufMut>(mut self, mut buf: B) -> Result<B> {
196 loop {
197 let mut n = 0;
198 let chunk = unsafe { buf.chunk_mut().as_uninit_slice_mut() };
202 for (b, dst) in self.by_ref().zip(&mut *chunk) {
203 dst.write(b?);
204 n += 1;
205 }
206 let exhausted = n < chunk.len();
207
208 unsafe { buf.advance_mut(n) };
212
213 if exhausted {
215 break Ok(buf);
216 }
217 }
218 }
219
220 pub fn extend_into<E: Extend<u8> + ?Sized>(self, buf: &mut E) -> Result<usize> {
224 buf.extend_reserve(self.len());
225 let mut n = 0;
226 for byte in self {
227 let byte = byte?;
228 buf.extend_one(byte);
229 n += 1;
230 }
231 Ok(n)
232 }
233
234 pub fn write_into<W: io::Write + ?Sized>(mut self, writer: &mut W) -> io::Result<usize> {
238 let mut buf = [MaybeUninit::<u8>::uninit(); 512];
239 let mut n = 0;
240 let mut done = false;
241 while !done {
242 let mut i = 0;
243 for dst in &mut buf {
244 if let Some(b) = self.next() {
245 dst.write(b.map_err(io::Error::other)?);
246 i += 1;
247 } else {
248 done = true;
249 break;
250 }
251 }
252 n += i;
253
254 if i != 0 {
255 unsafe { writer.write_all(slice::from_raw_parts(buf.as_ptr().cast(), i))? };
259 }
260 }
261 Ok(n)
262 }
263}
264
265impl Iterator for Decoder<'_> {
266 type Item = Result<u8>;
267
268 #[inline]
269 fn next(&mut self) -> Option<Self::Item> {
270 if let Some(s0) = self.rem.take() {
272 return Some(parse_nibble(s0).ok_or(DecodeError::InvalidCharacter(s0)));
273 }
274
275 match parse_byte(*self.src.split_off_first()?) {
277 Ok(b) => Some(Ok(b)),
278 Err(e) => Some(Err(e)),
279 }
280 }
281
282 #[inline]
283 fn size_hint(&self) -> (usize, Option<usize>) {
284 let n = self.len();
285 (n, Some(n))
286 }
287}
288
289impl DoubleEndedIterator for Decoder<'_> {
290 #[inline]
291 fn next_back(&mut self) -> Option<Self::Item> {
292 if let Some(x) = self.src.split_off_last() {
294 return match parse_byte(*x) {
295 Ok(b) => Some(Ok(b)),
296 Err(e) => Some(Err(e)),
297 };
298 }
299
300 if let Some(s0) = self.rem.take() {
302 return Some(parse_nibble(s0).ok_or(DecodeError::InvalidCharacter(s0)));
303 }
304
305 None
306 }
307}
308
309impl ExactSizeIterator for Decoder<'_> {
310 #[inline]
311 fn len(&self) -> usize {
312 self.src.len() + usize::from(self.rem.is_some())
313 }
314}
315
316impl FusedIterator for Decoder<'_> {}
317
318impl<const N: usize> TryFrom<Decoder<'_>> for [u8; N] {
319 type Error = DecodeError;
320
321 fn try_from(decoder: Decoder<'_>) -> Result<Self> {
322 decoder.into_array()
323 }
324}
325
326impl fmt::Display for Decoder<'_> {
327 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328 for byte in self.clone() {
329 if let Ok(byte) = byte {
330 write!(f, "{byte:02x}")?;
331 } else {
332 write!(f, "??")?;
333 }
334 }
335 Ok(())
336 }
337}
338
339impl PartialEq<[u8]> for Decoder<'_> {
340 fn eq(&self, other: &[u8]) -> bool {
341 self.clone().eq(other.iter().map(|&b| Ok(b)))
342 }
343}
344
345impl PartialOrd<[u8]> for Decoder<'_> {
346 fn partial_cmp(&self, other: &[u8]) -> Option<Ordering> {
347 Some(self.clone().cmp(other.iter().map(|&b| Ok(b))))
348 }
349}
350
351pub const fn decode_mut(src: &[u8], dst: &mut [u8]) -> Result<usize> {
360 let mut i = 0;
361 let mut si = src;
362
363 if let [s0, sn @ ..] = si
365 && sn.len() & 1 == 0
366 && dst.len() > i
367 {
368 let Some(s0) = parse_nibble(*s0) else {
369 return Err(DecodeError::InvalidCharacter(*s0));
370 };
371 dst[i] = s0;
372 si = sn;
373 i += 1;
374 }
375
376 while let [c0, c1, sn @ ..] = si
378 && dst.len() > i
379 {
380 let c0v = *c0;
381 let c1v = *c1;
382 dst[i] = match parse_byte([c0v, c1v]) {
383 Ok(b) => b,
384 Err(e) => return Err(e),
385 };
386 si = sn;
387 i += 1;
388 }
389
390 Ok(i)
391}
392
393#[inline]
402pub fn decode<T: AsRef<[u8]> + ?Sized>(src: &T) -> Decoder<'_> {
403 Decoder::new(src.as_ref())
404}
405
406#[inline]
424pub const fn skip_0x(src: &[u8]) -> &[u8] {
425 match src {
426 [b'0', b'x' | b'X', rest @ ..] => rest,
427 _ => src,
428 }
429}
430
431#[inline]
448pub const fn skip_leading_zeros(mut src: &[u8]) -> &[u8] {
449 while let [b'0', rest @ ..] = src {
450 src = rest;
451 }
452 src
453}
454
455const DEC_TABLE: [u8; 0x100] = {
463 let mut table = [0x80; 0x100];
464 let mut i = 0;
465
466 while i <= 0xf {
468 let c = char::from_digit(i as u32, 0x10).unwrap();
469 table[c.to_ascii_lowercase() as usize] = i;
470 table[c.to_ascii_uppercase() as usize] = i;
471 i += 1;
472 }
473
474 table
475};
476
477#[inline]
490pub const fn parse_nibble(b: u8) -> Option<u8> {
491 let v = DEC_TABLE[b as usize];
492 if v.cast_signed() >= 0 {
493 Some(v)
494 } else {
495 std::hint::cold_path();
496 None
497 }
498}
499
500#[inline]
509pub const fn parse_byte([h, l]: [u8; 2]) -> Result<u8> {
510 let hv = DEC_TABLE[h as usize];
511 let lv = DEC_TABLE[l as usize];
512
513 if (hv | lv).cast_signed() >= 0 {
514 Ok((hv << 4) | lv)
515 } else {
516 std::hint::cold_path();
517 let inv = if hv.cast_signed() >= 0 { l } else { h };
518 Err(DecodeError::InvalidCharacter(inv))
519 }
520}
521
522const ALPHABET: [u8; 32] = *b"0123456789abcdef0123456789ABCDEF";
527
528const LUT: [[u16; 256]; 2] = {
530 let mut t = [[0u16; 256]; 2];
531 {
532 let t = t[0].as_mut_slice();
533 let mut i = 0u16;
534 while i < 256 {
535 let b = (i & 0xff) as u8;
536 let h = LOWER.encode_nibble(b >> 4);
537 let l = LOWER.encode_nibble(b & 0x0f);
538 t[i as usize] = u16::from_ne_bytes([h, l]);
539 i += 1;
540 }
541 }
542 {
543 let t = t[1].as_mut_slice();
544 let mut i = 0u16;
545 while i < 256 {
546 let b = (i & 0xff) as u8;
547 let h = UPPER.encode_nibble(b >> 4);
548 let l = UPPER.encode_nibble(b & 0x0f);
549 t[i as usize] = u16::from_ne_bytes([h, l]);
550 i += 1;
551 }
552 }
553 t
554};
555
556#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
558#[repr(u8)]
559pub enum Encoding {
560 Lowercase = 0,
562 Uppercase = 1,
564}
565
566pub const STD: Encoding = Encoding::Lowercase;
568
569pub const LOWER: Encoding = Encoding::Lowercase;
571
572pub const UPPER: Encoding = Encoding::Uppercase;
574
575impl Encoding {
576 #[inline]
585 pub const fn encode_nibble(self, nibble: u8) -> u8 {
586 let idx = (((self as usize) << 4) + (nibble as usize)) & 31;
587 ALPHABET[idx]
588 }
589
590 #[inline]
604 pub const fn encode_mut(self, src: &[u8], dst: &mut [u8]) -> usize {
605 let lut = self.lut();
606 let mut n = dst.len() >> 1;
607 if n > src.len() {
608 n = src.len();
609 }
610
611 let src = src.as_ptr();
612 let dst = dst.as_mut_ptr();
613 let mut i = 0;
614 while i < n {
615 unsafe {
618 dst.add(i << 1)
619 .cast::<u16>()
620 .write_unaligned(lut[src.add(i).read() as usize]);
621 }
622 i += 1;
623 }
624 n << 1
625 }
626
627 #[inline]
636 pub const fn encode_byte(self, byte: u8) -> [u8; 2] {
637 LUT[self as usize][byte as usize].to_ne_bytes()
638 }
639
640 #[inline]
642 pub const fn encode_n<const N: usize>(self, src: &[u8; N]) -> ArrayStr<N> {
643 let mut out = [[0u8; 2]; N];
644 self.encode_mut(src.as_slice(), out.as_flattened_mut());
645 ArrayStr::new(out, N * 2)
646 }
647
648 #[inline]
650 pub const fn lut(self) -> &'static [u16; 256] {
651 &LUT[self as usize]
652 }
653}
654
655#[derive(Debug, Clone)]
668pub struct Encoder<'a> {
669 src: &'a [u8],
671 charset: Encoding,
673 low: Option<u8>,
675 high: Option<u8>,
677}
678
679impl<'a> From<&'a [u8]> for Encoder<'a> {
680 fn from(src: &'a [u8]) -> Self {
681 Self { src, charset: LOWER, low: None, high: None }
682 }
683}
684
685impl<'a> Encoder<'a> {
686 pub fn new(src: &'a [u8]) -> Self {
688 src.into()
689 }
690
691 pub const fn lower(mut self) -> Self {
693 self.charset = LOWER;
694 self
695 }
696
697 pub const fn upper(mut self) -> Self {
699 self.charset = UPPER;
700 self
701 }
702
703 pub const fn with_charset(mut self, charset: Encoding) -> Self {
705 self.charset = charset;
706 self
707 }
708
709 #[define_opaque(CharEncoder)]
711 pub fn into_chars(self) -> CharEncoder<'a> {
712 self.map(|x| x as char)
713 }
714
715 pub fn into_vec(self) -> Vec<u8> {
717 let lut = self.charset.lut();
718 let out_len = self.len();
719 let mut buf = Vec::<u8>::with_capacity(out_len);
720 if let Some(low) = self.low {
721 buf.push(self.charset.encode_nibble(low));
722 }
723 let pairs_end = buf.len() + 2 * self.src.len();
724 let base = buf.spare_capacity_mut();
725 for (i, &byte) in self.src.iter().enumerate() {
726 unsafe {
730 base
731 .as_mut_ptr()
732 .cast::<u16>()
733 .add(i)
734 .write_unaligned(lut[byte as usize]);
735 };
736 }
737 unsafe { buf.set_len(pairs_end) };
740 if let Some(high) = self.high {
743 buf.push(self.charset.encode_nibble(high));
744 }
745 debug_assert_eq!(buf.len(), out_len);
746 buf
747 }
748
749 pub fn into_bytes(self) -> Bytes {
751 Bytes::from(self.into_vec())
752 }
753
754 pub fn into_string(self) -> String {
756 super::ascii_to_str_owned(self.into_vec())
757 }
758
759 pub fn extend_into<E: Extend<u8> + ?Sized>(self, buf: &mut E) {
761 buf.extend(self);
762 }
763
764 pub fn into_buf<B: BufMut>(mut self, mut buf: B) -> B {
766 loop {
767 let mut n = 0;
768 let chunk = unsafe { buf.chunk_mut().as_uninit_slice_mut() };
772 for (b, d) in self.by_ref().zip(&mut *chunk) {
773 d.write(b);
774 n += 1;
775 }
776 let exhausted = n < chunk.len();
777
778 unsafe { buf.advance_mut(n) };
782
783 if exhausted {
785 break buf;
786 }
787 }
788 }
789
790 pub fn write_into<W: io::Write + ?Sized>(self, writer: &mut W) -> io::Result<usize> {
792 let Self { src: mut it, charset, low, mut high } = self;
793
794 let mut n = 0;
795
796 let mut buf = MaybeUninit::<[[u8; 2]; 64]>::uninit().transpose();
797 if let Some(low) = low {
798 buf[0].write([0, charset.encode_nibble(low)]);
799 n += 1;
800
801 for d in &mut buf[1..] {
802 let Some(&b) = it.split_off_first() else {
803 break;
804 };
805 d.write(charset.encode_byte(b));
806 n += 2;
807 }
808
809 let data = unsafe { slice::from_raw_parts(buf.as_ptr().cast::<u8>().add(1), n) };
812 writer.write_all(data)?;
813 }
814
815 while !it.is_empty() {
816 let mut local = 0;
817 for d in &mut buf {
818 let Some(&b) = it.split_off_first() else {
819 if let Some(hi) = high.take() {
820 d.write([charset.encode_nibble(hi), 0]);
822 local += 1;
823 }
824 break;
825 };
826 d.write(charset.encode_byte(b));
827 local += 2;
828 }
829 let data = unsafe { slice::from_raw_parts(buf.as_ptr().cast::<u8>(), local) };
832 writer.write_all(data)?;
833 n += local;
834 }
835
836 if let Some(high) = high {
837 writer.write_all(&[charset.encode_nibble(high)])?;
838 n += 1;
839 }
840 Ok(n)
841 }
842
843 pub fn format_into<W: fmt::Write + ?Sized>(self, writer: &mut W) -> fmt::Result {
845 for bytes in self {
846 writer.write_str(super::ascii_to_str(&[bytes]))?;
847 }
848 Ok(())
849 }
850}
851
852impl From<Encoder<'_>> for String {
853 fn from(encoder: Encoder<'_>) -> Self {
854 encoder.into_string()
855 }
856}
857
858impl From<Encoder<'_>> for Bytes {
859 fn from(encoder: Encoder<'_>) -> Self {
860 encoder.into_bytes()
861 }
862}
863
864impl From<Encoder<'_>> for Vec<u8> {
865 fn from(encoder: Encoder<'_>) -> Self {
866 encoder.into_vec()
867 }
868}
869
870impl Iterator for Encoder<'_> {
871 type Item = u8;
872
873 fn next(&mut self) -> Option<Self::Item> {
874 if let Some(low) = self.low.take() {
876 return Some(self.charset.encode_nibble(low));
877 }
878
879 if let Some(byte) = self.src.split_off_first() {
881 let byte = *byte;
882 let high = byte >> 4;
883 let low = byte & 0x0f;
884 self.low = Some(low);
885 return Some(self.charset.encode_nibble(high));
886 }
887
888 if let Some(high) = self.high.take() {
890 return Some(self.charset.encode_nibble(high));
891 }
892
893 None
894 }
895
896 fn size_hint(&self) -> (usize, Option<usize>) {
897 let n = self.len();
898 (n, Some(n))
899 }
900}
901
902impl DoubleEndedIterator for Encoder<'_> {
903 fn next_back(&mut self) -> Option<Self::Item> {
904 if let Some(high) = self.high.take() {
906 return Some(self.charset.encode_nibble(high));
907 }
908
909 if let Some(byte) = self.src.split_off_last() {
911 let byte = *byte;
912 let high = byte >> 4;
913 let low = byte & 0x0f;
914 self.high = Some(high);
915 return Some(self.charset.encode_nibble(low));
916 }
917
918 if let Some(low) = self.low.take() {
920 return Some(self.charset.encode_nibble(low));
921 }
922
923 None
924 }
925}
926
927impl ExactSizeIterator for Encoder<'_> {
928 fn len(&self) -> usize {
929 let rem = self.low.is_some() as usize + self.high.is_some() as usize;
930 (self.src.len() << 1) + rem
931 }
932}
933
934impl FusedIterator for Encoder<'_> {}
935
936impl fmt::Display for Encoder<'_> {
937 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
938 super::format_with_precision(self.clone(), f)
939 }
940}
941
942impl fmt::LowerHex for Encoder<'_> {
943 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
944 fmt::Display::fmt(&self.clone().lower(), f)
945 }
946}
947
948impl fmt::UpperHex for Encoder<'_> {
949 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
950 fmt::Display::fmt(&self.clone().upper(), f)
951 }
952}
953
954impl<'b> PartialEq<Encoder<'b>> for Encoder<'_> {
955 fn eq(&self, other: &Encoder<'b>) -> bool {
956 self.clone().eq(other.clone())
957 }
958}
959
960impl Ord for Encoder<'_> {
961 fn cmp(&self, other: &Self) -> Ordering {
962 self.clone().cmp(other.clone())
963 }
964}
965
966impl<'b> PartialOrd<Encoder<'b>> for Encoder<'_> {
967 fn partial_cmp(&self, other: &Encoder<'b>) -> Option<Ordering> {
968 self.clone().partial_cmp(other.clone())
969 }
970}
971
972impl Eq for Encoder<'_> {}
973
974impl PartialEq<[u8]> for Encoder<'_> {
975 fn eq(&self, other: &[u8]) -> bool {
976 self.clone().eq(other.iter().copied())
977 }
978}
979
980impl PartialEq<str> for Encoder<'_> {
981 fn eq(&self, other: &str) -> bool {
982 self.clone().eq(other.as_bytes().iter().copied())
983 }
984}
985
986impl PartialOrd<[u8]> for Encoder<'_> {
987 fn partial_cmp(&self, other: &[u8]) -> Option<Ordering> {
988 Some(self.clone().cmp(other.iter().copied()))
989 }
990}
991
992impl PartialOrd<str> for Encoder<'_> {
993 fn partial_cmp(&self, other: &str) -> Option<Ordering> {
994 Some(self.clone().cmp(other.as_bytes().iter().copied()))
995 }
996}
997
998impl serde::Serialize for Encoder<'_> {
999 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1000 let len = encode_len(self.src.len());
1001 serialize(serializer, len, |buffer| self.charset.encode_mut(self.src, buffer))
1002 }
1003}
1004
1005pub type CharEncoder<'a> =
1010 impl ExactSizeIterator<Item = char> + DoubleEndedIterator + FusedIterator + 'a;
1011
1012pub fn encode<I: AsRef<[u8]> + ?Sized>(src: &I) -> Encoder<'_> {
1025 Encoder::new(src.as_ref())
1026}
1027
1028#[inline]
1042pub const fn encode_mut(src: &[u8], dst: &mut [u8]) -> usize {
1043 LOWER.encode_mut(src, dst)
1044}
1045
1046pub const fn decode_n<const N: usize>(src: &[u8; N]) -> Option<Array<N>> {
1059 let mut out = [0; _];
1060 let Ok(written) = decode_mut(src.as_slice(), out.as_mut_slice()) else {
1061 return None;
1062 };
1063 Some(Array::new(out, written))
1064}
1065
1066#[inline]
1075pub const fn encode_n<const N: usize>(src: &[u8; N]) -> ArrayStr<N> {
1076 LOWER.encode_n(src)
1077}
1078
1079#[inline]
1090pub const fn encode_len(src_len: usize) -> usize {
1091 src_len << 1
1092}
1093
1094#[inline]
1107pub const fn decode_len(src_len: usize) -> usize {
1108 src_len.div_ceil(2)
1109}