PROGRAM MAIN
VAR
Schritt : INT;
fbData : _fbData;
Index : USINT;
tmp : INT;
fbZufall : DRAND;
END_VAR
CASE Schritt OF
0:;
FOR Index := 1 TO 10 DO
fbZufall(seed := Tmp);
tmp := LREAL_TO_INT(fbZufall.Num * 100);
fbData(Code := 1, Value := tmp, Index := Index);
END_FOR
Schritt := 10;
10:;
(* Test DEL *)
fbData(code := 3, Value := tmp, Index := 1);
Schritt := 20;
20:;
(* Test INS *)
tmp := 99;
fbData(code := 2, Value := tmp, Index := 1);
Schritt := 30;
30:;
END_CASE
FUNCTION_BLOCK _fbData
VAR_INPUT
Index : UINT; (* Der gewünschte Index *)
Code : BYTE (0..3) ; (* 0 = Lesen, 1 = Schreiben, 2 = INS, 3 = DEL*)
END_VAR
VAR_IN_OUT
Value : INT; (* Der Eingabe oder Ausgabewert, je nach Wunsch *)
END_VAR
VAR_OUTPUT
n : UINT; (* Wieviel Elemente sind aktuell drin *)
OldValue : INT; (* Luxus: Der Wert des letzten gelöschen Elementes *)
END_VAR
VAR CONSTANT
MaxArray : USINT := 10; (* Hier wird der Speicher verschwendet *)
END_VAR
VAR
daten : ARRAY [1..MaxArray] OF INT ; (* Unsere Datengrube *)
memory : ARRAY [1..MaxArray] OF INT; (* Das Paralleluniversum *)
nSize : BYTE; (* Die Größe der Type in Bytes *)
dest , src : UDINT; (* Ziel und Quelladressen für das Kopieren *)
nBytes : UDINT; (* Wieviele Bytes dürfen es werden *)
bInit : BOOL := TRUE; (* Kleiner Init des FB *)
END_VAR
IF bInit THEN (* Luxus, falls mal eine andere Type benutzt wird *)
nSize := SIZEOF(Value); (* Wieviel Bytes ist die Var gross ? *)
bInit := FALSE; (* Init abgeschlossen *)
END_IF
IF Index > 0 AND Index <= MaxArray THEN
CASE Code OF
0: (* Es soll ein Wert vom Index gelesen werden *)
Value := daten[Index];
1: (* Es soll ein Wert in den Index geschrieben werden *)
daten[Index] := Value;
n := n +1 * BOOL_TO_INT(n < MaxArray); (* Den Zähler raufzählen *)
2: (* Es ist ein INS auf ein Index gewünscht, die Reihe muss also schrumpfen *)
OldValue := daten[MaxArray]; (* Wir merken uns den alten Wert, falls es jemand später braucht. *)
MEMSET(ADR(memory), 0, nSize * MaxArray); (* Wir löschen unser memory *)
IF Index = 1 THEN (* Bei 1 ist immer alles anders *)
dest := ADR(memory[2]); (* Das Ziel ist daher die 2 *)
src := ADR(daten[1]); (* Die Quelle muss 1 sein *)
nBytes := nSize * MaxArray -1; (* Wir müssen Anzahl -1 Daten schaufeln *)
ELSE
dest := ADR(memory[1]); (* Es ist ein Eintrag > 1 gewünscht, daher *)
src := ADR(daten[1]); (* Müssen wir den unteren Teil *)
nBytes := nSize * (Index -1); (* bis vor der Position retten und *)
MEMCPY(dest,src,nBytes); (* Nun den vorderen Teil kopieren *)
dest := ADR(memory[Index+1]); (* Jetzt den hinteren Teil *)
src := ADR(daten[Index]); (* Adressieren und *)
nBytes := nSize * (MaxArray - Index +1); (* Die Menge berechnen *)
END_IF
MEMCPY(dest,src,nBytes); (* Wir schaufeln den hinteren Teil rüber *)
dest := ADR(daten[1]); (* Fertig, nun alles *)
src := ADR(memory[1]); (* Für das Rücksichern *)
nBytes := SIZEOF(daten); (* Aller Daten, das dürfte schneller sein *)
MEMCPY(dest,src,nBytes); (* Nun alles in die Originaldaten schaufeln *)
n := n +1 * BOOL_TO_INT(n < MaxArray); (* Den Zähler runterzählen *)
daten[Index] := Value; (* Hier nun endlich den gewünschten Wert eintragen *)
3: (* Es ist ein DEL auf ein Index gewünscht, die Reihe muss also schrumpfen *)
OldValue := daten[Index]; (* Wir merken uns den alten Wert, falls es jemand später braucht. *)
MEMSET(ADR(memory), 0, nSize * MaxArray); (* Wir löschen unser memory *)
IF Index = 1 THEN (* Wenn der erste ! Eintrag gelöscht werden soll, dann: *)
dest := ADR(memory[1]); (* Ist das Ziel die 1 und *)
src := ADR(daten[2]); (* Die Quelle die 2 !!! *)
nBytes := nSize * MaxArray -1; (* Wir müssen Anzahl -1 Daten schaufeln *)
ELSE
dest := ADR(memory[1]); (* Es ist ein Eintrag > 1 gewünscht, daher *)
src := ADR(daten[1]); (* Müssen wir den unteren Teil *)
nBytes := nSize * (Index -1); (* Bis vor der Position retten und *)
MEMCPY(dest,src,nBytes); (* Nun den vorderen Teil kopieren *)
dest := ADR(memory[Index]); (* Jetzt den hinteren Teil *)
src := ADR(daten[Index+1]); (* Adressieren und *)
nBytes := nSize * (MaxArray - Index ); (* Die Menge berechnen *)
END_IF
MEMCPY(dest,src,nBytes); (* Wir schaufeln den hinteren Teil rüber *)
dest := ADR(daten[1]); (* Fertig, nun alles *)
src := ADR(memory[1]); (* Für das Rücksichern *)
nBytes := SIZEOF(daten); (* Aller Daten, das dürfte schneller sein *)
MEMCPY(dest,src,nBytes); (* Nun alles in die Originaldaten schaufeln *)
n := n -1 * BOOL_TO_INT(n > 0); (* Den Zähler runterzählen *)
END_CASE
ELSE
Value := -999; (* Wenn der Index Müll war bekommt er halt Müll *)
END_IF