How to refactor a code with lot of check ?
Posted: Thu Aug 20, 2015 5:15 pm
Here is one of my procedures. The job is to read a serial bus for message : a message start with 0F and end with 04. Length is variable (but indicated at fourth byte).
Code: Select all
Procedure.i RecordFrame(ClientID, List Frame.VMBFrame(), *BNin)
; This procedure read the network buffer, extract Velbus frame and save them into LinkedList (with 'VMBFrame' structure)
; ClientID = TCP Connexion ID
; proc.Return = New frames number
; USAGE :
; Global NewList msg.VMBFrame()
; cpt = RecordFrame(ClientID, msg(), *BNin)
;
LastElement(Frame())
resultat.s =""
If *BNin
If NetworkClientEvent(ClientID) = #PB_NetworkEvent_Data
RXLen = ReceiveNetworkData(ClientID, *BNin, 4096)
;Debug "-> "+readmsg(*BNin,RXLen)+" ("+Str(RXLen)+")"
t=0
FrameNumber = 0
Repeat
;Debug t
If PeekA(*BNin+t) = $0F ; search for a START $0F
fixlen = 4 ; base len : 4 bytes (0F FX @@ Size .. .. .. ## 04)
If t+fixlen < RXLen ; VERIFY if still in the buffer (no overflow)
varlen = PeekA(*BNin+t+3) & $0F ; Size byte value is just 4 bits
crcloc = t+fixlen+varlen ; CheckSum position is T actual position + 4 + Size
fintrame = crcloc+1 ; Try to find end of frame : CheckSum + 1
RelativeLen = fixlen+varlen+2 ; [0F][FX][@@][Size][Fct][][]...[##][04] = Fixlen+Size+1+1 (include byte at pos. 0)
If fintrame <= RXLen ; VERIFY if end of frame still in the buffer (no overflow again)
If PeekA(*BNin+fintrame) = $04 ; Check if a END is at the right location
; == GOOD MESSAGE ==
;Debug "GOOD : "+ReadMsg(*BNin,fintrame+1)
frameNumber + 1
AddElement(Frame())
Frame()\long.i = RelativeLen
Frame()\BFrame = AllocateMemory(RelativeLen)
Frame()\BMask = AllocateMemory(RelativeLen)
Frame()\Stamp.i = Date()
CopyMemory(*BNin+t, Frame()\BFrame, RelativeLen) ; Start is byte 0. Example: for z = 0 to RelativeLen-1 !!!
t = fintrame ; add the offset to T (don't try to search a frame in this good message)
If PeekA(Frame()\BFrame+4) = 0
buttonNb = PeekA(Frame()\BFrame+5) | PeekA(Frame()\BFrame+6) | PeekA(Frame()\BFrame+7)
Debug "Message de $"+Hex(PeekA(Frame()\BFrame+2))+" fonction "+Hex(PeekA(Frame()\BFrame+4))+" Number : "+RSet(Bin(buttonNb,#PB_Ascii),8,"0")
EndIf
Else
Debug "Frame len error"
EndIf
EndIf
Else ; No enough space in buffer for a new frame... stop the loop
t = RXLen
EndIf
EndIf
t = t + 1
Until t => RXLen
EndIf
EndIf
ProcedureReturn FrameNumber.i
EndProcedure