udfFileReverse
int udfFileReverseV1 (str, str)
int udfFileReverseV2 (str, str)
int udfFileReverseV3 (str, str)
int udfFileReverseV4 (str, str)
int udfFileReverseV5 (str, str)
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileReverseV5 (strFilenameIn, strFilenameOut)
intFileSize = FileSize (strFilenameIn)
intLast = 1 + intFileSize
hdlBB = BinaryAlloc (intLast)
intBytesRead = BinaryReadEx (hdlBB, 1, strFilenameIn, 0, intFileSize)
intMid = intLast / 2
For intLeft = 1 To intMid
   intRight = intLast - intLeft
   BinaryPoke (hdlBB, intLeft - 1, BinaryPeek (hdlBB, intRight))
   BinaryPoke (hdlBB, intRight, BinaryPeek (hdlBB, intLeft))
Next
BinaryWriteEx (0, 0, strFilenameOut, 0, -1)
intBytesWritten = BinaryWriteEx (hdlBB, 0, strFilenameOut, 0, intMid) + BinaryWriteEx (hdlBB, intMid + 1, strFilenameOut, intMid, intLast - intMid - 1)
hdlBB = BinaryFree (hdlBB)
Return intBytesWritten
;..........................................................................................................................................
; This UDF "udfFileReverse" reads the content of the given input file
; and writes the same content into the new output file but in reversed order.
;
; Return value is the number of bytes written.
;
; (c)Detlev Dalitz.20100216.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileReverseV4 (strFilenameIn, strFilenameOut)
hdlBB = BinaryAlloc (FileSize (strFilenameIn))
intLast = BinaryRead (hdlBB, strFilenameIn) - 1
intMid = (intLast / 2) - !(intLast & 1)
For intLeft = 0 To intMid
   intRight = intLast - intLeft
   intByte = BinaryPeek (hdlBB, intRight)
   BinaryPoke (hdlBB, intRight, BinaryPeek (hdlBB, intLeft))
   BinaryPoke (hdlBB, intLeft, intByte)
Next
intBytesWritten = BinaryWrite (hdlBB, strFilenameOut)
hdlBB = BinaryFree (hdlBB)
Return intBytesWritten
;..........................................................................................................................................
; This UDF "udfFileReverse" reads the content of the given input file
; and writes the same content into the new output file but in reversed order.
;
; Return value is the number of bytes written.
;
; (c)Detlev Dalitz.20100216.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileReverseV3 (strFilenameIn, strFilenameOut)
intFileSize = FileSize (strFilenameIn)
intLast = 1 + intFileSize
hdlBB = BinaryAlloc (intLast)
intBytesRead = BinaryReadEx (hdlBB, 1, strFilenameIn, 0, intFileSize)
intMid = intLast / 2
For intLeft = 1 To intMid
   intRight = intLast - intLeft
   BinaryPoke (hdlBB, 0, BinaryPeek (hdlBB, intRight))
   BinaryPoke (hdlBB, intRight, BinaryPeek (hdlBB, intLeft))
   BinaryPoke (hdlBB, intLeft, BinaryPeek (hdlBB, 0))
Next
BinaryWriteEx (0, 0, strFilenameOut, 0, -1)
intBytesWritten = BinaryWriteEx (hdlBB, 1, strFilenameOut, 0, intFileSize)
hdlBB = BinaryFree (hdlBB)
Return intBytesWritten
;..........................................................................................................................................
; This UDF "udfFileReverse" reads the content of the given input file
; and writes the same content into the new output file but in reversed order.
;
; Return value is the number of bytes written.
;
; (c)Detlev Dalitz.20100216.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileReverseV2 (strFilenameIn, strFilenameOut)
intFileSize = FileSize (strFilenameIn)
hdlBBIn = BinaryAlloc (intFileSize)
hdlBBOut = BinaryAlloc (intFileSize)
intLast = intFileSize - 1
intBytesRead = BinaryRead (hdlBBIn, strFilenameIn)
For intI = 0 To intLast
   BinaryPoke (hdlBBOut, intLast - intI, BinaryPeek (hdlBBIn, intI))
Next
intBytesWritten = BinaryWrite (hdlBBOut, strFilenameOut)
hdlBBIn = BinaryFree (hdlBBIn)
hdlBBOut = BinaryFree (hdlBBOut)
Return intBytesWritten
;..........................................................................................................................................
; This UDF "udfFileReverse" reads the content of the given input file
; and writes the same content into the new output file but in reversed order.
;
; Return value is the number of bytes written.
;
; (c)Detlev Dalitz.20100216.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfFileReverseV1 (strFilenameIn, strFilenameOut)
arrA = ArrayFromStr (" " : FileGet (strFilenameIn))
intLen = ArrInfo (arrA, 1)
intMid = intLen / 2
For intLeft = 1 To intMid
   intRight = intLen - intLeft
   arrA[intLeft - 1] = arrA[intRight]
   arrA[intRight] = arrA[intLeft]
Next
strString = ArrayToStr (arrA)
Return FilePut (strFilenameOut, StrSub (strString, 1, intMid) : StrSub (strString, intMid + 2, intRight))
;..........................................................................................................................................
; This UDF "udfFileReverse" reads the content of the given input file
; and writes the same content into the new output file but in reversed order.
;
; Return value is the number of bytes written.
;
; Note:
; Works only with a text file data stream which contain no zero byte.
;
; (c)Detlev Dalitz.20100216.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


; Test.

GoSub FunctionalTest
GoSub PerformanceTest
Exit


;------------------------------------------------------------------------------------------------------------------------------------------
:FunctionalTest

strFileRoot = ItemRemove (-1, IntControl (1004, 0, 0, 0, 0), ".")
strFilenameIn = strFileRoot : ".reverse.in.txt"

strTest = "1234567890ABCDEFGHIJK" ; 21 chars.
intBytesWritten = FilePut (strFilenameIn, strTest)

strFilenameOut1 = strFileRoot : ".reverse.out.1.txt"
intBytesWritten1 = udfFileReverseV1 (strFilenameIn, strFilenameOut1)

strFilenameOut2 = strFileRoot : ".reverse.out.2.txt"
intBytesWritten2 = udfFileReverseV2 (strFilenameIn, strFilenameOut2)

strFilenameOut3 = strFileRoot : ".reverse.out.3.txt"
intBytesWritten3 = udfFileReverseV3 (strFilenameIn, strFilenameOut3)

strFilenameOut4 = strFileRoot : ".reverse.out.4.txt"
intBytesWritten4 = udfFileReverseV4 (strFilenameIn, strFilenameOut4)

strFilenameOut5 = strFileRoot : ".reverse.out.5.txt"
intBytesWritten5 = udfFileReverseV5 (strFilenameIn, strFilenameOut5)

Run (strFilenameOut1, "")
Run (strFilenameOut2, "")
Run (strFilenameOut3, "")
Run (strFilenameOut4, "")
Run (strFilenameOut5, "")
Return ; from GoSub.
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
:PerformanceTest
;------------------------------------------------------------------------------------------------------------------------------------------
; This profiling loop includes five variants of coding algorithms of the "udfFileReverse" function.
;------------------------------------------------------------------------------------------------------------------------------------------

; Which tests to check.
intTestMin = 1
intTestMax = 5

; How many loops to run.
intLoopMax = 4

; Init for all.
ClipPut ("")
strFileRoot = ItemRemove (-1, IntControl (1004, 0, 0, 0, 0), ".")
strFilenameIn = strFileRoot : ".reverse.in.txt"
strFilenameOutMask = strFileRoot : ".reverse.out.{1}.txt"
strTest = "1234567890ABCDEFGHIJK" ; 21 chars.

;intBytesWritten = FilePut (strFilenameIn, StrFill (strTest, 20)) ; 20 Bytes.
;intBytesWritten = FilePut (strFilenameIn, StrFill (strTest, 21)) ; 21 Bytes.
intBytesWritten = FilePut (strFilenameIn, StrFill (strTest, 10000)) ; 10000 Bytes.
;intBytesWritten = FilePut (strFilenameIn, StrFill (strTest, 100000)) ; 100000 Bytes.


; Loop.
BoxOpen ("Performance Test", "Be patient ...")
For intTest = intTestMin To intTestMax
   strFilenameOut = StrReplace (strFilenameOutMask, "{1}", intTest)
   intTicks%intTest% = 0
   For intLoop = 1 To intLoopMax
      strMsgText = "Test: " : intTestMax : "/" : intTest : @LF : "Loop: " : intLoopMax : "/" : intLoop : @LF : "Ticks%intTest%: " : intTicks%intTest%
      BoxText (strMsgText)
      Exclusive (@ON)
      GoSub Test%intTest%
      Exclusive (@OFF)
      intTicks%intTest% = intTicks%intTest% + intTicksStop - intTicksStart
   Next
   BoxText (strMsgText)
