简体   繁体   中英

Having trouble inflating a base64 string: zlib error: -3

My app receives a PDF as a base64, zLib deflated string in an xml file. At least that's the format I'm told it is in. It gets stored in a database, then I need to recreate the PDF from that string. I created a test app to figure it out. The function below takes the string and is supposed to return it in a decoded, inflated format which I believe I'll be able to use to rebuild the original PDF (I'm not there yet).

I've done lots of research and found a few different libraries and ways to do this as well as received a java program from the developer who is sending me the PDF to use as an example. However I can not get the string to a usable format. Using the ManagedZLib.dll and the function below seems to get me the closest. As far as I can tell from debugging, everything works until I try to decompress:

zStream.Read(decompressedBytes, 0, decodedBytes.Length - 1)

This produces a "zLib error: -3". The only info I can find on that error is it is a 'data error'. There is very little other information on the web about it.

Any help getting past this error, or thoughts on a different/better approach to accomplish my end goal is greatly appreciated.

Public Function DecompressString4(ByVal origString As String) As String

    Dim returnString = Nothing
    ' get the base64 content into String
    ManagedZLib.ManagedZLib.Initialize()

    '// parse the string into a byte array
    Dim b64bytes() As Byte = System.Text.Encoding.UTF8.GetBytes(origString)
    Dim decodedBytes() As Byte = Nothing

    'decode the byte array into another byte array, but this time of Base 64.
    Using ms As New MemoryStream(b64bytes)
        Using zStream As New ManagedZLib.Base64Stream(ms, Base64Options.Decode)
            ReDim decodedBytes(b64bytes.Length)
            zStream.Read(decodedBytes, 0, b64bytes.Length)
        End Using
    End Using

    decmpStrTxtBox.Text = Convert.ToString(decodedBytes)

    Dim decompressedBytes() As Byte = Nothing

    ' inflate the base64 array
    Using ms2 As New MemoryStream(decodedBytes)
        Using zStream As New ManagedZLib.CompressionStream(ms2, CompressionOptions.Decompress)
            'ReDim decompressedBytes(origString.Length)
            ReDim decompressedBytes(decodedBytes.Length)
            zStream.Read(decompressedBytes, 0, decodedBytes.Length - 1)
        End Using
    End Using

    'write output to a stream
    returnString = Convert.ToString(decompressedBytes)
    ManagedZLib.ManagedZLib.Terminate()

    Return returnString

End Function

Apparently I was making it too complicated. Here is the final solution for taking a base64 deflated string, decoding it, then inflating it and outputting a PDF from it. It could easily be tweaked to return the resulting string if needed. I ended up having much better results by not including any libraries (that were supposed to make it easier :-) ). I didn't actually find an answer to the error I was receiving and only assume that library wasn't designed for my purposes. Using the built in .net classes did the trick much better (Convert.FromBase64String and System.IO.Compression.DeflateStream).

I hope this helps someone in the future as I couldn't find an example of this anywhere.

Imports System.IO
Imports System.IO.Compression
Imports System.Text

    Public Sub DecompressString(ByVal origString As String)

    Dim decodedDeflatedBytes() As Byte = Nothing
    Dim decodedInflatedBytes() As Byte = Nothing

    'parse the string into a decoded byte array
    decodedDeflatedBytes = Convert.FromBase64String(origString)

    'once around the block to get the length of the buffer we'll need
    Dim decompressedBufferLength As Integer = 0
    Using ms1 As New MemoryStream(decodedDeflatedBytes)
        Using dStream1 As System.IO.Compression.DeflateStream = New System.IO.Compression.DeflateStream(ms1, Compression.CompressionMode.Decompress)
            While dStream1.ReadByte <> -1  ' -1 indicates nothing left to read
                decompressedBufferLength += 1
            End While
        End Using
    End Using

    'a second time around the block to do the actual inflation now that we have the length
    Using ms2 As New MemoryStream(decodedDeflatedBytes)
        Using dStream2 As System.IO.Compression.DeflateStream = New System.IO.Compression.DeflateStream(ms2, Compression.CompressionMode.Decompress)
            ReDim decodedInflatedBytes(decompressedBufferLength - 1) '11711
            dStream2.Read(decodedInflatedBytes, 0, decompressedBufferLength) '11712
        End Using
    End Using

    'output the PDF with a 'save as' prompt
    Response.ClearContent()
    Response.ClearHeaders()
    Response.Clear()
    Response.ContentType = "Application/pdf"
    Response.AddHeader("Content-Length", decodedInflatedBytes.Length.ToString)
    Response.AddHeader("content-disposition", "attachment;filename=YourReport.pdf")
    Response.BinaryWrite(decodedInflatedBytes)
    Response.End()

End Sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM