@@ -31,12 +31,10 @@ pub mod test;
31
31
32
32
// ----- Crates -----
33
33
34
- use bincode_core:: { serialize, BufferWriter } ;
35
34
use core:: convert:: TryFrom ;
36
35
use core:: fmt;
37
36
use heapless:: Vec ;
38
37
use num_enum:: { IntoPrimitive , TryFromPrimitive } ;
39
- use serde:: ser:: { self , Serialize , SerializeSeq , Serializer } ;
40
38
41
39
#[ cfg( feature = "server" ) ]
42
40
use log:: { error, warn} ;
@@ -136,6 +134,8 @@ pub enum HidIoCommandId {
136
134
#[ derive( Debug ) ]
137
135
#[ cfg_attr( feature = "defmt-impl" , derive( defmt:: Format ) ) ]
138
136
pub enum HidIoParseError {
137
+ BufferNotReady ,
138
+ BufferDataTooSmall ( usize ) ,
139
139
InvalidContinuedIdByte ( u8 ) ,
140
140
InvalidHidIoCommandId ( u32 ) ,
141
141
InvalidPacketIdWidth ( u8 ) ,
@@ -515,9 +515,9 @@ impl<const H: usize> HidIoPacketBuffer<H> {
515
515
/// Returns the currently computed serialized length of the
516
516
/// buffer. Can change based on the struct fields.
517
517
pub fn serialized_len ( & self ) -> u32 {
518
- // Sync packets have a serialized length of 1 (+1 for length)
518
+ // Sync packets have a serialized length of 1
519
519
if self . ptype == HidIoPacketType :: Sync {
520
- return 1 + 1 ;
520
+ return 1 ;
521
521
}
522
522
523
523
let hdr_len = self . hdr_len ( ) ;
@@ -531,8 +531,7 @@ impl<const H: usize> HidIoPacketBuffer<H> {
531
531
0
532
532
} ;
533
533
534
- // Extra byte is a type field from the serializer
535
- fullpackets + partialpacket + 1
534
+ fullpackets + partialpacket
536
535
}
537
536
538
537
/// Append payload data
@@ -674,48 +673,6 @@ impl<const H: usize> HidIoPacketBuffer<H> {
674
673
/// Serialize HidIoPacketBuffer
675
674
///
676
675
/// # Remarks
677
- /// Provides a raw data vector to the serialized data.
678
- /// Removes some of the header that Serialize from serde prepends.
679
- pub fn serialize_buffer < ' a > (
680
- & mut self ,
681
- data : & ' a mut [ u8 ] ,
682
- ) -> Result < & ' a [ u8 ] , HidIoParseError > {
683
- let options = bincode_core:: config:: DefaultOptions :: new ( ) ;
684
- let mut writer = BufferWriter :: new ( data) ;
685
- let len;
686
-
687
- // Serialize
688
- match serialize ( & self , & mut writer, options) {
689
- Ok ( _) => { }
690
- Err ( _e) => {
691
- error ! ( "Parse error: {:?}" , _e) ;
692
- return Err ( HidIoParseError :: SerializationError ) ;
693
- }
694
- } ;
695
-
696
- // Make sure serialization worked
697
- len = writer. written_len ( ) ;
698
- if self . ptype == HidIoPacketType :: Sync && len < 2
699
- || self . ptype != HidIoPacketType :: Sync && len < 5
700
- {
701
- error ! (
702
- "Serialization too small: {} -> {:02X?}" ,
703
- len,
704
- writer. written_buffer( )
705
- ) ;
706
- return Err ( HidIoParseError :: SerializationFailedResultTooSmall ( len) ) ;
707
- }
708
-
709
- // Slice off the first byte (type) header bytes from serde
710
- let slice = & data[ 1 ..len as usize ] ;
711
- Ok ( slice)
712
- }
713
- }
714
-
715
- impl < const H : usize > Serialize for HidIoPacketBuffer < H > {
716
- /// Serializer for HidIoPacketBuffer
717
- ///
718
- /// # Remarks
719
676
/// Determine cont, width, upper_len and len fields
720
677
/// According to this C-Struct:
721
678
///
@@ -730,17 +687,17 @@ impl<const H: usize> Serialize for HidIoPacketBuffer<H> {
730
687
/// uint8_t data[0]; // Start of data payload (may start with Id)
731
688
/// };
732
689
/// ```
733
- fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
734
- where
735
- S : Serializer ,
736
- {
690
+ pub fn serialize_buffer < ' a > ( & self , data : & ' a mut [ u8 ] ) -> Result < & ' a [ u8 ] , HidIoParseError > {
737
691
// Check if buffer is ready to serialize
738
692
if !self . done {
739
- return Err ( ser :: Error :: custom ( "HidIoPacketBuffer is not 'done'" ) ) ;
693
+ return Err ( HidIoParseError :: BufferNotReady ) ;
740
694
}
741
695
742
696
// --- First Packet ---
743
697
698
+ // Keep track of the serialization buffer position
699
+ let mut pos = 0 ;
700
+
744
701
// Determine id_width
745
702
let id_width = self . id_width ( ) ;
746
703
@@ -785,9 +742,7 @@ impl<const H: usize> Serialize for HidIoPacketBuffer<H> {
785
742
for idx in 0 ..id_width_len {
786
743
let id = ( self . id as u32 >> ( idx * 8 ) ) as u8 ;
787
744
if id_vec. push ( id) . is_err ( ) {
788
- return Err ( ser:: Error :: custom (
789
- "HidIoPacketBuffer failed to convert Id into bytes, vec add failed." ,
790
- ) ) ;
745
+ return Err ( HidIoParseError :: VecAddFailed ) ;
791
746
}
792
747
}
793
748
@@ -804,31 +759,19 @@ impl<const H: usize> Serialize for HidIoPacketBuffer<H> {
804
759
// upper_len - 2 bits
805
760
( upper_len & 0x3 ) ;
806
761
762
+ // Header byte is always serialized
763
+ pos = serialize_byte ( data, hdr_byte, pos) ?;
764
+
807
765
// Determine if this is a sync packet (much simpler serialization)
808
766
if self . ptype == HidIoPacketType :: Sync {
809
- let mut state = serializer. serialize_seq ( Some ( 0 ) ) ?;
810
- state. serialize_element ( & hdr_byte) ?;
811
- return state. end ( ) ;
767
+ return Ok ( data) ;
812
768
}
813
769
814
- // Serialize as a sequence
815
- let mut state = serializer. serialize_seq ( Some ( 0 ) ) ?;
816
-
817
- // Serialize header
818
- state. serialize_element ( & hdr_byte) ?;
819
-
820
770
// Serialize length
821
- state. serialize_element ( & len) ?;
822
-
823
- // If SYNC packet
824
- if self . ptype == HidIoPacketType :: Sync {
825
- return state. end ( ) ;
826
- }
771
+ pos = serialize_byte ( data, len, pos) ?;
827
772
828
773
// Serialize id
829
- for id_byte in & id_vec {
830
- state. serialize_element ( id_byte) ?;
831
- }
774
+ pos = serialize_bytes ( data, & id_vec[ ..id_width_len as usize ] , pos) ?;
832
775
833
776
// Serialize payload data
834
777
// We can't just serialize directly (extra info is included), serialize each element of vector separately
@@ -839,13 +782,11 @@ impl<const H: usize> Serialize for HidIoPacketBuffer<H> {
839
782
// Payload that's available
840
783
& self . data [ 0 ..data_len as usize ]
841
784
} ;
842
- for elem in slice {
843
- state. serialize_element ( elem) ?;
844
- }
785
+ pos = serialize_bytes ( data, slice, pos) ?;
845
786
846
787
// Finish serialization if no more payload left
847
788
if !cont {
848
- return state . end ( ) ;
789
+ return Ok ( data ) ;
849
790
}
850
791
851
792
// Determine how much payload is left
@@ -897,15 +838,13 @@ impl<const H: usize> Serialize for HidIoPacketBuffer<H> {
897
838
( upper_len & 0x3 ) ;
898
839
899
840
// Serialize header
900
- state . serialize_element ( & hdr_byte) ?;
841
+ pos = serialize_byte ( data , hdr_byte, pos ) ?;
901
842
902
843
// Serialize length
903
- state . serialize_element ( & len) ?;
844
+ pos = serialize_byte ( data , len, pos ) ?;
904
845
905
846
// Serialize id
906
- for id_byte in & id_vec {
907
- state. serialize_element ( id_byte) ?;
908
- }
847
+ pos = serialize_bytes ( data, & id_vec[ ..id_width_len as usize ] , pos) ?;
909
848
910
849
// Serialize payload data
911
850
// We can't just serialize directly (extra info is included), serialize each element of vector separately
@@ -917,18 +856,42 @@ impl<const H: usize> Serialize for HidIoPacketBuffer<H> {
917
856
data_len as usize
918
857
} ;
919
858
let slice = & self . data [ last_slice_index..slice_end] ;
920
- for elem in slice {
921
- state. serialize_element ( elem) ?;
922
- }
859
+ pos = serialize_bytes ( data, slice, pos) ?;
923
860
924
861
// Recalculate how much payload is left
925
862
payload_left -= ( slice_end - last_slice_index) as u32 ;
926
863
last_slice_index += payload_len as usize ;
927
864
}
928
865
929
866
// --- Finish serialization ---
930
- state. end ( )
867
+ Ok ( data)
868
+ }
869
+ }
870
+
871
+ /// Very simple error checking function for byte serialization
872
+ /// Returns the new serialization index pointer
873
+ fn serialize_byte ( data : & mut [ u8 ] , byte : u8 , pos : usize ) -> Result < usize , HidIoParseError > {
874
+ // Make sure buffer is large enough
875
+ if pos >= data. len ( ) {
876
+ return Err ( HidIoParseError :: BufferDataTooSmall ( pos - 1 ) ) ;
877
+ }
878
+
879
+ data[ pos] = byte;
880
+ Ok ( pos + 1 )
881
+ }
882
+
883
+ /// Very simple error checking function for byte array serialization
884
+ /// Returns the new serialization index pointer
885
+ fn serialize_bytes ( data : & mut [ u8 ] , bytes : & [ u8 ] , pos : usize ) -> Result < usize , HidIoParseError > {
886
+ // Make sure buffer is large enough
887
+ if pos + bytes. len ( ) > data. len ( ) && !bytes. is_empty ( ) {
888
+ return Err ( HidIoParseError :: BufferDataTooSmall ( pos - 1 ) ) ;
889
+ }
890
+
891
+ for ( i, byte) in bytes. iter ( ) . enumerate ( ) {
892
+ data[ pos + i] = * byte;
931
893
}
894
+ Ok ( pos + bytes. len ( ) )
932
895
}
933
896
934
897
impl fmt:: Display for HidIoPacketType {
0 commit comments