Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
;zlibUDF returns one of the following: ; buf: handle to a valid compressed buffer, if calling function with "compress" parameter ; which you must "binaryFree" this in your main program ; data: handle to the uncompressed buffer, if calling function with "decompress" or "uncompress" parameter ; This NO LONGER closes out the buffer that was passed to it. It must be closed by the user using "binaryFree" ;Errors returns: ; 0: invalid parameter passed to zlibUDF(), or ZLIB1.DLL doesn't exist ; -1: zero-byte string or file...cannot compress/decompress ; -2: if there was another problem with the actual DLLCall of the ZLIB1.DLL #DefineFunction zlibUDF(data,compOrDecomp) ;this could be a valid filename or just a string. If it's a filename, then it will get converted to a string. ; VALIDATE ZLIB COMPRESSION LIBRARY dll = "zlib1.dll" ;needs to be in the system path, or in the directory of the main EXE calling this UDF ; zlib1.dll can be located here: http://www.gzip.org/zlib/ If !FileExist(StrCat(DirWindows(1),dll)) ;if dll does not exist in system directory If FileExist(StrCat(FilePath(IntControl(1004,0,0,0,0)),dll)) ;if dll exists in current wbt path FileCopy(StrCat(FilePath(IntControl(1004,0,0,0,0)),dll),DirWindows(1),@FALSE) ;copy it to system directory Else Return 0 ;otherwise throw an error. EndIf EndIf ; VALIDATE COMPRESSION/DECOMPRESSION PARAMETER If StriCmp(compOrDecomp,"compress") != 0 && StriCmp(compOrDecomp,"uncompress") != 0 && StriCmp(compOrDecomp,"decompress") != 0 Message("zlib Error!",StrCat('"',compOrDecomp,'" is not a valid parameter for zlibUDF()!')) Return 0 EndIf ; CHECK IF INPUT IS A FILE, STRING OR A BUFFER AND GET THE SIZE If FileExist(data) size = FileSize(data) ;if so, get it's size dataType = "FILE" Else If BinaryBufInfo(data,-1) == @TRUE ;if it's a valid buffer size = binaryEodGet(data) ;gets the size of the INITIALIZED data in the buffer dataType = "BUF" Else size = StrLen(data) ;otherwise get the size of the string itself. dataType = "STRING" EndIf EndIf ; COMPRESS If StriCmp(compOrDecomp,"compress") == 0 ; RETURN ERROR IF THE DATA IS 0 BYTES If size == 0 Then Return (-1) ; PREP THE SOURCE LENGTH BUFFER size = StrFixLeft(size,"0",15) ;this is the original size, which will get appended onto the last 15 bytes of the buffer sourceLen = DllCallCDecl(dll,long:"compressBound",long:size) ;gets a minimum amount of space to allocate for the Dest buffer, but this ; value is slightly larger because zLib1.dll needs extra space for swapping ; READ THE FILE OR STRING INTO THE SOURCE BUFFER If dataType == "FILE" || dataType == "STRING" bufSource = BinaryAlloc(sourceLen) ;create a buffer the size of the source file or string If dataType == "FILE" BinaryRead(bufSource,data) ;file Else ;dataType == "STRING" BinaryPokeStr(bufSource,0,data) ;string EndIf Else bufSource = data ;data is already a buffer, so just set bufSource equal to it for uniformity. EndIf ; PREP THE DEST LENGTH BUFFER destLen = sourceLen bufDestLen = BinaryAlloc(destLen) ;create a buffer that will tell how long the destination buffer should be BinaryPoke4(bufDestLen,0,destLen) ; and poke that value into the buffer ; PREP THE DEST BUFFER bufDest = BinaryAlloc(destLen+15) ;create a buffer that will contain the final compressed data, plus 15 extra bytes ; COMPRESS THE SOURCE BUFFER INTO THE DEST BUFFER ret = DllCallCDecl(dll,long:"compress",LPBINARY:bufDest,LPBINARY:bufDestLen,LPBINARY:bufSource,LONG:sourceLen) If ret != 0 BinaryFree(bufDestLen) ; dataType <> "BUF" then BinaryFree(bufSource) ;free up the memory from the now-unused buffers BinaryFree(bufDest) ; Return(-2) EndIf ; ADD ORIGINAL SOURCE LENGTH TO THE END OF THE COMPRESSED DATA FOR UNCOMPRESSING LATER BinaryEodSet(bufDest,BinaryPeek4(bufDestLen,0)+15) ;add 15 bytes onto the end of the compressed buffer, after the last initialized byte BinaryPokeStr(bufDest,BinaryPeek4(bufDestLen,0),size) ;and then poke the original uncompressed size onto the end of the buffer (for "uncompress" to use later) BinaryFree(bufDestLen) ;free up the memory from the now-unused buffers If dataType <> "BUF" Then BinaryFree(bufSource) ;don't free the passed in buffer. That's up to the caller to do I should think. Return(bufDest) ;returns a buffer handle to the compressed data EndIf ; DECOMPRESS If StriCmp(compOrDecomp,"uncompress") == 0 || StriCmp(compOrDecomp,"decompress") == 0 ;PREP SOURCE DATA BUFFER If dataType == "BUF" bufSource = data Else bufSource = BinaryAlloc(size) ;size was defined towords top of function If dataType == "FILE" BinaryRead(bufSource,data) ;read data file into buffer Else ;dataType == "STRING" BinaryPokeStr(bufSource,0,data) ;poke data string into buffer EndIf EndIf ; GET LENGTHS OF SOURCE AND DESTINATION DATA INTO BUFFERS sourceLen = size-15 ;the actual buffer length is 15 bytes less than we've got size = BinaryPeekStr(bufSource,sourceLen,15) ; because the last 15 bytes is actually the size of the uncompressed data. BinaryEodSet(bufSource,sourceLen) ; and we need to reset the buffer to cut off those last 15 bytes once we have the value ; PREP DESTINATION LENGTH BUFFER destLen = DllCallCDecl(dll,long:"compressBound",long:size) ;gets a minimum amount of space to allocate for the Dest buffer, but this ; value is slightly larger because zLib1.dll needs extra space for swapping bufDestLen = BinaryAlloc(destLen) ;create a buffer that will tell how long the destination buffer should be BinaryPoke4(bufDestLen,0,destLen) ; and poke that value into the buffer ; PREP THE DESTINATION BUFFER bufDest = BinaryAlloc(destLen) ;create a buffer that will contain the final compressed data ; DECOMPRESS THE SOURCE BUFFER INTO THE DESTINATION BUFFER ret = DllCallCDecl(dll,long:"uncompress",LPBINARY:bufDest,LPBINARY:bufDestLen,LPBINARY:bufSource,LONG:sourceLen) BinaryEodSet(bufDest,size) ;truncate the extra characters from the end of the buffer to match the original size BinaryFree(bufDestLen) ; If dataType <> "BUF" Then BinaryFree(bufSource) ;don't free the passed in buffer. That's for the caller to do, I should think. If ret != 0 Then Return(-2) ; if there was a problem with the call to the DLL, then return (-2), Else Return bufDest ; otherwise, return the uncompressed buffer EndIf #EndFunction zlibUDF ; Example(s) ; CREATE RANDOM DATA BoxOpen("zLib","Creating random data.") data = "" For x = 1 To 1000 data = StrCat(data,Random(99999999999),@CRLF) Next ;x ; LOAD DATA INTO A BUFFER AND WRITE TO A FILE bufData = BinaryAlloc(StrLen(data)) BinaryPokeStr(bufData,0,data) BinaryWrite(bufData,"c:\_1-data.txt") ; COMPRESS BUFFER buf = zLibUDF(bufData,"COMPRESS") BinaryFree(bufData) ; WRITE COMPRESSED DATA TO A FILE BinaryWrite(buf,"c:\_2-compressed.txt") BinaryFree(buf) ; LOAD COMPRESSED DATA INTO BUFFER buf = BinaryAlloc(FileSize("c:\_2-compressed.txt")) BinaryRead(buf,"c:\_2-compressed.txt") ; UNCOMPRESS COMPRESSED DATA AND WRITE IT TO FILE bufUn = zLibUDF(buf,"UNCOMPRESS") BinaryFree(buf) BinaryWrite(bufUn,"c:\_3-uncompressed.txt") Message("Buffer Test","Check c:\_.txt for results") Exit
Article ID: W16712
File Created: 2005:02:18:12:21:56
Last Updated: 2005:02:18:12:21:56