Next
BoxShut ()

; Result.
Decimals (1)
intTicksSum = 0
For intTest = intTestMin To intTestMax
   intTicksSum = intTicksSum + intTicks%intTest%
Next
If intTicksSum < 1 Then intTicksSum = 1 ; To prevent dividing by zero.
For intTest = intTestMin To intTestMax
   intPct%intTest% = 100.0 * intTicks%intTest% / intTicksSum
Next

; Format output;
strTest = "Test"
strTicks = "Ticks"
strPct = "Pct"
strSep = "  "
strPre = "; "
intLenTest = Max (StrLen (strTest), StrLen (intTestMax))
intLenTicks = StrLen (strTicks)
intLenPct = StrLen (strPct)
For intTest = intTestMin To intTestMax
   intLenTicks = Max (intLenTicks, StrLen (intTicks%intTest%))
   intLenPct = Max (intLenPct, StrLen (intPct%intTest%))
Next
strTest = StrFixLeft (strTest, " ", intLenTest)
strTicks = StrFixLeft (strTicks, " ", intLenTicks)
strPct = StrFixLeft (strPct, " ", intLenPct)
strResult = ""
strResult = ItemInsert (strPre : "Iterations: " : intLoopMax, -1, strResult, @LF)
strResult = ItemInsert (strPre : strTest : strSep : strTicks : strSep : strPct, -1, strResult, @LF)
For intTest = intTestMin To intTestMax
   strTest = StrFixLeft (intTest, " ", intLenTest)
   strTicks = StrFixLeft (intTicks%intTest%, " ", intLenTicks)
   strPct = StrFixLeft (intPct%intTest%, " ", intLenPct)
   strResult = ItemInsert (strPre : strTest : strSep : strTicks : strSep : strPct, -1, strResult, @LF)
Next
strResult = strResult : @LF
Message ("Performance Test Result", strResult)
ClipPut (strResult)
Return ; from GoSub.
;------------------------------------------------------------------------------------------------------------------------------------------


;------------------------------------------------------------------------------------------------------------------------------------------
; Test GoSub's.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test1
intTicksStart = GetTickCount ()
intBytesWritten1 = udfFileReverseV1 (strFilenameIn, strFilenameOut)
intTicksStop = GetTickCount ()
Return ; from GoSub.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test2
intTicksStart = GetTickCount ()
intBytesWritten2 = udfFileReverseV2 (strFilenameIn, strFilenameOut)
intTicksStop = GetTickCount ()
Return ; from GoSub.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test3
intTicksStart = GetTickCount ()
intBytesWritten3 = udfFileReverseV3 (strFilenameIn, strFilenameOut)
intTicksStop = GetTickCount ()
Return ; from GoSub.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test4
intTicksStart = GetTickCount ()
intBytesWritten4 = udfFileReverseV4 (strFilenameIn, strFilenameOut)
intTicksStop = GetTickCount ()
Return ; from GoSub.
;------------------------------------------------------------------------------------------------------------------------------------------
:Test5
intTicksStart = GetTickCount ()
intBytesWritten5 = udfFileReverseV5 (strFilenameIn, strFilenameOut)
intTicksStop = GetTickCount ()
Return ; from GoSub.
;------------------------------------------------------------------------------------------------------------------------------------------
;==========================================================================================================================================
; Filesize: 10000 Bytes
; Iterations: 20
; Test  Ticks   Pct
;    1  33204  12.9  <== The winner (text only).
;    2  52111  20.3
;    3  65548  25.5
;    4  55125  21.5
;    5  50779  19.8  <== The winner (binary).
;------------------------------------------------------------------------------------------------------------------------------------------
; Filesize: 100000 Bytes
; Iterations: 4
; Test   Ticks   Pct
;    1   63592  12.7  <== The winner (text only).
;    2  101375  20.2
;    3  128859  25.7
;    4  108439  21.6
;    5   99483  19.8  <== The winner (binary).
;==========================================================================================================================================