BinaryWrite PDF to ASP - Seek error

This Forum is for the use of Software Developers requiring help and assistance for Tracker Software's PDF-Tools SDK of Library DLL functions(only) - Please use the PDF-XChange Drivers API SDK Forum for assistance with all PDF Print Driver related topics.

Moderators: Tracker Support, TrackerSupp-Daniel, Chris - Tracker Supp, Vasyl-Tracker Dev Team, Sean - Tracker, Andrew - Tracker Support, Tracker - Clarion Support, John - Tracker Supp, Tracker Supp-Stefan, Ivan - Tracker Software, Support Staff, moderators

Post Reply
dblwizard
User
Posts: 43
Joined: Fri May 20, 2005 5:39 pm
Location: Conifer, CO USA

BinaryWrite PDF to ASP - Seek error

Post by dblwizard » Wed Dec 10, 2008 7:04 am

Howdy,

I am trying to "stream" a pdf file down to an asp page. I have similar functionality that worked by sending the complete document in one BinaryWrite but I have run into problems because some of the PDF's are very large and by that I mean 10MB and larger. I am wanting to modify my code to send the pdf down in "chunks" using the response.BinaryWrite and response.Flush. I have two problems with my code. The PDF is corrupted somehow and I get a Seek error when I go beyond a certain size. The error occurs in the PXCPDF_WriteBuffer sub below inside the For loop on the line "lRC = mobjStream.Seek(lBufferPtr, STREAM_SEEK_SET)" and the exact error is "Error Number: -2147287015, Description: Automation error - An error occurred during a seek operation."

Here is the VB code:

Implements ObjectControl
Option Explicit

Public Enum enumPDFComponent
pdfPXC = 0
pdfISED = 1
End Enum

Private Const appModuleName = "clsPXCPDF"
Private mobjContext As ObjectContext
Private mobjApplication As Application
Private mobjServer As Server
'Private mobjRequest As Request
Private mabtBuffer() As Byte
Private mobjStream As olelib.IStream
Private mobjStreamStat As olelib.STATSTG
Private mobjDocumentType As clsDocumentTypeDisplay

Private Sub TiffsToPDFPXC(asFileNamesTiffA() As String)
On Error GoTo errHandler

Const appMethodName = "TiffsToPDFPXC"

Dim lpPDF As Long
Dim lRC As Long
Dim i As Long

UpdateLog appModuleName & ":" & appMethodName & " Entering", Logging

lpPDF = PXCPDF_Create()

UpdateLog appModuleName & ":" & appMethodName & " Logging - PXCPDF_Create - lpPDF:" & lpPDF, Logging
For i = LBound(asFileNamesTiffA) To UBound(asFileNamesTiffA)
Call PXCPDF_AddImage(lpPDF, asFileNamesTiffA(i), 0)
UpdateLog appModuleName & ":" & appMethodName & " Logging - PXCPDF_AddImage - lpPDF:" & lpPDF, Logging
Next i

PXCPDF_WriteBuffer (lpPDF)
lRC = PXC_ReleaseDocument(lpPDF)

UpdateLog appModuleName & ":" & appMethodName & " Exiting", Logging
Exit Sub

errHandler:
Err.Record appModuleName, appMethodName, errRaise
Exit Sub
Resume
End Sub

Private Sub PXCPDF_WriteBuffer(lpPDF_A As Long)
On Error GoTo errHandler

Const appMethodName = "PXCPDF_WriteBuffer"
Const BUFFER_SIZE = 10240

Dim lRC As Long
Dim lStreamLength As Long

UpdateLog appModuleName & ":" & appMethodName & " Entering. lpPDF_A:" & lpPDF_A, Logging

Set mobjStream = CreateStreamOnHGlobal(0, -1)
lRC = PXC_WriteDocumentToIStream(lpPDF_A, mobjStream)

If (IS_DS_FAILED(lRC)) Then
UpdateLog appModuleName & ":" & appMethodName & " Error - PXC_WriteDocumentToIStream: IS_DS_FAILED(). lRC = " & lRC & " Msg:" & GetDSErrorString(lRC), Logging
Err.Raise lRC, appModuleName & ":" & appMethodName, " Error - PXC_WriteDocumentToIStream: IS_DS_FAILED(). lRC = " & lRC & " Msg:" & GetDSErrorString(lRC)
Exit Sub
End If

Call UpdateLog(appModuleName & ":" & appMethodName & " - Getting Stream Stats. lRC:" & lRC, Logging)
Call mobjStream.Stat(mobjStreamStat)
Call UpdateLog(appModuleName & ":" & appMethodName & " - Stream size:" & mobjStreamStat.cbSize, Logging)
lStreamLength = CLng(mobjStreamStat.cbSize * 10000)

Dim lSize As Long
Dim lBufferPtr As Long
Dim lRemaining As Long
Dim i As Long
Dim objResponse As Response

Set objResponse = mobjContext("Response")
lSize = lStreamLength \ BUFFER_SIZE
lRemaining = lStreamLength Mod BUFFER_SIZE
ReDim mabtBuffer(BUFFER_SIZE)
lBufferPtr = 0

