;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffileadd",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffileadd
#DefineFunction udfFileAdd (InFileA, InFileB, OutFile)
; We must have an OutFilename.
If (OutFile=="") Then Return @FALSE
fsizeA=FileSize(InFileA)
fsizeB=FileSize(InFileB)
Select 1
Case((fsizeA==0)&&(fsizeB==0))
Return @FALSE
Break
Case((fsizeA==0)&&(fsizeB>0))
Return FileCopy(InFileB,OutFile,@FALSE)
Break
Case((fsizeA>0)&&(fsizeB==0))
Return FileCopy(InFileA,OutFile,@FALSE)
Break
Case((fsizeA>0)&&(fsizeB>0))
If FileCopy(InFileA,OutFile,@FALSE)
Return FileAppend(InFileB,OutFile)
EndIf
Break
EndSelect
Return @FALSE
; Detlev Dalitz.20010713
#EndFunction
:skip_udffileadd
;------------------------------------------------------------------------------------------------------------------------------------------
;--- test ---
; Create test environment.
InFileA=FileCreateTemp("TMP")
InFileB=FileCreateTemp("TMP")
; We use this script to create test data.
ThisFile=IntControl(1004,0,0,0,0)
FileCopy(ThisFile,InFileA,@FALSE)
FileCopy(ThisFile,InFileB,@FALSE)
OutFile=FileCreateTemp("TMP")
For i=1 To 5
Select i
Case 1
result = udfFileAdd(InFileA,InFileB,OutFile)
Break
Case 2
result = udfFileAdd("",InFileB,OutFile)
Break
Case 3
result = udfFileAdd(InFileA,"",OutFile)
Break
Case 4
result = udfFileAdd("","",OutFile)
Break
Case 5
result = udfFileAdd("","","")
Break
EndSelect
Display(2,"Demo udfFileAdd (InFileA, InFileB, OutFile)",StrCat("Test",i,@TAB," Result=",result))
If FileExist(OutFile)
; Take a look and wait for closing notepad.
RunZoomWait("notepad",OutFile)
FileDelete(OutFile)
Else
Display(2,"Demo udfFileAdd (InFileA, InFileB, OutFile)","No OutFile to view ...")
EndIf
Next
; Cleaning.
FileDelete(InFileA)
FileDelete(InFileB)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
udfBinaryFill (handle, offset, count, filler)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfbinaryfill",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfbinaryfill
#DefineFunction udfBinaryFill (handle, offset, count, filler)
Return (BinaryPokeStr(handle,offset,StrFill(filler,count)))
; Detlev Dalitz.20010713
#EndFunction
:skip_udfbinaryfill
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
bb = BinaryAlloc(1000)
num = udfBinaryFill(bb,0,1000,"QQQ ")
num = udfBinaryFill(bb,11,20,"#")
num = udfBinaryFill(bb,90,10,"#")
str = BinaryPeekStr(bb,0,BinaryEodGet(bb))
BinaryFree(bb)
Message("Demo udfBinaryFill (handle, offset, count, filler)",str)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
udfFileGetMaxLineLen (sFilename)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffilegetmaxlinelen",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffilegetmaxlinelen
#DefineFunction udfFileGetMaxLineLen (sFilename)
iFileSize = FileSize(sFilename)
If (iFileSize==0) Then Return (0) ; Nothing to do.
sMsgText = StrCat("udfFileGetMaxLineLen (",sFilename,") LineSize=")
InStudio = (RtStatus()==10)
hBB = BinaryAlloc(iFileSize+2)
BinaryReadEx(hBB,1,sFilename,0,iFileSize)
BinaryPokeStr(hBB,0,@LF)
BinaryPokeStr(hBB,BinaryEodGet(hBB),@CR)
iLineCount = BinaryStrCnt(hBB,0,BinaryEodGet(hBB)-1,@CRLF)
iLineAvg = iFileSize/Max(iLineCount,1)
iLineSize = 0
Select ((iLineAvg < 30) && (iLineCount > 1000))
; The magic is to set the proper values for auto switching between the methods.
; Is there any rule?
Case @TRUE
BinaryPokeStr(hBB,0,StrClean(BinaryPeekStr(hBB,0,BinaryEodGet(hBB)-1),@CRLF," ",@FALSE,2))
sSearch = StrCat(@LF,@CR)
While @TRUE
If InStudio Then wStatusMsg(StrCat(sMsgText,iLineSize))
BinaryReplace(hBB,sSearch,"",@FALSE)
If (BinaryEodGet(hBB)<=iLineSize) Then Break
iLineSize = iLineSize + 1
sSearch = StrCat(@LF,StrFill(" ",iLineSize),@CR)
EndWhile
Break
Case @FALSE
sBBTag = BinaryTagInit(hBB,@LF,@CR)
While @TRUE
If InStudio Then wStatusMsg(StrCat(sMsgText,iLineSize))
sBBTag = BinaryTagFind(sBBTag)
If (sBBTag=="") Then Break
iLineSize = Max(iLinesize,BinaryTagLen(sBBTag,0))
EndWhile
Break
EndSelect
BinaryFree(hBB)
Return (iLineSize)
;..........................................................................................................................................
; This Function "udfFileGetMaxLineLen" returns the maximal line length of lines in a file.
; This udf combines two lookup algorithms:
; 1. If the file has many many lines with each small line length (I claim this special algorithm as my invention).
; 2. If the file has not so many lines but each with larger length (standard algorithm).
;..........................................................................................................................................
; Detlev Dalitz.20010714
;..........................................................................................................................................
#EndFunction
:skip_udffilegetmaxlinelen
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
sFilename1 = IntControl(1004,0,0,0,0) ; We use this file as test input.
iLineLengthMax1 = udfFileGetMaxLineLen(sFilename1)
sFilename2 = StrCat(DirHome(),"wil.clr") ; We use "wil.clr" file as test input.
iLineLengthMax2 = udfFileGetMaxLineLen(sFilename2)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
udfOneWordPerLine (sFilenameIn, sFilenameOut)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfonewordperline",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfonewordperline
#DefineFunction udfOneWordPerLine (sFilenameIn, sFilenameOut)
iFileSize = FileSize(sFilenameIn)
If (iFileSize==0) Then Return (@FALSE)
If (sFilenameOut=="") Then sFilenameOut = sFilenameIn ; Caution: Overwrite input file.
hBBXlate = BinaryAlloc(256)
sFilenameXlate = StrCat(Environment("temp"),"\myxlate.tmp")
; sFilenameXlate = FileCreateTemp("XLT")
If !FileExist(sFilenameXlate)
; Writing xlate table.
GoSub PokeTable
BinaryWrite(hBBXlate,sFilenameXlate)
Else
; Loading xlate table.
BinaryRead(hBBXlate,sFilenameXlate)
EndIf
; Transforming.
hBB = BinaryAlloc(iFileSize)
BinaryRead(hBB,sFilenameIn)
BinaryConvert(hBB,0,1,0,0) ; From ansi to oem, because my table is designed for ascii chars.
BinaryXlate(hBB,hBBXlate,0) ; Apply Xlate table.
BinaryFree(hBBXlate)
BinaryConvert(hBB,1,0,0,0) ; From oem to ansi.
While BinaryReplace(hBB," "," ",@TRUE)
EndWhile
iFileSize = BinaryWrite(hBB,sFilenameOut)
iBlankCount = BinaryStrCnt(hBB,0,BinaryEodGet(hBB)-1," ")
BinaryFree(hBB)
hBB = BinaryAlloc(iFileSize+iBlankCount+2+1)
BinaryReadEx(hBB,1,sFilenameOut,0,iFileSize)
BinaryPokeStr(hBB,0,@LF)
BinaryPokeStr(hBB,BinaryEodGet(hBB),@CR)
BinaryReplace(hBB," ",@CRLF,@TRUE)
; Delete all blank lines.
sSearch = StrCat(@LF,@CR)
While BinaryReplace(hBB,sSearch,"",@TRUE)
EndWhile
BinaryPokeStr(hBB,BinaryEodGet(hBB),@LF)
BinaryWriteEx(hBB,0,sFilenameOut,0,-1)
BinaryWriteEx(hBB,1,sFilenameOut,0,BinaryEodGet(hBB)-1)
BinaryFree(hBB)
Return (@TRUE)
;..........................................................................................................................................
:PokeTable
;--- translation table ascii -----------------------------------------------------------------------
;Codes 0 1 2 3 4 5 6 7 8 9 A B C D E F
sRow0 ="032 032 032 032 032 032 032 032 032 032 032 032 032 032 032 032" ; 0x0- ; " "
sRow1 ="032 032 032 032 032 032 032 032 032 032 032 032 032 032 032 032" ; 0x1- ; " "
sRow2 ="032 032 032 035 036 037 038 032 032 032 032 032 032 045 032 032" ; 0x2- ; " #$ & - " ; [pct]=037
sRow3 ="048 049 050 051 052 053 054 055 056 057 032 032 032 032 032 032" ; 0x3- ; "0123456789 "
sRow4 ="064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079" ; 0x4- ; "@ABCDEFGHIJKLMNO"
sRow5 ="080 081 082 083 084 085 086 087 088 089 090 032 032 032 032 095" ; 0x5- ; "PQRSTUVWXYZ _"
sRow6 ="032 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111" ; 0x6- ; " abcdefghijklmno"
sRow7 ="112 113 114 115 116 117 118 119 120 121 122 032 032 032 032 032" ; 0x7- ; "pqrstuvwxyz "
sRow8 ="128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143" ; 0x8- ; "ÇüéâäàåçêëèïîìÄÅ"
sRow9 ="144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159" ; 0x9- ; "ÉæÆôöòûùÿÖÜø£Ø׃"
sRow10="160 161 162 163 164 165 166 167 032 032 032 032 032 032 032 032" ; 0xA- ; "áíóúñѪº "
sRow11="032 032 032 032 032 032 032 032 032 032 032 032 032 032 032 032" ; 0xB- ; " "
sRow12="032 032 032 032 032 032 032 032 032 032 032 032 032 032 032 032" ; 0xC- ; " "
sRow13="032 032 032 032 032 032 032 032 032 032 032 032 032 032 032 032" ; 0xD- ; " "
sRow14="224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239" ; 0xE- ; "ÓßÔÒõÕµþÞÚÛÙýݯ´"
sRow15="032 032 032 032 032 032 032 032 032 032 032 032 032 032 032 032" ; 0xF- ; " "
;--- translation table ascii -----------------------------------------------------------------------
For iRow=0 To 15
For iCol=0 To 15
BinaryPoke(hBBXlate,(16*iRow)+iCol,ItemExtract(1+iCol,sRow%iRow%," "))
Next
Drop(sRow%iRow%)
Next
Return ; from GoSub
;..........................................................................................................................................
; This function "udfOneWordPerLine" creates a file with a single word on each line from a given textfile.
; This function can be used as a first step for creating an indexlist or "Konkordanz"
; (Note: Duplicates have to removed afterwards).
;
; Detlev Dalitz.20010101.20030702
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------
:skip_udfonewordperline
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffiletoitemlist",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffiletoitemlist
#DefineFunction udfFileToItemList (sFilename, sDelimiter)
iBBSize = FileSize(sFilename)
If !iBBSize Then Return ("")
hBB = BinaryAlloc(iBBSize)
BinaryRead(hBB,sFilename)
sItemList = BinaryPeekStr(hBB,0,iBBSize)
BinaryFree(hBB)
sItemList = StrReplace(sItemList,@CRLF,@CR)
sItemList = StrReplace(sItemList,@LF,@CR)
sItemList = StrReplace(sItemList,@CR,sDelimiter)
Return (sItemList)
;..........................................................................................................................................
; Create itemlist from txtfile with EOL=CR or EOL=LF or EOL=CRLF
; Example: MyItemList = udfFileToItemList(myfile,@TAB)
;..........................................................................................................................................
#EndFunction
:skip_udffiletoitemlist
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfitemlisttofile",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfitemlisttofile
#DefineFunction udfItemListToFile (sItemList, sDelimiter, sFilename)
If (sItemList=="") Then Return (0)
sItemList = StrReplace(sItemList,sDelimiter,@CRLF)
hBB = BinaryAlloc(StrLen(sItemList))
BinaryPokeStr(hBB,0,sItemList)
iResult = BinaryWrite(hBB,sFilename)
BinaryFree(hBB)
Return (iResult)
;..........................................................................................................................................
; Create txtfile with EOL=CRLF from ItemList
; Example: ItemListToFile(mylist,@TAB,myfile)
;..........................................................................................................................................
#EndFunction
:skip_udfitemlisttofile
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfsorttextfile",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfsorttextfile
#DefineFunction udfSortTextFile (sFilenameIn, sFilenameOut, iDirection)
Select iDirection
Case @ASCENDING
Return (udfItemListToFile(ItemSort(udfFileToItemList(sFilenameIn,@CR),@CR),@CR,sFilenameOut))
Break
Case @DESCENDING
Return (udfItemListToFile(udfReverseList(ItemSort(udfFileToItemList(sFilenameIn,@CR),@CR),@CR),@CR,sFilenameOut))
Break
EndSelect
Return (@FALSE)
#EndFunction
:skip_udfsorttextfile
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udftrimlistdup",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udftrimlistdup
#DefineFunction udfTrimListDup (sItemList, sDelimiter)
sTrimList = ""
iCount = ItemCount(sItemList,sDelimiter)
For i=1 To iCount
sItem = ItemExtract(i,sItemList,sDelimiter)
If (sItem>"") Then If !ItemLocate(sItem,sTrimList,sDelimiter) Then sTrimList = ItemInsert(sItem,-1,sTrimList,sDelimiter)
Next
Return (sTrimList)
#EndFunction
:skip_udftrimlistdup
;------------------------------------------------------------------------------------------------------------------------------------------
;--- test ---
sFilenameIn = IntControl(1004,0,0,0,0) ; We use this script for test input.
sFilenameTmp = FileCreateTemp("TMP") ; Temporary file for test output.
; Build a file with single word on each line.
; Words are listed in order of original occurance.
udfOneWordPerLine (sFilenameIn, sFilenameTmp)
RunWait("notepad", sFilenameTmp) ; Wait for closing notepad.
; Build a file with single word on each line but sorted.
udfSortTextFile (sFilenameTmp, sFilenameTmp, @ASCENDING)
RunWait("notepad", sFilenameTmp) ; Wait for closing notepad.
; Build a condensed file with unique word on each line.
sItemList = udfFileToItemList (sFilenameTmp, @LF)
sItemList = udfTrimListDup (sItemList, @LF)
udfItemListToFile (sItemList, @LF, sFilenameTmp)
RunWait("notepad", sFilenameTmp) ; Wait for closing notepad.
FileDelete(sFilenameTmp) ; Cleaning.
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
udfFileSetEOLTo (sFilename, sDelimiter)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffileseteolto",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffileseteolto
#DefineFunction udfFileSetEOLTo (sFilename, sDelimiter)
iBBsize = FileSize(sFilename)
If (iBBsize==0) Then Return (0) ; Nothing to do.
If (sDelimiter!=@CRLF) Then If (sDelimiter!=@CR) Then If (sDelimiter!=@LF) Then Return (0) ; Nothing to do.
hBB = BinaryAlloc(iBBsize)
BinaryRead(hBB,sFilename)
iAdd = -2 * BinaryStrCnt(hBB,0,iBBsize-1,@CRLF)
iAdd = iAdd + BinaryStrCnt(hBB,0,iBBsize-1,@CR)
iAdd = iAdd + BinaryStrCnt(hBB,0,iBBsize-1,@LF)
BinaryFree(hBB)
iBBsize = iBBsize + iAdd
bb = BinaryAlloc(iBBsize)
BinaryRead(hBB,sFilename)
BinaryReplace(hBB, @CRLF, @LF, @TRUE)
BinaryReplace(hBB, @CR, @LF, @TRUE)
BinaryReplace(hBB, @LF, @CRLF, @TRUE)
If (sDelimiter!=@CRLF) Then BinaryReplace(hBB,@CRLF,sDelimiter,@TRUE)
iBBsize = BinaryWrite(hBB,sFilename)
BinaryFree(hBB)
Return (iBBsize)
;..........................................................................................................................................
; This function udfFileSetEOLTo() normalizes a given textfile's End-Of-Line sequences,
; and set the End-Of-Line sequences to the given eol-delimiter, that can be @CRLF or @CR or @LF.
;..........................................................................................................................................
; Detlev Dalitz.20010713.20020715
;..........................................................................................................................................
#EndFunction
:skip_udffileseteolto
;------------------------------------------------------------------------------------------------------------------------------------------
;--- test ---
sFilenameFrom = IntControl(1004,0,0,0,0) ; We use a copy of this file as test input.
sFilename = FileMapName(sFilenameFrom, Environment("temp"))
iResult = FileCopy(sFilenameFrom,sFilename,@FALSE)
sDelimiter = @TAB ; No change, @TAB is not allowed in this case.
iFileSize = udfFileSetEOLTo (sFilename, sDelimiter)
sDelimiter = @CR
iFileSize = udfFileSetEOLTo (sFilename, sDelimiter)
sDelimiter = @CRLF
iFileSize = udfFileSetEOLTo (sFilename, sDelimiter)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
udfFileSetEOLToCRLF (sFilename)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffileseteoltocrlf",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffileseteoltocrlf
#DefineFunction udfFileSetEOLToCRLF (sFilename)
iBBsize = FileSize(sFilename)
If (iBBsize==0) Then Return (iBBsize) ; Nothing to do.
iBBmin = 0
iBBmax = iBBsize - 1
hBB = BinaryAlloc(iBBsize)
BinaryRead(hBB,sFilename)
iAdd = -2 * BinaryStrCnt(hBB,iBBmin,iBBmax,@CRLF)
iAdd = iAdd + BinaryStrCnt(hBB,iBBmin,iBBmax,@CR)
iAdd = iAdd + BinaryStrCnt(hBB,iBBmin,iBBmax,@LF)
BinaryFree(hBB)
If (iAdd==0) Then Return (iBBsize) ; Nothing to do.
iBBsize = iBBsize + iAdd
hBB = BinaryAlloc(iBBsize)
BinaryRead(hBB,sFilename)
BinaryReplace(hBB, @CRLF, @LF, @TRUE)
BinaryReplace(hBB, @CR, @LF, @TRUE)
BinaryReplace(hBB, @LF, @CRLF, @TRUE)
iBBsize = BinaryWrite(hBB,sFilename)
BinaryFree(hBB)
Return (iBBsize)
;..........................................................................................................................................
; This function udfFileSetEOLToCRLF() normalizes a given
; textfile's End-Of-Line sequences to the standard DOS two byte sequence @CRLF.
; Single @CR or @LF will be changed to @CRLF.
;..........................................................................................................................................
; Detlev Dalitz.20010722.20020715
;..........................................................................................................................................
#EndFunction
:skip_udffileseteoltocrlf
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
sFilename = IntControl(1004,0,0,0,0) ; We use this file as test input.
iFileSize = udfFileSetEOLToCRLF (sFilename)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfisstringinfile",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfisstringinfile
#DefineFunction udfIsStringInFile (sFilename, iOffset, sSearchStr, iDirection, iMatchCase)
iFileSize = FileSize(sFilename)
If (iFileSize == 0) Then Return (@FALSE)
If (iOffset < 0) Then Return (@FALSE)
If (iOffset > FileSize(sFilename)-1) Then Return (@FALSE)
hBB = BinaryAlloc(iFileSize)
BinaryRead(hBB,sFilename)
iBool = (BinaryIndexEx(hBB,iOffset,sSearchStr,iDirection,iMatchCase) > -1)
BinaryFree(hBB)
Return (iBool)
#EndFunction
:skip_udfisstringinfile
;------------------------------------------------------------------------------------------------------------------------------------------
;--- test ---
sFilename = IntControl(1004,0,0,0,0) ; We use this file as test input.
If udfIsStringInFile(sFilename,0,"Test",@FWDSCAN,0)
Message ("Demo udfIsStringInFile","String found")
Else
Message ("Demo udfIsStringInFile","String NOT found")
EndIf
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
udfFileShrink (sFilename, iShrinkSize, iMode)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffileshrink",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffileshrink
#DefineFunction udfFileShrink (sFilename, iShrinkSize, iMode)
iFileSize = FileSizeEx(sFilename)
If !iFileSize Then Return (0)
iShrinkSize = Min(iFileSize,Max(0,iShrinkSize))
If !iShrinkSize Then Return (iFileSize)
hbb = BinaryAlloc(iShrinkSize)
If Min(1,Max(0,iMode))
BinaryReadEx(hbb,0,sFilename,0,iShrinkSize)
Else
BinaryReadEx(hbb,0,sFilename,iFileSize-iShrinkSize,iShrinkSize)
EndIf
iFileSize = BinaryWrite(hbb,sFilename)
BinaryFree(hbb)
Return (iFileSize)
;..........................................................................................................................................
; CAUTION: This function overwrites the original input file sFilename without permission !!!
;
; This function udfFileShrink() does not respect linebreak sequences.
; The function just cuts the byte stream on the given iShrinkSize byte boundary.
; This can cause an incomplete line at the boundary.
;
; iMode=0 ... Cut top of file : The tail resp. bottom of the file will be saved.
; iMode=1 ... Cut bottom of file : The head resp. top of the file will be saved.
;
;..........................................................................................................................................
; Detlev Dalitz.20010810.20020724
;..........................................................................................................................................
#EndFunction
:skip_udffileshrink
;--------------------------------------------------------------------------------------------------
;--- test ---
; Example: How to shrink a logfile.
; Create two testfiles, each of 20 byte length.
; Each file contain the string "TOP...........BOTTOM".
; These files will be shrinked to 8 byte sized files.
; The "top" file will be shrinked to the string "TOP....." (iMode=1).
; The "bot" file will be shrinked to the string "..BOTTOM" (iMode=0).
; Prepare testcase.
sTop = FileCreateTemp("top")
sBot = FileCreateTemp("bot")
iBBSize = 20
hBB = BinaryAlloc(iBBSize)
BinaryEodSet(hBB,iBBSize)
BinaryPokeStr(hBB,0,"TOP")
BinaryPokeStr(hBB,iBBSize-6,"BOTTOM")
BinaryReplace(hBB,"",".",@TRUE)
BinaryWrite(hBB,sTop)
BinaryWrite(hBB,sBot)
BinaryFree(hBB)
; Test the udf.
RunWait("notepad",sBot) ; Display original "bot" file and wait for closing notepad.
iByteWritten = udfFileShrink(sBot,8,0)
RunWait("notepad",sBot) ; Display shrinked "bot" file and wait for closing notepad.
RunWait("notepad",sTop) ; Display original "top" file and wait for closing notepad.
iByteWritten = udfFileShrink(sTop,8,1)
RunWait("notepad",sTop) ; Display shrinked "top" file and wait for closing notepad.
; Cleaning.
TimeDelay(2)
FileDelete(sTop)
FileDelete(sBot)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
udfFilePickRandomLine (sFilename)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffilepickrandomline_2",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffilepickrandomline_2
#DefineFunction udfFilePickRandomLine_2 (sFilename)
If (sFilename=="") Then Return ("")
sItemList = FileGet(sFilename)
iLineCnt = ItemCount(sItemList,@LF)-(StrSub(sItemList,FileSize(sFilename),1)==@LF)
While @TRUE
sLine = ItemExtract(1,ItemExtract(1+Random(iLineCnt),sItemList,@LF),@CR)
If (sLine!="") Then Break
EndWhile
Return (sLine)
;..........................................................................................................................................
; This Function "udfFilePickRandomLine" returns a single line,
; randomly extracted out of textfile.
; Can be used for building a "quote of the day" application.
;..........................................................................................................................................
; Detlev Dalitz.20030709
;..........................................................................................................................................
#EndFunction
:skip_udffilepickrandomline_2
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffilepickrandomline",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffilepickrandomline
#DefineFunction udfFilePickRandomLine (sFilename)
If (sFilename=="") Then Return ("")
iBBSize = FileSize(sFilename)
If (iBBSize==0) Then Return ("")
hBB = BinaryAlloc(iBBSize)
BinaryRead(hBB,sFilename)
; Count how many lines.
iLineCnt = BinaryStrCnt(hBB,0,iBBSize-1,@CRLF) -1
While @TRUE
; Pick a random line (first line is line 0).
iRandLineNum = Random(iLineCnt)
; Go find that line.
iLineStartsAt = 0
For i=1 To iRandLineNum
iLineStartsAt = 2+BinaryIndex(hBB,iLineStartsAt,@CRLF,@FWDSCAN)
Next
; Found beginning of line. Find end.
iLineEndsAt = BinaryIndex(hBB,iLineStartsAt,@CRLF,@FWDSCAN)
; Extract Line.
sLine = BinaryPeekStr(hBB,iLineStartsAt,iLineEndsAt-iLineStartsAt)
If (sLine!="") Then Break
EndWhile
BinaryFree(hBB)
Return (sLine)
;..........................................................................................................................................
; This Function "udfFilePickRandomLine" returns a single line,
; randomly extracted out of textfile.
; Can be used for building a "quote of the day" application.
;
; Conf: WinBatch
; From: Marty marty@winbatch.com
; Date: Sunday, December 02, 2001 09:49 PM
; Slightly modified by Detlev Dalitz.20020204
;..........................................................................................................................................
#EndFunction
:skip_udffilepickrandomline
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
sFilename = IntControl(1004,0,0,0,0) ; We use this file as test input.
sMsgTitle = "Demo udfFilePickRandomLine (sFilename)"
sMsgText = udfFilePickRandomLine (sFilename)
Message(sMsgTitle,sMsgText)
sMsgTitle = "Demo udfFilePickRandomLine_2 (sFilename)"
sMsgText = udfFilePickRandomLine_2 (sFilename)
Message(sMsgTitle,sMsgText)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfdelduplines",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfdelduplines
#DefineFunction udfDelDupLines (sFilenameIn, sFilenameOut, sFilenameDup, iTrimBlanks, iTrimEmptyLines)
iFileSize = FileSize(sFilenameIn)
If (iFileSize==0) Then Return (@FALSE) ; Nothing to do
If (sFilenameOut=="") Then sFilenameOut = sFilenameIn ; Overwrites input file, caution!
iDupYes = (sFilenameDup>"")
hBB = BinaryAlloc(2+iFileSize)
BinaryPokeStr(hBB,0,@LF) ; A little helper
BinaryReadEx(hBB,1,sFilenameIn,0,iFileSize)
BinaryPokeStr(hBB,BinaryEodGet(hBB),@CR) ; A little helper
If Min(1,Max(0,iTrimEmptyLines)) Then BinaryReplace(hBB,StrCat(@LF,@CR),"",@FALSE) ; Delete all blank lines
If Min(1,Max(0,iTrimBlanks))
; Delete trailing blanks.
sSearch = StrCat(" ",@CR)
While BinaryReplace(hBB,sSearch,@CR,@FALSE)
EndWhile
; Delete leading blanks.
sSearch = StrCat(@LF," ")
While BinaryReplace(hBB,sSearch,@LF,@FALSE)
EndWhile
EndIf
If iDupYes Then hFDup = FileOpen(sFilenameDup,"WRITE")
hFOut = FileOpen(sFilenameOut,"WRITE")
While @TRUE
sBBTag = BinaryTagInit(hBB,@LF,@CR)
sBBTag = BinaryTagFind(sBBTag)
If (sBBTag=="") Then Break
sLine = BinaryTagExtr(sBBTag,0)
FileWrite(hFOut,sLine)
If (sLine=="")
sBBTag = BinaryTagRepl(sBBTag,"")
Continue
EndIf
iDupCount = BinaryReplace(hBB,StrCat(@LF,sLine,@CR),"",@FALSE)
If iDupYes
For iDup=2 To iDupCount
FileWrite(hFDup,sLine)
Next
EndIf
EndWhile
BinaryFree(hBB)
FileClose(hFOut)
If iDupYes Then FileClose(hFDup)
Return (@TRUE)
;..........................................................................................................................................
; This udf "udfDelDupLines" extracts duplicate lines out of a textfile using WIL's binary functions.
; The input file sFilenameIn must be a textfile with @CRLF as eol delimiter.
; The input file needs not to be sorted.
;
; If sFilenameOut is an empty string then file sFilenameIn will be overwritten without permission.
; If iTrimBlanks is @TRUE or 1 then leading and trailing blanks will be deleted,
; If iTrimBlanks is @FALSE or 0 then leading and trailing blanks will not be touched.
; If iTrimEmptyLines is @TRUE or 1 then empty lines will be deleted.
; If iTrimEmptyLines is @FALSE or 0 then empty lines will persist.
;
; This udf "udfDelDupLines" returns @TRUE on success otherwise @FALSE.
;..........................................................................................................................................
; Detlev Dalitz.20020210.20020715.20030703
;..........................................................................................................................................
#EndFunction
:skip_udfdelduplines
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
While @TRUE
sTest = AskItemlist("Choose a testcase","1,2,3,4,5,6",",",@UNSORTED,@SINGLE)
If (sTest=="") Then Goto CANCEL
sFilenameIn = FileCreateTemp("IN")
sFilenameOut = FileCreateTemp("OUT")
sFilenameDup = FileCreateTemp("DUP")
hFW = FileOpen(sFilenameIn,"WRITE")
FileWrite(hFW," ***FILEA UNIQUE***")
FileWrite(hFW," ***COMMON*** ")
FileWrite(hFW,"")
FileWrite(hFW," ***File A DUP***")
FileWrite(hFW," ***COMMON DUP***")
FileWrite(hFW," ***File A DUP***")
FileWrite(hFW," ***COMMON DUP***")
FileWrite(hFW,"")
FileWrite(hFW," ***File A 1*** ")
FileWrite(hFW," ***File X 1*** ")
FileWrite(hFW," ***File A 2*** ")
FileWrite(hFW," ***File X 2*** ")
FileWrite(hFW," ***File A 2*** ")
FileWrite(hFW," ***File X 2*** ")
FileWrite(hFW," ***File A 3*** ")
FileWrite(hFW," ***File X 3*** ")
FileWrite(hFW," ***File A 3*** ")
FileWrite(hFW," ***File X 3*** ")
FileWrite(hFW," ***File A 3*** ")
FileWrite(hFW,"***File X 3*** ")
FileClose(hFW)
Goto test%iTest%
:test1
RunWait("notepad",sFilenameIn)
iResult = udfDelDupLines(sFilenameIn,sFilenameOut,sFilenameDup,@FALSE,@FALSE)
RunWait("notepad",sFilenameOut)
RunWait("notepad",sFilenameDup)
Goto cleaning
:test2
RunWait("notepad",sFilenameIn)
iResult = udfDelDupLines(sFilenameIn,sFilenameOut,sFilenameDup,@TRUE,@FALSE)
RunWait("notepad",sFilenameOut)
RunWait("notepad",sFilenameDup)
Goto cleaning
:test3
RunWait("notepad",sFilenameIn)
iResult = udfDelDupLines(sFilenameIn,"","",@FALSE,@FALSE)
; input file has been overwritten
RunWait("notepad",sFilenameIn)
Goto cleaning
:test4
RunWait("notepad",sFilenameIn)
iResult = udfDelDupLines(sFilenameIn,"","",@TRUE,@TRUE)
; input file has been overwritten
RunWait("notepad",sFilenameIn)
Goto cleaning
:test5
RunWait("notepad",sFilenameIn)
iResult = udfDelDupLines(sFilenameIn,sFilenameOut,"",@FALSE,@FALSE)
RunWait("notepad",sFilenameOut)
Goto cleaning
:test6
RunWait("notepad",sFilenameIn)
iResult = udfDelDupLines(sFilenameIn,sFilenameOut,"",@TRUE,@TRUE)
RunWait("notepad",sFilenameOut)
Goto cleaning
:cleaning
FileDelete(sFilenameIn)
FileDelete(sFilenameOut)
FileDelete(sFilenameDup)
EndWhile
:CANCEL
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfbinaryinsert",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfbinaryinsert
#DefineFunction udfBinaryInsert (hBBTarget, iTargetOffset, hBBInsert, iInsertOffset, iInsertLength)
iTargetOffset = Min(Max(0,iTargetOffset),BinaryEodGet(hBBTarget))
iTargetLength = BinaryEodGet(hBBTarget)
iInsertOffset = Min(Max(0,iInsertOffset),BinaryEodGet(hBBInsert))
iInsertLength = Min(Max(0,iInsertLength),BinaryEodGet(hBBInsert))
iNewLength = iTargetLength + iInsertLength
hBBNew = BinaryAlloc(iNewLength)
BinaryEodSet(hBBNew,iNewLength)
Select 1
Case (iInsertLength == 0)
BinaryCopy(hBBNew,0,hBBTarget,0,iTargetLength)
Break
Case (iTargetOffset >= iTargetLength)
BinaryCopy(hBBNew,0,hBBTarget,0,iTargetLength)
BinaryCopy(hBBNew,iTargetLength,hBBInsert,0,iInsertLength)
Break
Case (iTargetOffset <= 0)
BinaryCopy(hBBNew,0,hBBInsert,0,iInsertLength)
BinaryCopy(hBBNew,iInsertLength,hBBTarget,0,iTargetLength)
Break
Case 1
BinaryCopy(hBBNew,0,hBBTarget,0,iTargetOffset)
BinaryCopy(hBBNew,iTargetOffset+iInsertLength,hBBTarget,iTargetOffset,iTargetLength-iTargetOffset)
BinaryCopy(hBBNew,iTargetOffset,hBBInsert,iInsertOffset,iInsertLength)
Break
EndSelect
Return (hBBNew)
;..........................................................................................................................................
; This function "udfBinaryInsert" returns a handle to a new created binary buffer.
; The new binary buffer contains the target buffer content
; along with the inserted part of the insertion binary buffer.
;
; Detlev Dalitz.20020616
;..........................................................................................................................................
#EndFunction
:skip_udfbinaryinsert
;------------------------------------------------------------------------------------------------------------------------------------------
; --- sTest ---
sMsgTitle = "Demo udfBinaryInsert (hBBTarget, iTargetOffset, hBBInsert, iInsertOffset, iInsertLength)"
sTest1 = "udfBinaryInsert (hBB1, 0, hBB2, 0, 3)" ; "123+++++"
sTest2 = "udfBinaryInsert (hBB1, BinaryEodGet(hBB1), hBB2, 0, 3)" ; "+++++123"
sTest3 = "udfBinaryInsert (hBB1, 3, hBB2, 0, 3)" ; "+++123++"
sTest4 = "udfBinaryInsert (hBB1, 3, hBB2, 1, 1)" ; "+++2++"
sTest5 = "udfBinaryInsert (hBB1, 3, hBB2, 1, 0)" ; "+++++"
hBB1 = BinaryAlloc(5)
BinaryPokeStr(hBB1,0,"+++++")
hBB2 = BinaryAlloc(3)
BinaryPokeStr(hBB2,0,"123")
For i=1 To 5
sTest = sTest%i%
hBB3 = %sTest%
sMsgText = ""
sMsgText = StrCat(sMsgText,sTest%i%,@CRLF)
sMsgText = StrCat(sMsgText,'hBB1',@TAB,'= "',BinaryPeekStr(hBB1,0,BinaryEodGet(hBB1)),'"',@CRLF)
sMsgText = StrCat(sMsgText,'hBB2',@TAB,'= "',BinaryPeekStr(hBB2,0,BinaryEodGet(hBB2)),'"',@CRLF)
sMsgText = StrCat(sMsgText,'hBB3',@TAB,'= "',BinaryPeekStr(hBB3,0,BinaryEodGet(hBB3)),'"',@CRLF)
Pause(sMsgTitle,sMsgText)
Next
BinaryFree(hBB1)
BinaryFree(hBB2)
BinaryFree(hBB3)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
udfFileGetLineCount (sFilename)
;------------------------------------------------------------------------------------------------------------------------------------------
; Test to find out a rule how lines are counted ...
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffilegetlinecount",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffilegetlinecount
#DefineFunction udfFileGetLineCount (sFilename)
iBBSize = FileSizeEx(sFilename)
If !iBBSize Then Return (0)
hBB = BinaryAlloc(iBBSize)
iHigh = BinaryRead(hBB,sFilename)-1
While (@CR==BinaryPeekStr(hBB,iHigh,1))
iHigh = iHigh-1
EndWhile
iLineCount = BinaryStrCnt(hBB,0,iHigh,@LF)
iLineCount = iLineCount+(@LF<>BinaryPeekStr(hBB,iHigh,1))
BinaryFree(hBB)
Return (iLineCount)
;..........................................................................................................................................
; This function "udfFileGetLineCount" returns the number of lines counted in a textfile.
; The function takes only @LF characters into account.
; All @CR characters are ommitted.
; The function provides the same number of lines as counted by the WIL standard FileRead function.
;..........................................................................................................................................
; Detlev Dalitz.20020820
;..........................................................................................................................................
#EndFunction
:skip_udffilegetlinecount
;------------------------------------------------------------------------------------------------------------------------------------------
AddExtender("WWWSK34i.DLL")
sMsgTitle = "Demo LineCount and EOL Delimiters"
sMsgText = ""
sFilenameTemp = FileCreateTemp("TMP")
sFolderTemp = FilePath(sFilenameTemp)
FileDelete(sFilenameTemp)
sTestLine1 = "How many lines?" ; 1
sTestLine2 = StrCat("How many lines?",@CR) ; 1
sTestLine3 = StrCat("How many lines?",@LF) ; 1
sTestLine4 = StrCat("How many lines?",@CRLF) ; 1
sTestLine5 = StrCat("How many lines?",Num2Char(26)) ; 1
sTestLine6 = StrCat("How many lines?",@CR,@CR) ; 1
sTestLine7 = StrCat("How many lines?",@CR,@CR,Num2Char(26)) ; 1
sTestLine8 = StrCat("How many lines?",@LF,"test") ; 2
sTestLine9 = StrCat("How many lines?",@LF,@LF) ; 2
sTestLine10 = StrCat("How many lines?",@LF,@LF,@CR) ; 2
sTestLine11 = StrCat("How many lines?",@LF,@LF,"test") ; 3
sTestLine12 = StrCat("How many lines?",@LF,@LF,Num2Char(26)) ; 3
sTestLine13 = StrCat("How many lines?",@CRLF,@CRLF) ; 2
sTestLine14 = StrCat("How many lines?",@CRLF,@CRLF,Num2Char(26)) ; 3
IntControl (53,0,0,0,0) ; For the test: No line terminator for FileWrite.
For i=1 To 14
sFilenameTest = StrCat(sFolderTemp,"Test.",i,".txt")
hFW = FileOpen(sFilenameTest,"WRITE")
FileWrite(hFW,sTestLine%i%)
FileClose(hFW)
Next
sMsgText = StrCat(sMsgText,"FileRead",@LF)
; Using the standard FileRead function.
For i=1 To 14
sFilenameTest = StrCat(sFolderTemp,"Test.",i,".txt")
iFileSize%i% = FileSize(sFilenameTest)
IntControl(65,4096*256,0,0,0) ; Enlarge fileread buffer for speedy access. ; added DD.20030128
hFR = FileOpen(sFilenameTest,"READ")
iLineCount%i% = 0
While 1
If ("*EOF*"==FileRead(hFR)) Then Break
iLineCount%i% = 1+iLineCount%i%
EndWhile
FileClose(hFR)
sTestLine = urlEncode(sTestLine%i%)
sTestLine = StrFix(sTestLine," ",40)
sMsgText = StrCat(sMsgText,sTestLine,"FileSize",i,"=",iFileSize%i%,@TAB,"LineCount",i,"=",iLineCount%i%,@LF)
Next
sMsgText = StrCat(sMsgText,@LF,"udfFileGetLineCount",@LF)
; Using the udfFileGetLineCount replacement function.
For i=1 To 14
sFilenameTest = StrCat(sFolderTemp,"Test.",i,".txt")
iFileSize%i% = FileSize(sFilenameTest)
iLineCount%i% = udfFileGetLineCount(sFilenameTest)
sTestLine = urlEncode(sTestLine%i%)
sTestLine = StrFix(sTestLine," ",40)
sMsgText = StrCat(sMsgText,sTestLine,"FileSize",i,"=",iFileSize%i%,@TAB,"LineCount",i,"=",iLineCount%i%,@LF)
Next
For i=1 To 14
sFilenameTest = StrCat(sFolderTemp,"Test.",i,".txt")
FileDelete(sFilenameTest)
Next
IntControl(28,1,0,0,0)
IntControl(63,200,100,800,900)
AskItemlist(sMsgTitle,sMsgText,@LF,@UNSORTED,@SINGLE)
:CANCEL
Exit
;..........................................................................................................................................
; If the WIL function 'FileRead' is the standard to decide
; what is a line and what is not a line,
; then the following rule might be the general rule:
;
; 1. All @CR characters are ommitted and not counted.
; 2. LineCount is the sum of all @LF characters in the file.
; 3. If the last character in file is not a @LF, then increment LineCount by 1.
;..........................................................................................................................................
;------------------------------------------------------------------------------------------------------------------------------------------
; *EOF*
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffiledelduplines",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffiledelduplines
#DefineFunction udfFileDelDupLines (sFilenameIn, sFilenameOut, sFilenameDup, iTrimBlanks, iTrimEmptyLines)
iFileSize = FileSize(sFilenameIn)
If (iFileSize==0) Then Return (0) ; Nothing to do.
If (sFilenameOut=="") Then sFilenameOut = sFilenameIn ; Overwrites input file, caution!
iDupYes = (sFilenameDup>"")
iTrimBlanks = Min(1,Max(0,iTrimBlanks))
iTrimEmptyLines = Min(1,Max(0,iTrimEmptyLines))
sItemList = FileGet(sFilenameIn)
If iTrimEmptyLines Then sItemList = StrReplace(sItemList,StrCat(@LF,@CR),"") ; Delete all empty lines.
sItemList = StrReplace(sItemList,@CRLF,@LF)
sTrimList = ""
sDupList = ""
iCount = ItemCount(sItemList,@LF)
For i=1 To iCount
sItem = ItemExtract(i,sItemList,@LF)
If iTrimBlanks Then sItem = StrTrim(sItem)
If (sItem=="")
If iTrimEmptyLines Then Continue
sTrimList = ItemInsert(sItem,-1,sTrimList,@LF)
EndIf
If !ItemLocate(sItem,sTrimList,@LF) Then sTrimList = ItemInsert(sItem,-1,sTrimList,@LF)
Else If iDupYes Then sDupList = ItemInsert(sItem,-1,sDupList,@LF)
Next
If (sDupList>"")
sDupList = StrReplace(sDupList,@LF,@CRLF)
iFileSize = FilePut(sFilenameDup,sDupList)
EndIf
iFileSize = 0
If (sTrimList>"")
sTrimList = StrReplace(sTrimList,@LF,@CRLF)
iFileSize = FilePut(sFilenameOut,sTrimList)
EndIf
Return (iFileSize)
;..........................................................................................................................................
; This udf "udfFileDelDupLines" removes duplicate lines from a textfile.
; The input file sFilenameIn must be a textfile with @CRLF as eol delimiter.
; The input file needs not to be sorted.
;
; If sFilenameOut is an empty string then file sFilenameIn will be overwritten without permission.
; If iTrimBlanks is @TRUE or 1 then leading and trailing blanks will be deleted,
; If iTrimBlanks is @FALSE or 0 then leading and trailing blanks will not be touched.
; If iTrimEmptyLines is @TRUE or 1 then empty lines will be deleted.
; If iTrimEmptyLines is @FALSE or 0 then empty lines will persist.
;
; If input filesize is zero, then the function returns 0 immediately.
; On success the function returns the number of bytes written to the output file.
;
;..........................................................................................................................................
; Detlev Dalitz.20030705
;..........................................................................................................................................
#EndFunction
:skip_udffiledelduplines
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
sFilenameIn = IntControl(1004,0,0,0,0) ; We use this file as test input.
sFilename = StrCat(Environment("TEMP"),"\",FileRoot(sFilenameIn))
sFilenameOut = StrCat(sFilename,".trim.1.txt")
sFilenameDup = ""
iTrimBlanks = @TRUE
iTrimEmptyLines = @TRUE
iFileSize1 = udfFileDelDupLines (sFilenameIn, sFilenameOut, sFilenameDup, iTrimBlanks, iTrimEmptyLines)
sFilenameOut = StrCat(sFilename,".trim.2.txt")
sFilenameDup = ""
iTrimBlanks = @FALSE
iTrimEmptyLines = @TRUE
iFileSize2 = udfFileDelDupLines (sFilenameIn, sFilenameOut, sFilenameDup, iTrimBlanks, iTrimEmptyLines)
sFilenameOut = StrCat(sFilename,".trim.3.txt")
sFilenameDup = ""
iTrimBlanks = @TRUE
iTrimEmptyLines = @FALSE
iFileSize3 = udfFileDelDupLines (sFilenameIn, sFilenameOut, sFilenameDup, iTrimBlanks, iTrimEmptyLines)
sFilenameOut = StrCat(sFilename,".trim.4.txt")
sFilenameDup = ""
iTrimBlanks = @FALSE
iTrimEmptyLines = @FALSE
iFileSize4 = udfFileDelDupLines (sFilenameIn, sFilenameOut, sFilenameDup, iTrimBlanks, iTrimEmptyLines)
sFilenameOut = StrCat(sFilename,".trim.5.txt")
sFilenameDup = StrCat(sFilename,".dupl.5.txt")
iTrimBlanks = @FALSE
iTrimEmptyLines = @TRUE
iFileSize5 = udfFileDelDupLines (sFilenameIn, sFilenameOut, sFilenameDup, iTrimBlanks, iTrimEmptyLines)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
udfFileReadLastLine (sFilename)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffilereadlastline",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffilereadlastline
#DefineFunction udfFileReadLastLine (sFilename)
sLine = ""
iFilesize = FileSize(sFilename)
If iFilesize
iBBsize = 8192 ; Assumption: 8 kByte buffer, will cover some lines.
hBB = BinaryAlloc(iBBsize)
If BinaryReadEx(hBB,0,sFilename,Max(0,iFileSize-iBBsize),iBBsize)
BinaryReplace(hBB,@CRLF,@LF,@TRUE)
BinaryReplace(hBB,@CR,"",@TRUE)
iEod = BinaryEodGet(hBB)-1
iLf = BinaryIndexEx(hBB,iEod,@LF,@BACKSCAN,@TRUE)
Select @TRUE
Case (iLf < 0) ; Not a valid textfile or try a larger buffer.
Break
Case (iLf < iEod) ; Last Line without trailing @LF.
sLine = BinaryPeekStr(hBB,iLf+1,iEod)
Break
Case @TRUE ; Valid Line.
iEod = iEod-1
iLf = BinaryIndexEx(hBB,iEod,@LF,@BACKSCAN,@TRUE)
sLine = BinaryPeekStr(hBB,iLf+1,iEod-iLf)
Break
EndSelect
EndIf
BinaryFree(hBB)
EndIf
Return (sLine)
;..........................................................................................................................................
; This Function "udfFileReadLastLine" returns the last line of a textfile.
;
; Detlev Dalitz.20030107
;..........................................................................................................................................
#EndFunction
:skip_udffilereadlastline
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
sFilename = IntControl(1004,0,0,0,0) ; We use this script as test input file.
MsgTitle = "Demo udfFileReadLastLine(sFilename)"
MsgText = StrCat('Filename = "',sFilename,'"',@LF,'Last Line = "',udfFileReadLastLine(sFilename),'"')
Message(MsgTitle,MsgText)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
udfFileReadLastLines (sFilename, iLines)
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffilereadlastlines",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffilereadlastlines
#DefineFunction udfFileReadLastLines (sFilename, iLines)
If (iLines < 1) Then Return ("")
iFilesize = FileSize(sFilename)
If (iFilesize < 1) Then Return ("")
; Check for trailing @LF and adjust lines to read.
hBB = BinaryAlloc(1)
If BinaryReadEx(hBB,0,sFilename,iFileSize-1,1)
If (BinaryPeekStr(hBB,0,1) != @LF) Then iLines = iLines - 1
EndIf
BinaryFree(hBB)
; Read file from backward into buffer chunks of n byte size
; and move the line pointer for each @LF backward into the file.
iBBsize = 8192 ; Modify buffer size to your needs.
hBB = BinaryAlloc(iBBsize)
iChunkOffset = (iFileSize / iBBSize) * iBBsize
While @TRUE
If (iChunkOffset < 0) Then Break
If BinaryReadEx(hBB,0,sFilename,iChunkOffset,iBBsize)
iLfOffset = BinaryEodGet(hBB)
While @TRUE
If (iLines < 0) Then Break
iLfOffset = BinaryIndexEx(hBB,iLfOffset-1,@LF,@BACKSCAN,@TRUE)
If (iLfOffset < 0) Then Break
iLines = iLines - 1
EndWhile
EndIf
If (iLines < 0) Then Break
iChunkOffset = iChunkOffset - iBBsize
EndWhile
BinaryFree(hBB)
; Get all the last lines into one buffer and peek the whole string.
If (iLfOffset < 0) Then iLfOffset = 0
If (iChunkOffset < 0) Then iChunkOffset = 0
iLfOffset = iLfOffset + iChunkOffset
If iLfOffset Then iLfOffset = iLfOffset + 1
sLines = ""
iBBSize = iFileSize - iLfOffset
If (iBBSize > 0)
hBB = BinaryAlloc(iBBsize)
If BinaryReadEx(hBB,0,sFilename,iLfOffset,iBBsize)
; Move eod pointer before trailing @LF and trailing @CR.
If (BinaryPeekStr(hBB,iBBSize-1,1) == @LF) Then iBBSize = iBBSize - 1
If (BinaryPeekStr(hBB,iBBSize-1,1) == @CR) Then iBBSize = iBBSize - 1
sLines = BinaryPeekStr(hBB,0,iBBsize)
EndIf
BinaryFree(hBB)
EndIf
Return (sLines)
;..........................................................................................................................................
; This Function "udfFileReadLastLines" returns a string
; that contains the last n lines of a textfile.
;
; Detlev Dalitz.20030528
;..........................................................................................................................................
#EndFunction
:skip_udffilereadlastlines
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
sFilename = IntControl(1004,0,0,0,0) ; We use this file as test input.
iLines = 11
sLines = udfFileReadLastLines(sFilename,iLines)
sLines = StrReplace(sLines,@CRLF,@LF)
sLines = StrReplace(sLines,@CR,"")
MsgTitle = "Demo udfFileReadLastLines (sFilename, iLines)"
MsgText = StrCat('Filename = "',sFilename,'"',@LF,'Last ',iLines,' Lines ==>',@LF,sLines,@LF,'<==')
Message(MsgTitle,MsgText)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
; udfStrToFile (sString, sFilename, iMode)
; udfFileAppendStr (sString, sLineTerm, sFilename)
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udfstrtofile",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udfstrtofile
#DefineFunction udfStrToFile (sString, sFilename, iMode)
iMode = Min(4,Max(0,iMode))
IntControl (53,iMode,0,0,0)
hfw = FileOpen(sFilename,"APPEND")
FileWrite(hfw,sString)
FileClose(hfw)
;..........................................................................................................................................
; This Function "udfStrToFile" writes data to a file from a given sString,
; and lets you select a different line terminator, or none at all, as specified by iMode.
; iMode=0 ... No line terminator
; iMode=1 ... CR/LF (DOS) (default)
; iMode=2 ... LF (UNIX)
; iMode=3 ... CR (Macintosh)
; iMode=4 ... Tab
;
; Detlev Dalitz.20020724
;..........................................................................................................................................
#EndFunction
:skip_udfstrtofile
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
If ItemLocate("udffileappendstr",IntControl(77,103,0,0,0),@TAB) Then Goto skip_udffileappendstr
#DefineFunction udfFileAppendStr (sString, sLineTerm, sFilename)
IntControl (53,0,0,0,0)
hfw = FileOpen(sFilename,"APPEND")
FileWrite(hfw,sString)
FileWrite(hfw,sLineTerm)
FileClose(hfw)
;..........................................................................................................................................
; This Function "udfFileAppendStr" writes data to a file from a given sString,
; and lets you select a different line terminator as specified by sLineTerm.
;
; Detlev Dalitz.20020724
;..........................................................................................................................................
#EndFunction
:skip_udffileappendstr
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
sTempFile = FileCreateTemp("TMP")
FileDelete(sTempFile)
sTempFolder = FilePath(sTempFile)
sFilename = "Test.udfStrAppendToFile.bin"
sFilename = StrCat(sTempFolder,sFilename)
:1
udfStrToFile("1_xxx_1" ,sFilename,0) ; iMode=0 ... No line terminator
udfStrToFile("1_tab_1" ,sFilename,4) ; iMode=4 ... Tab
udfStrToFile("1_mac_cr_1" ,sFilename,3) ; iMode=3 ... CR (Macintosh)
udfStrToFile("1_unix_lf_1" ,sFilename,2) ; iMode=2 ... LF (UNIX)
udfStrToFile("1_dos_crlf_1" ,sFilename,1) ; iMode=1 ... CR/LF (DOS) (default)
RunWait(StrCat(DirHome(),"browser.exe"),sFilename)
:2
udfFileAppendStr("2_xxx_2" ,"" ,sFilename)
udfFileAppendStr("2_tab_2" ,@TAB ,sFilename)
udfFileAppendStr("2_mac_cr_2" ,@CR ,sFilename)
udfFileAppendStr("2_unix_lf_2" ,@LF ,sFilename)
udfFileAppendStr("2_dos_crlf_2",@CRLF ,sFilename)
udfFileAppendStr('"2_SSV_2"' ,";" ,sFilename) ; Writing "SSV semicolon separated value" file.
udfFileAppendStr('"2_SSV_2"' ,";" ,sFilename)
udfFileAppendStr('"2_SSV_2"' ,"" ,sFilename)
udfFileAppendStr(@CRLF ,"" ,sFilename)
udfFileAppendStr('"2_CSV_2"' ,"," ,sFilename) ; Writing "CSV comma separated value" file.
udfFileAppendStr('"2_CSV_2"' ,"," ,sFilename)
udfFileAppendStr('"2_CSV_2"' ,"" ,sFilename)
udfFileAppendStr(@CRLF ,"" ,sFilename)
udfFileAppendStr(@CRLF ,Num2Char(26),sFilename) ; Writing "EndOfFile" terminator.
RunWait(StrCat(DirHome(),"browser.exe"),sFilename)
FileDelete(sFilename)
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*
How to read a text file backwards FileOpenReverse (sFilename) FileReadReverse (hFR) FileCloseReverse (hFR)
;------------------------------------------------------------------------------------------------------------------------------------------
; How to read a text file backwards?
;------------------------------------------------------------------------------------------------------------------------------------------
; The following set of three functions provides backward reading of a text file.
; That means the last line of the textfile will be returned first.
; When the upper bound of the file is reached, the string *BOF* will be returned.
; The functions are designed to work with CRLF terminated lines only.
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileOpenReverse (sFilename)
iFileSize = FileSize(sFilename)
hFR = BinaryAlloc(8+iFileSize)
BinaryReadEx(hFR,6,sFilename,0,iFileSize)
If BinaryPeek2(hFR,4+iFileSize)<>2573 Then BinaryPoke2(hFR,6+iFileSize,2573)
If BinaryPeek2(hFR,6)<>2573 Then BinaryPoke2(hFR,4,2573)
iGlobalOffset=7+iFileSize
BinaryPoke4(hFR,0,iGlobalOffset)
Return hFR
;..........................................................................................................................................
; This function "FileOpenReverse" opens a text file for reading.
; The EOL character must be the CRLF sequence.
; The function returns a handle to the "reversed" file, that is temporarily stored into a binary buffer.
; The returning handle is actually the handle to the underlying binary buffer.
; This handle must be used in the "udfFileReadReverse" and "udfFileCloseReverse" functions.
;..........................................................................................................................................
; Usage of binary buffer:
; BufferSize = FileSize + 8 byte.
; Reserved: byte 0..3 for pointer iGlobalOffset.
; Reserved: byte 4..5 for extra opening CRLF.
; Reserved: 2 byte at end of file stream for extra closing CRLF.
;
; 1. Read file into buffer offset 6.
; 2. Add CRLF at end if it does not exist.
; 3. Add CRLF at beginning if it does not exist.
; 4. Set pointer iGlobalOffset to the end of buffer.
;
; CRLF = 2573 = 13 + 10*256
;..........................................................................................................................................
; This function is based on a #DefineSubroutine related proposal by Guido 02/02, published in the WinBatch forum.
; Modified by Detlev Dalitz.20031025
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileReadReverse (hFR)
iGlobalOffset = BinaryPeek4(hFR,0)
iOffsetR = BinaryIndexEx(hFR,iGlobalOffset,@CRLF,@BACKSCAN,@FALSE)
If iOffsetR<5 Then Return "*BOF*"
iOffsetL = BinaryIndexEx(hFR,iOffsetR,@CRLF,@BACKSCAN,@FALSE)
If iOffsetL<0 Then Return "*BOF*"
sLine = BinaryPeekStr(hFR,2+iOffsetL,iOffsetR-iOffsetL)
iGlobalOffset=2+iOffsetL
BinaryPoke4(hFR,0,iGlobalOffset)
If sLine==@CRLF Then Return ""
Return sLine
;..........................................................................................................................................
; This function "udfFileReadReverse" reads data from a file, line by line.
; The handle hFileReverse must be the same that was returned by udfFileOpenReverse. ;
;..........................................................................................................................................
; This function is based on a subroutine related proposal by Guido 02/02, published in the WinBatch forum.
; Modified by Detlev Dalitz.20031025
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileCloseReverse (hFR)
BinaryFree(hFR)
Return 0
;..........................................................................................................................................
; This function "udfFileCloseReverse" frees the allocated binary buffer, that means file access will be closed.
; The handle hFileReverse must be the same that was returned by udfFileOpenReverse.
;..........................................................................................................................................
; This function is based on a subroutine related proposal by Guido 02/02, published in the WinBatch forum.
; Modified by Detlev Dalitz.20031025
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------
; --- test ---
; Get last 10 lines of a file.
sFile=IntControl(1004,0,0,0,0) ; We use this script as test input file.
hFR = udfFileOpenReverse(sFile)
ic=0
While ic<10
sLine = udfFileReadReverse(hFR)
If sLine=="*BOF*" Then Break
ic=ic+1
Message("",sLine)
EndWhile
udfFileCloseReverse(hFR)
Message("*BOF*", "Ready.")
Exit
;------------------------------------------------------------------------------------------------------------------------------------------
;*EOF*