unit filterunit; {$mode objfpc}{$H+} interface uses Classes, SysUtils; type tAbfahrt = record haltestellenId: integer; linie,ziel,richtung: string; sAn,sAb,iAn,iAb: tDateTime; end; tFilterKriterium = (fkZeit,fkLinie,fkHaltestelle); tBoolOperation = (boPush1,boPop1,boPush2,boPop2, boNot,boAnd,boOr, boSet,boPropablySet,boClr, boTrust,boMistrust, boDrop,boCopy); tFilter = class kriterien: array of tFilterKriterium; vergleiche: array of string; verknuepfung: array of tBoolOperation; function regelErfuellt(abf: tAbfahrt; genuegsamkeit: byte): boolean; constructor create(var f: textfile); destructor destroy; override; end; function extractTime(source: string): tDateTime; function extract(verifyer,source: string): string; overload; function extract(verifyer,source: string; out tag: string): string; overload; implementation uses math, lowlevelUnit; function tFilter.regelErfuellt(abf: tAbfahrt; genuegsamkeit: byte): boolean; var i: longint; stack1,stack2,reg: array of byte; begin setlength(stack1,0); setlength(stack2,0); setlength(reg,min(length(kriterien),length(vergleiche))); for i:=0 to length(reg)-1 do case kriterien[i] of fkZeit: reg[i]:=max(byte(abf.sAb - now < strtotime(vergleiche[i])), 2*byte(abf.iAb - now < strtotime(vergleiche[i]))); fkLinie: reg[i]:=2*byte(strtoint(abf.Linie) = strtoint(vergleiche[i])); fkHaltestelle: reg[i]:=2*byte(abf.haltestellenId = strtoint(vergleiche[i])); end{of Case}; for i:=0 to length(verknuepfung)-1 do case verknuepfung[i] of boNot: reg[length(reg)-1]:=2-reg[length(reg)-1]; boPush1: begin setlength(stack1,length(stack1)+1); stack1[length(stack1)-1]:=reg[length(reg)-1]; setlength(reg,length(reg)-1); end; boPop1: begin setlength(reg,length(reg)+1); reg[length(reg)-1]:=stack1[length(stack1)-1]; setlength(stack1,length(stack1)-1); end; boPush2: begin setlength(stack2,length(stack2)+1); stack2[length(stack2)-1]:=reg[length(reg)-1]; setlength(reg,length(reg)-1); end; boPop2: begin setlength(reg,length(reg)+1); reg[length(reg)-1]:=stack1[length(stack2)-1]; setlength(stack2,length(stack2)-1); end; boAnd: begin reg[length(reg)-2]:=min(reg[length(reg)-1],reg[length(reg)-2]); setlength(reg,length(reg)-1); end; boOr: begin reg[length(reg)-2]:=max(reg[length(reg)-1],reg[length(reg)-2]); setlength(reg,length(reg)-1); end; boSet: reg[length(reg)-1]:=2; boPropablySet: reg[length(reg)-1]:=1; boClr: reg[length(reg)-1]:=0; boDrop: setlength(reg,length(reg)-1); boTrust: reg[length(reg)-1]:=2*byte(reg[length(reg)-1]<>0); boMistrust: reg[length(reg)-1]:=2*byte(reg[length(reg)-1]=2); boCopy: begin setlength(reg,length(reg)+1); reg[length(reg)-1]:=reg[length(reg)-2]; end; end{of case}; result:=reg[0]>=genuegsamkeit; setlength(reg,0); setlength(stack1,0); setlength(stack2,0); end; constructor tFilter.create(var f: textfile); var s: string; i: byte; begin inherited create; setlength(kriterien,0); setlength(vergleiche,0); setlength(verknuepfung,0); i:=0; while not eof(f) do begin readln(f,s); if s=':filter' then exit; if (length(s)=0) or (s[1]='#') then continue; if s=':filter:' then begin if i<>0 then raise exception.create('Ich habe zu häufig '':filter:''!'); inc(i); continue; end; case i of 0: begin setlength(kriterien,length(kriterien)+1); case s[1] of 't': kriterien[length(kriterien)-1]:=fkZeit; 'l': kriterien[length(kriterien)-1]:=fkLinie; 'h': kriterien[length(kriterien)-1]:=fkHaltestelle; else raise Exception.create('Ich kenne Kriterium '''+s[1]+''' nicht!'); end{of Case}; delete(s,1,1); setlength(vergleiche,length(vergleiche)+1); vergleiche[length(vergleiche)-1]:=s; end; 1: begin setlength(verknuepfung,length(verknuepfung)+1); case s[1] of '-': verknuepfung[length(verknuepfung)-1]:=boNot; '&': verknuepfung[length(verknuepfung)-1]:=boAnd; '|': verknuepfung[length(verknuepfung)-1]:=boOr; '0': verknuepfung[length(verknuepfung)-1]:=boClr; '1': verknuepfung[length(verknuepfung)-1]:=boPropablySet; '2': verknuepfung[length(verknuepfung)-1]:=boSet; 'v': verknuepfung[length(verknuepfung)-1]:=boPush1; '^': verknuepfung[length(verknuepfung)-1]:=boPop1; '<': verknuepfung[length(verknuepfung)-1]:=boPush2; '>': verknuepfung[length(verknuepfung)-1]:=boPop2; '*': verknuepfung[length(verknuepfung)-1]:=boDrop; '~': verknuepfung[length(verknuepfung)-1]:=boCopy; 'T': verknuepfung[length(verknuepfung)-1]:=boTrust; 'M': verknuepfung[length(verknuepfung)-1]:=boMistrust; else raise exception.create('Ich kenne Verknüpfung '''+s[1]+''' nicht!'); end{of Case}; end; end{of Case}; end; raise exception.create('Unerwartetes Dateiende!'); end; destructor tFilter.destroy; var i: longint; begin for i:=0 to length(vergleiche)-1 do vergleiche[i]:=''; setlength(kriterien,0); setlength(vergleiche,0); setlength(verknuepfung,0); inherited destroy; end; function extractTime(source: string): tDateTime; var ja,mo,ta,st,mi,se: word; begin ja:=strtoint(erstesArgument(source,'-')); mo:=strtoint(erstesArgument(source,'-')); ta:=strtoint(erstesArgument(source,'T')); st:=strtoint(erstesArgument(source,':')); mi:=strtoint(erstesArgument(source,':')); se:=strtoint(source); result:=encodeDate(ja,mo,ta)+encodeTime(st,mi,se,0); end; function extract(verifyer,source: string): string; overload; begin result:=''; if (pos('<'+verifyer+'>',source)>0) or (pos('<'+verifyer+' ',source)>0) then begin delete(source,1,pos('<'+verifyer,source)+length('<'+verifyer)-1); delete(source,1,pos('>',source)); result:=copy(source,1,pos('',source)-1); end; end; function extract(verifyer,source: string; out tag: string): string; overload; begin result:=''; tag:=''; if (pos('<'+verifyer+'>',source)>0) or (pos('<'+verifyer+' ',source)>0) then begin delete(source,1,pos('<'+verifyer,source)+length('<'+verifyer)-1); tag:=copy(source,2,pos('>',source)-2); delete(source,1,pos('>',source)); result:=copy(source,1,pos('',source)-1); end; end; end.