Call UpdateLog(appModuleName & ":" & appMethodName & " - lSize:" & lSize & ", lRemaining:" & lRemaining, Logging)

For i = 0 To lSize - 1
Call UpdateLog(appModuleName & ":" & appMethodName & " - lBufferPtr:" & lBufferPtr, Logging)
' Call FillByte(mabtBuffer, 0)
lRC = mobjStream.Seek(lBufferPtr, STREAM_SEEK_SET)
Call UpdateLog(appModuleName & ":" & appMethodName & " - Seek-lRC:" & lRC, Logging)
lRC = mobjStream.Read(mabtBuffer(0), BUFFER_SIZE)
Call UpdateLog(appModuleName & ":" & appMethodName & " - i:" & i & ", Read-lRC:" & lRC, Logging)
objResponse.BinaryWrite (mabtBuffer)
objResponse.Flush
lBufferPtr = lBufferPtr + BUFFER_SIZE
Next i

ReDim mabtBuffer(lRemaining)
' Call FillByte(mabtBuffer, 0)
Call UpdateLog(appModuleName & ":" & appMethodName & " - lBufferPtr:" & lBufferPtr, Logging)
mobjStream.Seek lBufferPtr, STREAM_SEEK_SET
lRC = mobjStream.Read(mabtBuffer(0), lRemaining)
objResponse.BinaryWrite (mabtBuffer)
objResponse.Flush

Set objResponse = Nothing
Set mobjStream = Nothing

Call UpdateLog(appModuleName & ":" & appMethodName & " - Exiting.", Logging)

Exit Sub

errHandler:
Err.Record appModuleName, appMethodName, errRaise
Exit Sub
Resume
End Sub

Here is the ASP code:

<%@ Language=VBScript %>
<% Option Explicit %>
<!--#include file='includes/Application.inc'-->
<!-- #include file='includes/ServerUtils.inc' -->
<%
Dim objPDF
Dim sDocumentType
Dim sInstrument

sDocumentType = Request.QueryString("DocumentType") & ""
sInstrument = Request.QueryString("Instrument") & ""

If Len(sDocumentType) > 0 AND Len(sInstrument) > 0 Then
Set objPDF = Server.CreateObject("LEImage.clsPXCPDF")
Response.ContentType = "application/pdf"

Response.AddHeader "Content-disposition", _
"inline; filename=" + StripOutPage(sInstrument) + "_doc.pdf"
Call objPDF.GetDocumentPDF(sDocumentType, sInstrument, "")

Set objPDF = Nothing
Response.End
Else
Response.Write "Invalid querystring parameters!<br>sDocumentType:" & sDocumentType & "**<br/>" & _
"sInstrument:" & sInstrument & "**"
Response.End
End If
%>

Thanks

dblwizard

Lzcat - Tracker Supp
Site Admin
Posts: 711
Joined: Thu Jun 28, 2007 8:42 am

Re: BinaryWrite PDF to ASP - Seek error

Post by Lzcat - Tracker Supp » Thu Dec 11, 2008 7:25 am

looks like your problem is not related to PDF-XChange, but there is something wrong whe you deal with IStream. Can you try to sent some other file same way (for example zip archive - to have possibility verify integrity)?
Looking to your code I don't unserstood this line:

Code: Select all

lStreamLength = CLng(mobjStreamStat.cbSize * 10000)
mobjStreamStat.cbSize should contain real size in bytes, so I wondering why it should be multiplied.
Victor
Tracker Software
Project manager

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.

dblwizard
User
Posts: 43
Joined: Fri May 20, 2005 5:39 pm
Location: Conifer, CO USA

Re: BinaryWrite PDF to ASP - Seek error

Post by dblwizard » Thu Dec 11, 2008 7:50 am

To be honest I'm not 100% sure. I wrote the original code back in 2000 and don't remember all of the resources that I used to write it. Part of it came from help here in the post:

http://www.tracker-software.com/forum3/ ... zard#p3977

I tried to look at the attachment of that link to see if the code was in there but the attachment is no longer available. The way that I have had this working in the past is using the following function that was much simpler and then using a BinaryWrite on the actual asp page and this code has been working without problems for 3 years:

Private Function PXCPDF_GetBuffer(lpPDF_A As Long) As Byte()
On Error GoTo errHandler

Const appMethodName = "PXCPDF_GetBuffer"

Dim lRC As Long
Dim lStreamLength As Long

UpdateLog appModuleName & ":" & appMethodName & " Entering. lpPDF_A:" & lpPDF_A, Logging

Set mobjStream = CreateStreamOnHGlobal(0, -1)
lRC = PXC_WriteDocumentToIStream(lpPDF_A, mobjStream)

If (IS_DS_FAILED(lRC)) Then
UpdateLog appModuleName & ":" & appMethodName & " Error - PXC_WriteDocumentToIStream: IS_DS_FAILED(). lRC = " & lRC & " Msg:" & GetDSErrorString(lRC), Logging
Err.Raise lRC, appModuleName & ":" & appMethodName, " Error - PXC_WriteDocumentToIStream: IS_DS_FAILED(). lRC = " & lRC & " Msg:" & GetDSErrorString(lRC)
Exit Function
End If

