1use smallvec::SmallVec;
2
3use crate::traits::*;
4use crate::util::*;
5
6#[derive(Debug, Copy, Clone, Eq, PartialEq)]
10pub struct BytesMeta {
11 pub prefix_len: usize,
13 pub len: usize,
15 pub padding: usize,
17}
18
19impl<'a> TlRead<'a> for BytesMeta {
20 type Repr = Bare;
21
22 #[inline(always)]
23 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
24 match compute_bytes_meta(packet) {
25 Ok((prefix_len, len, padding)) => Ok(Self {
26 prefix_len,
27 len,
28 padding,
29 }),
30 Err(e) => Err(e),
31 }
32 }
33}
34
35impl<'a> TlRead<'a> for &'a [u8] {
37 type Repr = Bare;
38
39 #[inline(always)]
40 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
41 read_bytes(packet)
42 }
43}
44
45impl TlWrite for &[u8] {
47 type Repr = Bare;
48
49 #[inline(always)]
50 fn max_size_hint(&self) -> usize {
51 bytes_max_size_hint(self.len())
52 }
53
54 #[inline(always)]
55 fn write_to<P>(&self, packet: &mut P)
56 where
57 P: TlPacket,
58 {
59 write_bytes(self, packet)
60 }
61}
62
63impl<'a> TlRead<'a> for Box<[u8]> {
65 type Repr = Bare;
66
67 #[inline(always)]
68 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
69 Ok(Box::from(ok!(read_bytes(packet))))
70 }
71}
72
73impl TlWrite for Box<[u8]> {
75 type Repr = Bare;
76
77 #[inline(always)]
78 fn max_size_hint(&self) -> usize {
79 bytes_max_size_hint(self.len())
80 }
81
82 #[inline(always)]
83 fn write_to<P>(&self, packet: &mut P)
84 where
85 P: TlPacket,
86 {
87 write_bytes(self, packet)
88 }
89}
90
91impl<'a> TlRead<'a> for Vec<u8> {
93 type Repr = Bare;
94
95 #[inline(always)]
96 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
97 match read_bytes(packet) {
98 Ok(bytes) => Ok(bytes.to_vec()),
99 Err(e) => Err(e),
100 }
101 }
102}
103
104impl TlWrite for Vec<u8> {
106 type Repr = Bare;
107
108 #[inline(always)]
109 fn max_size_hint(&self) -> usize {
110 bytes_max_size_hint(self.len())
111 }
112
113 #[inline(always)]
114 fn write_to<P>(&self, packet: &mut P)
115 where
116 P: TlPacket,
117 {
118 write_bytes(self.as_slice(), packet)
119 }
120}
121
122#[cfg(feature = "bytes")]
124impl TlRead<'_> for bytes::Bytes {
125 type Repr = Bare;
126
127 #[inline(always)]
128 fn read_from(packet: &mut &'_ [u8]) -> TlResult<Self> {
129 match read_bytes(packet) {
130 Ok(bytes) => Ok(bytes::Bytes::copy_from_slice(bytes)),
131 Err(e) => Err(e),
132 }
133 }
134}
135
136#[cfg(feature = "bytes")]
138impl TlWrite for bytes::Bytes {
139 type Repr = Bare;
140
141 #[inline(always)]
142 fn max_size_hint(&self) -> usize {
143 bytes_max_size_hint(self.len())
144 }
145
146 #[inline(always)]
147 fn write_to<P>(&self, packet: &mut P)
148 where
149 P: TlPacket,
150 {
151 write_bytes(self, packet)
152 }
153}
154
155impl<'a, const N: usize> TlRead<'a> for &'a [u8; N] {
157 type Repr = Bare;
158
159 #[inline(always)]
160 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
161 read_fixed_bytes(packet)
162 }
163}
164
165impl<'a, const N: usize> TlRead<'a> for [u8; N] {
167 type Repr = Bare;
168
169 #[inline(always)]
170 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
171 match read_fixed_bytes(packet) {
172 Ok(data) => Ok(*data),
173 Err(e) => Err(e),
174 }
175 }
176}
177
178impl<const N: usize> TlWrite for [u8; N] {
180 type Repr = Bare;
181
182 #[inline(always)]
183 fn max_size_hint(&self) -> usize {
184 N
185 }
186
187 #[inline(always)]
188 fn write_to<P>(&self, packet: &mut P)
189 where
190 P: TlPacket,
191 {
192 packet.write_raw_slice(self.as_ref())
193 }
194}
195
196impl<'a, T, const N: usize> TlRead<'a> for SmallVec<[T; N]>
198where
199 [T; N]: smallvec::Array,
200 <[T; N] as smallvec::Array>::Item: TlRead<'a>,
201{
202 type Repr = Bare;
203
204 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
205 let len = ok!(read_vector_len(packet));
206
207 let mut items = SmallVec::<[T; N]>::with_capacity(len);
208 for _ in 0..len {
209 items.push(ok!(TlRead::read_from(packet)));
210 }
211 Ok(items)
212 }
213}
214
215impl<'a, T> TlRead<'a> for Vec<T>
217where
218 T: TlRead<'a>,
219{
220 type Repr = Bare;
221
222 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
223 let len = ok!(read_vector_len(packet));
224
225 let mut items = Vec::with_capacity(len);
226 for _ in 0..len {
227 items.push(ok!(TlRead::read_from(packet)));
228 }
229 Ok(items)
230 }
231}
232
233impl<T> TlWrite for Vec<T>
235where
236 T: TlWrite,
237{
238 type Repr = Bare;
239
240 #[inline(always)]
241 fn max_size_hint(&self) -> usize {
242 <&[T]>::max_size_hint(&self.as_slice())
243 }
244
245 #[inline(always)]
246 fn write_to<P>(&self, packet: &mut P)
247 where
248 P: TlPacket,
249 {
250 <&[T]>::write_to(&self.as_slice(), packet)
251 }
252}
253
254impl<T> TlWrite for &[T]
256where
257 T: TlWrite,
258{
259 type Repr = Bare;
260
261 #[inline(always)]
262 fn max_size_hint(&self) -> usize {
263 4 + self.iter().map(TlWrite::max_size_hint).sum::<usize>()
264 }
265
266 #[inline(always)]
267 fn write_to<P>(&self, packet: &mut P)
268 where
269 P: TlPacket,
270 {
271 (self.len() as u32).write_to(packet);
272 for item in *self {
273 item.write_to(packet);
274 }
275 }
276}
277
278impl<T, const N: usize> TlWrite for SmallVec<[T; N]>
280where
281 [T; N]: smallvec::Array,
282 <[T; N] as smallvec::Array>::Item: TlWrite,
283{
284 type Repr = Bare;
285
286 #[inline(always)]
287 fn max_size_hint(&self) -> usize {
288 self.as_slice().max_size_hint()
289 }
290
291 #[inline(always)]
292 fn write_to<P>(&self, packet: &mut P)
293 where
294 P: TlPacket,
295 {
296 self.as_slice().write_to(packet)
297 }
298}
299
300#[derive(Copy, Clone)]
304pub struct IterRef<'a, I: Sized>(pub &'a I);
305
306impl<I, T> TlWrite for IterRef<'_, I>
307where
308 I: Iterator<Item = T> + ExactSizeIterator + Clone,
309 T: TlWrite,
310{
311 type Repr = Bare;
312
313 fn max_size_hint(&self) -> usize {
314 let mut total = 4;
315 for item in self.0.clone() {
316 total += item.max_size_hint();
317 }
318 total
319 }
320
321 fn write_to<P>(&self, packet: &mut P)
322 where
323 P: TlPacket,
324 {
325 (self.0.len() as u32).write_to(packet);
326 for item in self.0.clone() {
327 item.write_to(packet);
328 }
329 }
330}
331
332#[derive(Debug)]
334#[repr(transparent)]
335pub struct BoundedBytes<const N: usize>([u8]);
336
337impl<const N: usize> BoundedBytes<N> {
338 #[inline]
340 pub const fn try_wrap(bytes: &[u8]) -> Option<&Self> {
341 if bytes.len() <= N {
342 Some(unsafe { &*(bytes as *const [u8] as *const BoundedBytes<N>) })
344 } else {
345 None
346 }
347 }
348
349 #[inline]
356 pub unsafe fn wrap_unchecked(bytes: &[u8]) -> &Self {
357 unsafe { &*(bytes as *const [u8] as *const BoundedBytes<N>) }
359 }
360}
361
362impl<const N: usize> AsRef<[u8]> for BoundedBytes<N> {
363 #[inline]
364 fn as_ref(&self) -> &[u8] {
365 &self.0
366 }
367}
368
369impl<const N: usize> AsMut<[u8]> for BoundedBytes<N> {
370 #[inline]
371 fn as_mut(&mut self) -> &mut [u8] {
372 &mut self.0
373 }
374}
375
376impl<const N: usize> std::ops::Deref for BoundedBytes<N> {
377 type Target = [u8];
378
379 #[inline]
380 fn deref(&self) -> &Self::Target {
381 &self.0
382 }
383}
384
385impl<const N: usize> std::ops::DerefMut for BoundedBytes<N> {
386 #[inline]
387 fn deref_mut(&mut self) -> &mut Self::Target {
388 &mut self.0
389 }
390}
391
392impl<'a, const N: usize> TlRead<'a> for &'a BoundedBytes<N> {
393 type Repr = Bare;
394
395 #[inline]
396 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
397 fn read_bytes_with_max_len<'a>(
398 packet: &mut &'a [u8],
399 max_len: usize,
400 ) -> TlResult<&'a [u8]> {
401 let (prefix_len, len, padding) = ok!(compute_bytes_meta(packet));
402 if len > max_len {
403 return Err(TlError::InvalidData);
404 }
405
406 let packet_ptr = packet.as_ptr();
407 let result = unsafe { std::slice::from_raw_parts(packet_ptr.add(prefix_len), len) };
408
409 let skip_len = prefix_len + len + padding;
410 *packet = unsafe {
411 std::slice::from_raw_parts(
412 packet_ptr.add(skip_len),
413 packet.len().unchecked_sub(skip_len),
414 )
415 };
416 Ok(result)
417 }
418
419 let result = ok!(read_bytes_with_max_len(packet, N));
420
421 Ok(unsafe { BoundedBytes::wrap_unchecked(result) })
423 }
424}
425
426impl<const N: usize> TlWrite for &BoundedBytes<N> {
427 type Repr = Bare;
428
429 #[inline(always)]
430 fn max_size_hint(&self) -> usize {
431 bytes_max_size_hint(self.len())
432 }
433
434 #[inline(always)]
435 fn write_to<P>(&self, packet: &mut P)
436 where
437 P: TlPacket,
438 {
439 write_bytes(self, packet)
440 }
441}
442
443#[derive(Debug, Clone)]
445pub struct IntermediateBytes<T>(pub T);
446
447impl<T> IntermediateBytes<T>
448where
449 T: AsRef<[u8]>,
450{
451 pub fn as_slice(&self) -> &[u8] {
453 self.0.as_ref()
454 }
455}
456
457impl<'a, T> TlRead<'a> for IntermediateBytes<T>
458where
459 T: TlRead<'a>,
460{
461 type Repr = Bare;
462
463 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
464 match read_bytes(packet) {
465 Ok(mut intermediate) => match T::read_from(&mut intermediate) {
466 Ok(data) => Ok(IntermediateBytes(data)),
467 Err(e) => Err(e),
468 },
469 Err(e) => Err(e),
470 }
471 }
472}
473
474impl<T> TlWrite for IntermediateBytes<T>
475where
476 T: TlWrite,
477{
478 type Repr = Bare;
479
480 fn max_size_hint(&self) -> usize {
481 bytes_max_size_hint(self.0.max_size_hint())
482 }
483
484 fn write_to<P>(&self, packet: &mut P)
485 where
486 P: TlPacket,
487 {
488 let len = self.0.max_size_hint();
489 let mut have_written = write_bytes_len(len, packet);
490
491 self.0.write_to(packet);
492 have_written += len;
493
494 let remainder = have_written % 4;
495 if remainder != 0 {
496 let buf = [0u8; 4];
497 packet.write_raw_slice(&buf[remainder..]);
498 }
499 }
500}
501
502pub struct RawBytes<'a, R>(&'a [u8], std::marker::PhantomData<R>);
504
505impl<'a, R> RawBytes<'a, R> {
506 pub fn new(raw: &'a [u8]) -> Self {
508 RawBytes(raw, std::marker::PhantomData)
509 }
510
511 #[inline(always)]
513 pub fn into_inner(self) -> &'a [u8] {
514 self.0
515 }
516}
517
518impl<R> AsRef<[u8]> for RawBytes<'_, R> {
519 fn as_ref(&self) -> &[u8] {
520 self.0
521 }
522}
523
524impl<R> std::fmt::Debug for RawBytes<'_, R> {
525 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
526 f.debug_tuple("RawBytes").field(&self.0).finish()
527 }
528}
529
530impl<R> Eq for RawBytes<'_, R> {}
531impl<R> PartialEq for RawBytes<'_, R> {
532 fn eq(&self, other: &Self) -> bool {
533 self.0.eq(other.0)
534 }
535}
536
537impl<R> Copy for RawBytes<'_, R> {}
538impl<R> Clone for RawBytes<'_, R> {
539 #[inline]
540 fn clone(&self) -> Self {
541 *self
542 }
543}
544
545impl<'a, R: Repr> TlRead<'a> for RawBytes<'a, R> {
546 type Repr = R;
547
548 fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
549 let result = *packet;
550 *packet = &packet[packet.len()..];
553 Ok(Self::new(result))
554 }
555}
556
557impl<R: Repr> TlWrite for RawBytes<'_, R> {
558 type Repr = R;
559
560 #[inline(always)]
561 fn max_size_hint(&self) -> usize {
562 self.0.len()
563 }
564
565 #[inline(always)]
566 fn write_to<P>(&self, packet: &mut P)
567 where
568 P: TlPacket,
569 {
570 packet.write_raw_slice(self.0);
571 }
572}
573
574pub struct OwnedRawBytes<R>(Vec<u8>, std::marker::PhantomData<R>);
578
579impl<R> OwnedRawBytes<R> {
580 #[inline(always)]
582 pub fn new(raw: Vec<u8>) -> Self {
583 OwnedRawBytes(raw, std::marker::PhantomData)
584 }
585
586 #[inline(always)]
588 pub fn into_inner(self) -> Vec<u8> {
589 self.0
590 }
591}
592
593impl<R> std::fmt::Debug for OwnedRawBytes<R> {
594 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
595 f.debug_tuple("OwnedRawBytes").field(&self.0).finish()
596 }
597}
598
599impl<R> Eq for OwnedRawBytes<R> {}
600impl<R> PartialEq for OwnedRawBytes<R> {
601 fn eq(&self, other: &Self) -> bool {
602 self.0.eq(&other.0)
603 }
604}
605
606impl<R> Clone for OwnedRawBytes<R> {
607 fn clone(&self) -> Self {
608 Self(self.0.clone(), std::marker::PhantomData)
609 }
610}
611
612impl<R> AsRef<[u8]> for OwnedRawBytes<R> {
613 fn as_ref(&self) -> &[u8] {
614 &self.0
615 }
616}
617
618impl<R: Repr> TlRead<'_> for OwnedRawBytes<R> {
619 type Repr = R;
620
621 fn read_from(packet: &mut &'_ [u8]) -> TlResult<Self> {
622 match RawBytes::<R>::read_from(packet) {
623 Ok(RawBytes(inner, ..)) => Ok(Self::new(inner.to_vec())),
624 Err(e) => Err(e),
625 }
626 }
627}
628
629impl<R: Repr> TlWrite for OwnedRawBytes<R> {
630 type Repr = R;
631
632 #[inline(always)]
633 fn max_size_hint(&self) -> usize {
634 self.0.len()
635 }
636
637 #[inline(always)]
638 fn write_to<P>(&self, packet: &mut P)
639 where
640 P: TlPacket,
641 {
642 packet.write_raw_slice(self.0.as_slice())
643 }
644}
645
646#[inline(always)]
647fn read_vector_len(packet: &mut &[u8]) -> TlResult<usize> {
648 let len = ok!(u32::read_from(packet)) as usize;
649
650 if unlikely((len * 4) > packet.len()) {
653 Err(TlError::UnexpectedEof)
654 } else {
655 Ok(len)
656 }
657}
658
659#[inline(always)]
660fn read_fixed_bytes<'a, const N: usize>(packet: &mut &'a [u8]) -> TlResult<&'a [u8; N]> {
661 match packet.split_first_chunk() {
662 Some((chunk, tail)) => {
663 *packet = tail;
664 Ok(chunk)
665 }
666 None => Err(TlError::UnexpectedEof),
667 }
668}
669
670#[inline(always)]
672pub const fn bytes_max_size_hint(mut len: usize) -> usize {
673 if len < 254 {
674 len += 1;
675 } else {
676 len += 4;
677 }
678
679 len + (4 - len % 4) % 4
681}
682
683#[inline(always)]
684fn write_bytes_len<T>(len: usize, packet: &mut T) -> usize
685where
686 T: TlPacket,
687{
688 if len < 254 {
689 packet.write_raw_slice(&[len as u8]);
690 1
691 } else {
692 packet.write_raw_slice(&[254, len as u8, (len >> 8) as u8, (len >> 16) as u8]);
693 4
694 }
695}
696
697#[inline(always)]
698fn write_bytes<T>(bytes: &[u8], packet: &mut T)
699where
700 T: TlPacket,
701{
702 let len = bytes.len();
703 let mut have_written = write_bytes_len(len, packet);
704
705 packet.write_raw_slice(bytes);
706 have_written += len;
707
708 let remainder = have_written % 4;
709 if remainder != 0 {
710 packet.write_raw_slice(&[0u8; 4][remainder..]);
711 }
712}
713
714#[inline(always)]
715fn read_bytes<'a>(packet: &mut &'a [u8]) -> TlResult<&'a [u8]> {
716 let (prefix_len, len, padding) = ok!(compute_bytes_meta(packet));
717
718 let packet_ptr = packet.as_ptr();
719 let result = unsafe { std::slice::from_raw_parts(packet_ptr.add(prefix_len), len) };
720
721 let skip_len = prefix_len + len + padding;
722 *packet = unsafe {
723 std::slice::from_raw_parts(
724 packet_ptr.add(skip_len),
725 packet.len().unchecked_sub(skip_len),
726 )
727 };
728 Ok(result)
729}
730
731#[inline(always)]
735fn compute_bytes_meta(packet: &[u8]) -> TlResult<(usize, usize, usize)> {
736 let packet_len = packet.len();
737 if unlikely(packet_len < 4) {
738 return Err(TlError::UnexpectedEof);
739 }
740
741 let first_bytes = unsafe { packet.as_ptr().cast::<u32>().read_unaligned() };
742 let (len, have_read) = if first_bytes & 0xff != SIZE_MAGIC as u32 {
743 ((first_bytes & 0xff) as usize, 1)
744 } else {
745 ((first_bytes >> 8) as usize, 4)
746 };
747
748 let padding = (4 - (have_read + len) % 4) % 4;
749 if unlikely(packet_len < have_read + len + padding) {
750 return Err(TlError::UnexpectedEof);
751 }
752
753 Ok((have_read, len, padding))
754}
755
756const SIZE_MAGIC: u8 = 254;
757
758#[cfg(test)]
759mod tests {
760 use super::*;
761
762 #[test]
763 fn read_small_slice() {
764 assert_eq!(read_bytes(&mut [1, 123, 0, 0].as_ref()).unwrap(), &[123]);
765 }
766}