Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: sort variable line-length binary buffers
GOSUB INITFUNCTION ; Make sort_records function available. GOTO EXAMPLE2 ; Example 1 - sort variable length file/buffer File="F:\Winbatch\Commands\setupscript.wbt" X=BinaryAlloc(FileSize(File)) ; Get size of buffer for file to sort. BinaryRead(X,File) ; Load file into buffer. Started=TimeYMDHMS() ; Timing. Newfile=sort_Records(1,X,0,1,0,300,@CrLf,0) ; Call function - see parm description in function. BinaryFree(X) ; Free buffer. IF Newfile==-1 Message("oops","bad parm") ; Oops. EXIT ENDIF Display(3,"Sorted",StrCat("Time:",TimeDiffSecs(TimeYMDHMS(),Started)," seconds")) ; How long did it take. X=FileCreateTemp("srt") ; Create temp file for newly sorted records. BinaryWrite(Newfile,X) ; Create newly sorted file. BinaryFree(Newfile) ; Free buffer. EXIT ; Example 2 - sort an item list :EXAMPLE2 Data="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" List="" FOR X=1 TO 500 ; Create number of test items. List=ItemInsert(StrCat(StrSub(Data,Random(25)+1,10),"",StrSub(Data,Random(25)+1,10),"",StrSub(Data,Random(25)+1,10)),-1,List,":") NEXT Newlist=sort_Records(0,List,0,5,0,50,":",1) ; Call function - see parm description in function. Message(" ",StrReplace(Newlist,":",@CrLf)) EXIT :INITFUNCTION ; Sort_Records function ; Written by Steffen Fraas sfraas@zoo.co.uk 01/03/2001 #DefineFunction sort_Records(Intype,Input,Sort_sequence,Start_sort_on_column,Sort_number_of_columns,Max_line_length,Delim,Gx) ; Intype - 1 binary buffer, 0 itemstring ; Input - binary buffer/itemstring containing lines to be sorted ; Sort_sequence - 1 ascending, 0 descending ; Start_sort_on_column - start sorting on column x ; Sort_number_of_columns - number of columns to sort on, 0 to rest of line ; Max_line_length - maximum line length ; Delim - single or multi byte line delimiter ; Gx - 1 progress bar, 0 no progress bar ; ; Test return value for 1 integer, 2 string, 65 binary buffer, using the VarType instruction. ; ; Return (address of a new sorted binary buffer) or ; Return (itemstring of newly sorted itemstring) or ; return (-1) sort aborted - bad input parms ; return (-2) no data to sort ; return (-3) line length exceeded GOSUB SETCONSTANTS ; Setup details. IF Retcode<>0 THEN RETURN (Retcode) ; Something's wrong with parms/input. Brk=BinaryEodGet(Rbuf)-1 IF BrkBrk THEN GOTO ENDIN ; Go through input buffer. Ll = BinaryIndexEx(Rbuf,Ls,Delim,@FwdScan,1)-Ls ; Ll is length of current line minus delimiter. IF Ll < 0 THEN Ll=Brk-Ls+1 ; If delimiter not found. End of buffer;remaining data. THEN Rc=0 ; Delimiter required. Tsf=Tsf+1 ; Records processed. IF Gx THEN aStatusBar(1,StrCat("Reading in... ",Tbar,"lines"),"Input phase",Tbar,Tsf) ; Show progress. IF Ll > Xl THEN GOTO MAXLINE ; Max line exceeded. IF Rc THEN BinaryCopy(Wbuf,Ose,Rbuf,Ls,Ll+Dx) ; If trailing delim, copy data + delim into wbuf. ELSE BinaryCopy(Wbuf,Ose,Rbuf,Ls,Ll) ; Copy data only, no delim. ELSE BinaryPokeStr(Wbuf,BinaryEodGet(Wbuf),Delim) ; Add missing delim, should be last rec. Ls=Ls+Ll+Dx ; Add length of old data + delim. Ose=Ose+Xl2 ; Incr o/p buffer offset. GOTO STARTIN :ENDIN BinaryEodSet(Wbuf,Ose) ; Set eod. IF Sort_sequence THEN BinarySort(Wbuf,Xl2,Start_sort_on_column-1,Sort_number_of_columns,@String|@Ascending) ; Sort lines in asc. ELSE BinarySort(Wbuf,Xl2,Start_sort_on_column-1,Sort_number_of_columns,@String|@Descending) ; Sort in desc. Ose=0 ; Offset for i/p buffer. Tsf=0 Ls=BinaryIndex(Wbuf,0,"",@FwdScan) ; Skip over nulls in asc sort, 0 in des. FOR X=1 TO Tbar ; Go through input buffer, now fixed xl2 length. BinaryCopy(Wbuf,Ose,Wbuf,Ls,Xl2) ; Create output. Ose=BinaryIndexNc(Wbuf,Ose+Xl2-1,"",@BackScan)+1 ; Find first non null, should be delimiter. Ls=Ls+Xl2 ; Input buffer's new offset. Tsf=Tsf+1 ; O/p lines created. IF Gx THEN aStatusBar(1,StrCat("Writing out... ",Tbar," lines"),"Output phase",Tbar,Tsf) ; Show progress. NEXT IF Gx THEN aStatusBar(2,"","",0,0) ; Close bar. IF Rc THEN BinaryEodSet(Wbuf,Ose) ; Set eod last rec had a delimiter. ELSE BinaryEodSet(Wbuf,Ose-Dx) ; This one did not. IF Intype THEN RETURN (Wbuf) ; Return newly sorted buffer. BinaryFree(Rbuf) ; Delete input buffer. Input2=BinaryPeekStr(Wbuf,0,BinaryEodGet(Wbuf)) ; New itemstring. BinaryFree(Wbuf) ; Free output buffer. RETURN (Input2) ; Finished. :MAXLINE IF Gx THEN aStatusBar(2,"","",0,0) ; Close bar. Badline=BinaryPeekStr(Rbuf,Ls,Min(Xl,Ll)) ; Get bad line. Display(3,"Line %Tsf% length exceeded - Sort aborted",Badline) BinaryFree(Wbuf) ; Free output buffer. IF Intype THEN RETURN (-3) ; Line length exceeded code. BinaryFree(Rbuf) ; Free input itemstring buffer. RETURN (-3) ; Itemstring line length exceeded. :SETCONSTANTS Retcode=-1 ; Assume bad parms. AddExtender("wwsop34i.DLL") ; Used for graph and retry. Ls=0 ; # of bytes read so far. Ose=0 ; Offset for o/p buffer. Tsf=0 ; No of lines sorted. Rc=1 ; Line has delimiter. Tbar=0 ; Astatusbus total. IF !(Gx==0 || Gx==1) THEN RETURN ; Invalid graph request. IF !StrLen(Delim) THEN RETURN ; Zero length delimiter. Dx=StrLen(Delim) ; Size of delimiter. IF !(IsNumber(Sort_sequence) && IsNumber(Start_sort_on_column) && IsNumber(Sort_number_of_columns) && IsNumber(Max_line_length)) THEN RETURN ; Ensure all numerical values. IF !(Sort_sequence==0 || Sort_sequence==1) THEN RETURN ; Not ascending or descending. IF Max_line_length<1 THEN RETURN ; Invalid max length. Xl=Max_line_length Xl2=Xl+Dx ; Size of each record. IF Start_sort_on_column<1 || Start_sort_on_column>Xl THEN RETURN ; Invalid start sort column. IF Sort_number_of_columns<0 || Sort_number_of_columns>Max_line_length THEN RETURN ; In invalid sort number of columns. IF Sort_number_of_columns==0 THEN Sort_number_of_columns=Xl-Start_sort_on_column+1 ; Default sort number of columns. IF Sort_number_of_columns>Xl-Start_sort_on_column+1 THEN RETURN ; Sort number of columns exceed max length. Retcode=0 ; Parms ok. IF Intype THEN IF BinaryEodGet(Input)<1 THEN Retcode=-2 ; Nothing to sort. IF !Intype THEN IF !StrLen(Input) THEN Retcode=-2 ; Nothing to sort. IF Retcode<>0 THEN RETURN ; Bad parms, or bad input. IF !Intype THEN Rbuf=BinaryAlloc(StrLen(Input)) ; Alloc buffer for itemstring. THEN BinaryPokeStr(Rbuf,0,Input) ; Load item string into a binary buffer. ELSE Rbuf=Input ; Lines in binary buffer to sort. RETURN #EndFunction ; End of function. RETURN ; Function's `log on` return.
Article ID: W14997
File Created: 2001:11:08:12:41:18
Last Updated: 2001:11:08:12:41:18