It is currently Sat Nov 25, 2017 2:59 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: GZip and Deflate in IIS
PostPosted: Sat May 06, 2017 9:36 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Wed Sep 22, 2010 1:50 am
Posts: 765
Location: Bradenton, FL
Many thanks to JHPJHP for his beautiful code! I have adapted it for my needs. This is a dll wrapper I created to use inside other dll's for Microsoft Internet Information Server (IIS). Since it lives inside a server process, the compressed data just overwrites the source data.

zlib_wrapper_64.pb
Code:
EnableExplicit

#Z_NO_FLUSH                =  0
#Z_PARTIAL_FLUSH           =  1
#Z_SYNC_FLUSH              =  2
#Z_FULL_FLUSH              =  3
#Z_FINISH                  =  4
#Z_BLOCK                   =  5
#Z_TREES                   =  6
                             
#Z_OK                      =  0
#Z_STREAM_END              =  1
#Z_NEED_DICT               =  2
#Z_ERRNO                   = -1
#Z_STREAM_ERROR            = -2
#Z_DATA_ERROR              = -3
#Z_MEM_ERROR               = -4
#Z_BUF_ERROR               = -5
#Z_VERSION_ERROR           = -6

#Z_DEFAULT_COMPRESSION     = -1
#Z_NO_COMPRESSION          =  0
#Z_BEST_SPEED              =  1
#Z_BEST_COMPRESSION        =  9
                             
#Z_DEFAULT_STRATEGY        =  0
#Z_FILTERED                =  1
#Z_HUFFMAN_ONLY            =  2
#Z_RLE                     =  3
#Z_FIXED                   =  4
                             
#Z_BINARY                  =  0
#Z_TEXT                    =  1
#Z_ASCII                   =  1
#Z_UNKNOWN                 =  2
                             
#Z_NULL                    =  0
#Z_DEFLATED                =  8
                             
#MAX_MEM_LEVEL             =  9
#MAX_WBITS                 = 15
#GZIP_ENCODING             = 16
                             
#OS_FAT                    =  0
#OS_AMIGA                  =  1
#OS_VMS                    =  2
#OS_UNIX                   =  3
#OS_VM_CMS                 =  4
#OS_ATARI_TOS              =  5
#OS_HPFS                   =  6
#OS_MACINTOSH              =  7
#OS_Z_SYSTEM               =  8
#OS_CP_M                   =  9
#OS_TOPS_20                = 10
#OS_NTFS                   = 11
#OS_QDOS                   = 12
#OS_ACORN_RISCOS           = 13
                             
#ZLIB_VERSION              = "1.2.8"
#CHUNK_SIZE                = 1024 * 256

Structure Z_STREAM Align #PB_Structure_AlignC
    *next_in
    avail_in.l
    total_in.l
    *next_out
    avail_out.l
    total_out.l
    *msg
    *state
    *zalloc
    *zfree
    *opaque
    data_type.l
    adler.l
    reserved.l
EndStructure

Structure GZ_HEADER Align #PB_Structure_AlignC
    text.l
    time.l
    xflags.l
    os.l
    *extra
    extra_len.l
    extra_max.l
    *name
    name_max.l
    *comment
    comm_max.l
    hcrc.l
    done.l
EndStructure

ImportC "zlib_64.lib"
    compress2(*destinBuffer, *destinSize, *sourceBuffer, sourceSize.i, compressLevel.i)
    deflate(*stream, flush)
    deflateBound(*stream, sourceLen)
    deflateEnd(*stream)
    deflateInit2_(*stream, level, method, windowBits, memLevel, strategy, version.p-ascii, strm_size)
    deflateSetHeader(*stream, *head)
EndImport

ProcedureDLL.i AttachProcess(instance.i)
EndProcedure

ProcedureDLL.i DetachProcess(instance.i)
EndProcedure

ProcedureDLL.i AttachThread(instance.i)
EndProcedure

ProcedureDLL.i DetachThread(instance.i)
EndProcedure

; **********************************************************************************
; dll procedure to pack a memory area into a new memory area using ZLib
; **********************************************************************************