Call UpdateLog(appModuleName & ":" & appMethodName & " - Getting Stream Stats. lRC:" & lRC, Logging)
Call mobjStream.Stat(mobjStreamStat)
Call UpdateLog(appModuleName & ":" & appMethodName & " - Stream size:" & mobjStreamStat.cbSize, Logging)
lStreamLength = CLng(mobjStreamStat.cbSize * 10000)
ReDim mabtBuffer(lStreamLength + 2)
mobjStream.Seek 0, STREAM_SEEK_SET
lRC = mobjStream.Read(mabtBuffer(0), lStreamLength)
PXCPDF_GetBuffer = mabtBuffer
Set mobjStream = Nothing

Call UpdateLog(appModuleName & ":" & appMethodName & " - Exiting.", Logging)

Exit Function

errHandler:
Err.Record appModuleName, appMethodName, errRaise
Exit Function
Resume
End Function

And here is the asp page code:

<%@ Language=VBScript %>
<% Option Explicit %>
<!--#include file='includes/Application.inc'-->
<!-- #include file='includes/ServerUtils.inc' -->
<%
Dim objPDF
Dim sDocumentType
Dim sInstrument

sDocumentType = Request.QueryString("DocumentType") & ""
sInstrument = Request.QueryString("Instrument") & ""

If Len(sDocumentType) > 0 AND Len(sInstrument) > 0 Then
Set objPDF = Server.CreateObject("LEImage.clsPXCPDF")
Response.ContentType = "application/pdf"

Response.AddHeader "Content-disposition", _
"inline; filename=" + StripOutPage(sInstrument) + "_doc.pdf"
Response.BinaryWrite objPDF.GetDocumentPDF(sDocumentType, sInstrument, "")

Set objPDF = Nothing
Response.End
Else
Response.Write "Invalid querystring parameters!<br>sDocumentType:" & sDocumentType & "**<br/>" & _
"sInstrument:" & sInstrument & "**"
Response.End
End If
%>

dblwizard
User
Posts: 43
Joined: Fri May 20, 2005 5:39 pm
Location: Conifer, CO USA

Re: BinaryWrite PDF to ASP - Seek error

Post by dblwizard » Thu Dec 11, 2008 8:43 am

I don't think that mobjStreamStat.cbSize is the actual size. First it is a currency data type and when I combine a 10 page document cbSize is 22.774. so if I convert that to a Long Im going to loose the .774. My guess is maybe it should be 1000 instead of 10000. Any other thoughts?

dblwizard
User
Posts: 43
Joined: Fri May 20, 2005 5:39 pm
Location: Conifer, CO USA

Re: BinaryWrite PDF to ASP - Seek error

Post by dblwizard » Thu Dec 11, 2008 9:25 am

In doing a few more tests cbSize comes back with up to 4 digits to the right of the decimal place. Thus the need to multiply by 10000.

Thanks

dbl

Lzcat - Tracker Supp
Site Admin
Posts: 711
Joined: Thu Jun 28, 2007 8:42 am

Re: BinaryWrite PDF to ASP - Seek error

Post by Lzcat - Tracker Supp » Thu Dec 11, 2008 6:03 pm

mobjStreamStat.cbSize has NOT currency format! Is is ULARGE_INTEGER (unsigned 64 bit integer) - see http://msdn.microsoft.com/en-us/library ... S.85).aspx
You may try use ULong (http://msdn.microsoft.com/en-us/library/9zsfkcew.aspx) for holding stream length.
Victor
Tracker Software
Project manager

Please archive any files posted to a ZIP, 7z or RAR file or they will be removed and not posted.

dblwizard
User
Posts: 43
Joined: Fri May 20, 2005 5:39 pm
Location: Conifer, CO USA

Re: BinaryWrite PDF to ASP - Seek error

Post by dblwizard » Thu Dec 11, 2008 6:25 pm

Well I think we are going down the wrong path here as the code that has been working is the same implementation of the cbSize. I am going off of what the ObjectBrowser shows for the olelib.STATSTG. It shows the cbSize to be "Currency" as you can see from the jpg that I have attached. I am using third party implmentation to get the olelib interfaces called "Edanmo's OLE interfaces & functions v1.81" and "Edanmo's OLE interfaces for Implments v1.51". This is the only way that I have been able to find to get to the OLELIB interfaces. If you have a better way I'm all ears but I think that is why we are seeing a difference in the interface definition. Also remember that this is VB6 not vb.net.

As I stated earlier I have a version that does a single BinaryWrite to dump the PDF down and it works fine. So is there anything else you can see that might be the problem or do you have a better way to get access to the Stream object in VB6.

Thanks
Attachments
VB Snapshot.zip
This is a screen shot of VB with the object browser open. You can see that it defines cbSize as Currency
(96.83 KiB) Downloaded 215 times

Post Reply