Přešel jsem na pole bajtů, BinaryReader mě nenapadl, navíc neumím posoudit v čem by mně pomohl. Data z portu čtu přes metodu podkladového streamu objektu SerialPort - SerialPort.BaseStream.BeginRead(mBuffer, 0, mBufferSize, acCtiDataCom, Nothing), takže binární data mám v poli bajtů mBuffer. Pro vlastní parsování přečtených dat by mně objekt BinaryReader asi nijak nepomohl. Napsal jsem si vlastní třídu, která provádí operace Append, IndexOf, Remove a GetBytes nad interním bufferem, abych dosáhl obdobné funkcionality, jakou mám u typu String už vestavěnou. Používám tam ale často ReDim a Copy, což jsou zřejmě záležitosti plýtvající pamětí a procesorovým časem. Pro moje potřeby (pole o desítkách, max. stovkách bajtů) to zatím vyhovuje. Přikládám kód, pokud tam okem odborníka objevíte nějakou zradu, která by mohla časem něco způsobit, či možnost udělat něco elegantněji dejte prosím vědět.
Public Class bArray
'Třída poskytující základní vyhledávací a kopírovací operace nad polem bajtů
Private mBuf() As Byte 'Interní buffer
Public Sub New() 'Prázdný konstruktor
End Sub
Public ReadOnly Property Length() As Integer
'Vlastnost zproetředkující aktuální délku interního bufferu
Get
Length = mBuf.Length
End Get
End Property
Public Function IndexOf(ByVal What As Byte(), ByVal From As Integer) As Integer
'Funkce vrací počáteční index prvního výskytu bajtového vzoru zadaného parametrem What v interním bufferu. Hledání počíná na indexu From
Dim Nalezen As Boolean = False
Dim IndexPrvnihoByte As Integer = System.Array.IndexOf(mBuf, What(0), From) 'Hledám první bajt v poli, který odpovídá prvnímu bajtu v hledaném vzoru
Do While IndexPrvnihoByte > -1 And IndexPrvnihoByte + What.Length <= mBuf.Length 'Cyklus přes všechny výskyty - prvni bajt vzoru v poli nalezen a v mBuf zbývá místo pro celý vzor
Nalezen = True 'Kdyby byl vzor jednobajtový tak je to on
Dim J As Integer = 1
Do While J < What.Length 'Cyklus přes zbývající bajty vzoru
If mBuf(IndexPrvnihoByte + J) <> What(J) Then 'Není shoda na pozici J vzoru, končím
Nalezen = False
Exit Do
End If
J += 1
Loop
If Nalezen Then Exit Do 'Byla shoda ve všech pozicích vzoru, nalezl jsem.
IndexPrvnihoByte = System.Array.IndexOf(mBuf, What(0), IndexPrvnihoByte + 1)
Loop
If Nalezen Then IndexOf = IndexPrvnihoByte Else IndexOf = -1
End Function
Public Function GetBytes(ByVal From As Integer, ByVal Count As Integer) As Byte()
'Fuunkce vrací bajtové pole vzniklé kopií interního bufferu od pozice From a délce Count
Dim pBuf(Count - 1) As Byte 'Nadefinuji pomocný buffer potřebné velikosti
System.Array.Copy(mBuf, From, pBuf, 0, Count) 'Zkopíruji do něj příslušnou část pole
GetBytes = pBuf 'Vrátím hodnotu
End Function
Public Sub Append(ByVal ibuf As Byte(), ByVal Count As Integer)
'Metoda přidá z bajtového pole zadaného parametrem ibuf Count bajtů na konec interního bufferu
Dim mBufIndex As Integer 'Index v interním bufferu
If mBuf Is Nothing Then 'Buffer ještě nebyl inicializován
mBufIndex = 0
ReDim mBuf(mBufIndex - 1)
Else
mBufIndex = mBuf.Length
End If
ReDim Preserve mBuf(mBuf.Length + Count - 1) 'Dimenzuju interní buffer přesně na potřebnou velikost se zachováním obsahu
System.Array.Copy(ibuf, 0, mBuf, mBufIndex, Count) 'Zkopíruju přidávané bajty do interního bufferu
End Sub
Public Sub Remove(ByVal Count As Integer)
'Metoda odstraní ze začátku interního bufferu Count bajtů a zredukuje interní buffer na aktuální velikost
Dim pBuf(mBuf.Length - Count - 1) As Byte 'Nadefinuji pomocný buffer potřebné velikosti
System.Array.Copy(mBuf, Count, pBuf, 0, mBuf.Length - Count) 'Odložím do něj data, která mají v interním bufferu zůstat
ReDim mBuf(mBuf.Length - Count - 1) 'Dimenzuju interní buffer přesně na potřebnou velikost a vymažu obsah
System.Array.Copy(pBuf, 0, mBuf, 0, mBuf.Length) 'Zkopíruju data, která mají v interním bufferu zůstat z pomocného bufferu zpět
End Sub
End Class
|