ProcedureDLL.i PackMemoryZlib(*sourceBuffer, sourceSize, compressLevel = 9)

; *sourceBuffer  = pointer to the source buffer
;  sourceSize    = size of the source buffer
;  compressLevel = compression level

; NOTE: #Z_DATA_ERROR means the file cannot be compressed
; NOTE: CompressLevel must be between 0 (lowest) and 9 (highest)
; NOTE: The compressed file will be written on top of the source file

   Protected result.i
    Protected compressErr.i
    Protected destinSize.i   = sourceSize * 1.4
   Protected destinBuffer.s = Space(destinSize)

    If *sourceBuffer <= 0
        ProcedureReturn #Z_MEM_ERROR
    EndIf

    If sourceSize <= 0
        ProcedureReturn #Z_MEM_ERROR - 10
    EndIf

    If compressLevel < 0 Or compressLevel > 9
        ProcedureReturn #Z_MEM_ERROR - 100
    EndIf

; now compress the data, and see what we get in return

    result = compress2(@destinBuffer, @destinSize, *sourceBuffer, sourceSize, compressLevel)

    Select result
    Case #Z_OK
        If destinSize >= sourceSize
            result = #Z_DATA_ERROR
        Else
         CopyMemory(@destinBuffer, *sourceBuffer, destinSize)
            result = destinSize
        EndIf
    Case -3; Z_DATA_ERROR
        result = #Z_BUF_ERROR
    Case -4, -5; Z_ERROR_MEM, Z_BUF_ERROR
        result = #Z_STREAM_ERROR
    Default; ANYTHING ELSE
        result = #Z_ERRNO
    EndSelect

    ProcedureReturn result

EndProcedure

; **********************************************************************************
; procedure to deflate the data itself
; **********************************************************************************

