1- using System ;
1+ using System ;
22using System . Collections . Generic ;
33using OSDP . Net . Messages ;
44
55namespace OSDP . Net . Model . CommandData
66{
7+ /// <summary>
8+ /// Defines the field size used for the <see cref="MessageDataFragment.TotalSize"/> and
9+ /// <see cref="MessageDataFragment.Offset"/> values.
10+ /// </summary>
11+ public enum MessageDataFragmentFieldSize
12+ {
13+ /// <summary>
14+ /// Use 2-byte unsigned integer fields.
15+ /// </summary>
16+ TwoBytes ,
17+
18+ /// <summary>
19+ /// Use 4-byte signed integer fields.
20+ /// </summary>
21+ FourBytes
22+ }
23+
724 /// <summary>
825 /// Represents a fragment of data for a multipart message.
926 /// </summary>
1027 public class MessageDataFragment
1128 {
29+ private readonly MessageDataFragmentFieldSize sizeAndOffsetFieldSize ;
30+
1231 /// <summary>
1332 /// Initializes a new instance of the <see cref="MessageDataFragment"/> class.
1433 /// </summary>
1534 /// <param name="totalSize">Total message data size as little-endian format</param>
1635 /// <param name="offset">Offset of the current message</param>
1736 /// <param name="fragmentSize">Size of the fragment</param>
1837 /// <param name="dataFragment">Message fragment data</param>
19- public MessageDataFragment ( int totalSize , int offset , ushort fragmentSize , byte [ ] dataFragment )
38+ /// <param name="sizeAndOffsetFieldSize">The field size used for <see cref="TotalSize"/> and <see cref="Offset"/>.</param>
39+ public MessageDataFragment ( int totalSize , int offset , ushort fragmentSize , byte [ ] dataFragment ,
40+ MessageDataFragmentFieldSize sizeAndOffsetFieldSize )
2041 {
2142 TotalSize = totalSize ;
2243 Offset = offset ;
2344 FragmentSize = fragmentSize ;
2445 DataFragment = dataFragment ;
46+ this . sizeAndOffsetFieldSize = sizeAndOffsetFieldSize ;
2547 }
2648
2749 /// <summary>
@@ -46,24 +68,52 @@ public MessageDataFragment(int totalSize, int offset, ushort fragmentSize, byte[
4668
4769 internal ReadOnlySpan < byte > BuildData ( )
4870 {
71+ var useTwoByteFields = sizeAndOffsetFieldSize == MessageDataFragmentFieldSize . TwoBytes ;
4972 var data = new List < byte > ( ) ;
50- data . AddRange ( Message . ConvertIntToBytes ( TotalSize ) ) ;
51- data . AddRange ( Message . ConvertIntToBytes ( Offset ) ) ;
73+ data . AddRange ( useTwoByteFields ? Message . ConvertShortToBytes ( ( ushort ) TotalSize ) : Message . ConvertIntToBytes ( TotalSize ) ) ;
74+ data . AddRange ( useTwoByteFields ? Message . ConvertShortToBytes ( ( ushort ) Offset ) : Message . ConvertIntToBytes ( Offset ) ) ;
5275 data . AddRange ( Message . ConvertShortToBytes ( FragmentSize ) ) ;
5376 data . AddRange ( DataFragment ) ;
5477 return data . ToArray ( ) ;
5578 }
5679
5780 /// <summary>Parses the message payload bytes</summary>
5881 /// <param name="data">Message payload as bytes</param>
82+ /// <param name="sizeAndOffsetFieldSize">The field size used for <see cref="TotalSize"/> and <see cref="Offset"/>.</param>
5983 /// <returns>An instance of MessageDataFragment representing the message payload</returns>
60- public static MessageDataFragment ParseData ( ReadOnlySpan < byte > data )
84+ public static MessageDataFragment ParseData ( ReadOnlySpan < byte > data ,
85+ MessageDataFragmentFieldSize sizeAndOffsetFieldSize )
6186 {
87+ var dataOffset = 0 ;
88+
89+ var totalSize = ReadValue ( sizeAndOffsetFieldSize , data , ref dataOffset ) ;
90+ var offset = ReadValue ( sizeAndOffsetFieldSize , data , ref dataOffset ) ;
91+ var fragmentSize = ( ushort ) ReadValue ( MessageDataFragmentFieldSize . TwoBytes , data , ref dataOffset ) ;
92+ var fragmentData = data . Slice ( dataOffset ) . ToArray ( ) ;
93+
6294 return new MessageDataFragment (
63- Message . ConvertBytesToInt ( data . Slice ( 0 , 4 ) . ToArray ( ) ) ,
64- Message . ConvertBytesToInt ( data . Slice ( 4 , 4 ) . ToArray ( ) ) ,
65- Message . ConvertBytesToUnsignedShort ( data . Slice ( 8 , 2 ) . ToArray ( ) ) ,
66- data . Slice ( 10 ) . ToArray ( ) ) ;
95+ totalSize ,
96+ offset ,
97+ fragmentSize ,
98+ fragmentData ,
99+ sizeAndOffsetFieldSize ) ;
100+
101+ static int ReadValue ( MessageDataFragmentFieldSize fieldSize , ReadOnlySpan < byte > data , ref int offset )
102+ {
103+ switch ( fieldSize )
104+ {
105+ case MessageDataFragmentFieldSize . TwoBytes :
106+ var twoByteValue = Message . ConvertBytesToUnsignedShort ( data . Slice ( offset , 2 ) ) ;
107+ offset += 2 ;
108+ return twoByteValue ;
109+ case MessageDataFragmentFieldSize . FourBytes :
110+ var fourByteValue = Message . ConvertBytesToInt ( data . Slice ( offset , 4 ) . ToArray ( ) ) ;
111+ offset += 4 ;
112+ return fourByteValue ;
113+ default :
114+ throw new ArgumentOutOfRangeException ( nameof ( fieldSize ) , fieldSize , null ) ;
115+ }
116+ }
67117 }
68118 }
69119}
0 commit comments