Procedure.i Deflate_Payload(*destinBuffer, destinSize, *sourceBuffer, sourceSize, *sourceName)

   Protected nOut.i            = 0
   Protected nSize.i           = 0
   Protected nStart.i          = 0
    Protected headerComment.s   = "Compressed in gzip format"
    Protected *output           = AllocateMemory(#CHUNK_SIZE)
    Protected *stream.Z_STREAM  = AllocateMemory(SizeOf(Z_STREAM))
    Protected *header.GZ_HEADER = AllocateMemory(SizeOf(GZ_HEADER))
    Protected windowBits.i      = (15 | #GZIP_ENCODING)

    *stream\zalloc    = #Z_NULL
    *stream\zfree     = #Z_NULL
    *stream\opaque    = #Z_NULL
    *stream\data_type = #Z_BINARY
    deflateInit2_(*stream, #Z_DEFAULT_COMPRESSION, #Z_DEFLATED, windowBits, #MAX_MEM_LEVEL, #Z_DEFAULT_STRATEGY, #ZLIB_VERSION, SizeOf(Z_STREAM))
    *header\name      = *sourceName
    *header\comment   = @headerComment
    *header\text      = #Z_NULL
    *header\time      = Date() + 60 * 60 * 4
    *header\xflags    = #Z_NULL
    *header\os        = #OS_NTFS
    *header\extra_len = #Z_NULL
    *header\extra_max = #Z_NULL
    *header\name_max  = #Z_NULL
    *header\comm_max  = #Z_NULL
    *header\hcrc      = #Z_NULL
    *header\done      = #Z_NULL

    deflateSetHeader(*stream, *header)

    *stream\next_in    = *sourceBuffer
    *stream\avail_in   = sourceSize

    Repeat
        *stream\avail_out = #CHUNK_SIZE
        *stream\next_out  = *output
        deflate(*stream, #Z_FINISH)
        nOut  = #CHUNK_SIZE - *stream\avail_out
        nSize = nSize + nOut

        If nSize = 0
            Break
        EndIf

        CopyMemory(*output, *destinBuffer + nStart, nOut)
        nStart + nOut
    Until *stream\avail_out <> 0

    deflateEnd(*stream)

    FreeMemory(*header)
    FreeMemory(*stream)
   FreeMemory(*output)

   ProcedureReturn nSize

EndProcedure

; **********************************************************************************
; dll procedure to pack a memory area into a new memory area using ZLib Gzip
; **********************************************************************************

ProcedureDLL.i PackGzipZlib(*sourceBuffer, sourceSize, *sourceName)

; *sourceBuffer  = pointer to the source buffer
;  sourceSize    = size of the source buffer

; NOTE: #Z_DATA_ERROR means the file cannot be compressed
; NOTE: The compressed file will be written on top of the source file

   Protected result.i
    Protected compressErr.i
    Protected destinSize.i   = sourceSize * 1.4
   Protected destinBuffer.s = Space(destinSize)

    If *sourceBuffer <= 0
        ProcedureReturn #Z_MEM_ERROR
    EndIf

    If sourceSize <= 0
        ProcedureReturn #Z_MEM_ERROR - 10
    EndIf

; now compress the data, and see what we get in return

    result = Deflate_Payload(@destinBuffer, destinSize, *sourceBuffer, sourceSize, *sourceName)

    If result > 0
      destinSize = result
        If destinSize >= sourceSize
            result = #Z_DATA_ERROR
        Else
         CopyMemory(@destinBuffer, *sourceBuffer, destinSize)
        EndIf
   Else
        result = #Z_ERRNO
    EndIf

    ProcedureReturn result

EndProcedure

CompilerIf #PB_Compiler_Thread = 0
    CompilerError "ZLib components must be compiled with threadsafe enabled!"
CompilerEndIf

Here is the process I used to test the compression files for validity, prior to utilizing inside my IIS dll processes.

check_compression.pb
Code:
EnableExplicit

Define result.i
Define anyFile.s
Define fileName.s
Define libNumber.i
Define resultLine.s
Define sourceSize.i
Define sourceName.s
Define sourceBuffer.s
Define libraryName.s  = "zlib_wrapper_64.dll"

; open the library needed

libNumber = OpenLibrary(#PB_Any, libraryName)
If libNumber <= 0
    MessageRequester("Test", "Unable To open " + libraryName)
    End
EndIf

; create prototypes for the compression dll

Prototype compressGzip(*sourceBuffer, sourceSize.i, *sourceName)
Prototype compressDflt(*sourceBuffer, sourceSize, compressLevel.i)

; now define the global we will need to call the functions

Global compressGzip.compressGzip = GetFunction(libNumber, "PackGzipZlib")
Global compressDflt.compressDflt = GetFunction(libNumber, "PackMemoryZlib")

anyFile = OpenFileRequester("Inflate / Deflate", "", "All files (*.*)|*.*", 0)

If anyFile
    sourceSize = FileSize(anyFile)

    Select #True
    Case Bool(sourceSize < 0)
        MessageRequester("Compression Test", "There was a problem opening the file, operation cancelled.")
    Case Bool(sourceSize = 0)
        MessageRequester("Compression Test", "File is empty, operation cancelled.")
    Case Bool(sourceSize > 1024 * 1024 * 1024)
        MessageRequester("Compression Test", "File is greater than 1Gb, operation cancelled.")
    Default
        fileName = GetFilePart(anyFile)

        If ReadFile(0, anyFile, #PB_File_SharedRead | #PB_File_SharedWrite | #PB_File_NoBuffering)
            sourceBuffer = Space(sourceSize + 1)
            ReadData(0, @sourceBuffer, sourceSize)
            CloseFile(0)
        EndIf

        result     = compressGzip(@sourceBuffer, sourceSize.i, @sourceName)
        resultLine = "GZip'd size = " + Str(result) + #CRLF$

        If CreateFile(0, anyFile + ".gz", #PB_File_NoBuffering)
            WriteData(0, @sourceBuffer, result)
            CloseFile(0)
        EndIf

        result     = compressDflt(@sourceBuffer, sourceSize, 9)
        resultLine + "Deflate'd size = " + Str(result)

        If CreateFile(0, anyFile + ".df", #PB_File_NoBuffering)
            WriteData(0, @sourceBuffer, result)
            CloseFile(0)
        EndIf

        MessageRequester("Compression Test", resultLine)
    EndSelect
Else
    MessageRequester("Compression Test", "Could Not Read the file.")
EndIf

End


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye