open-insight/SYSPROG/STPROC/RTI_HTTP_DOWNLOAD_UI.txt
2024-03-25 15:17:34 -07:00

478 lines
15 KiB
Plaintext

compile function rti_HTTP_Download_UI( object, method, param1, param2, param3, param4, param5, param6, param7, param8 )
/*
** Copyright (C) 2012-2019 Revelation Software Inc. All Rights Reserved **
Author : Captain C
Date : June 2019
Purpose : Commuter module for the RTI_HTTP_DOWNLOAD_UI form
Comments
========
Amended Date Reason
======= ==== ======
Mr C 09 Mar 22 The form's visibility is controlled from it's caller
(i.e. rti_HTTP_Download)
*/
#pragma precomp event_precomp
declare function get_Property, retStack, rti_Res2Str, rti_ErrorText
declare function rti_Convert, msWin_GetTickCount64, exec_Method
$insert rti_HTTP_Download_Equates
$insert ps_HTTPClient_Equates
$insert rti_Resources_Equates
$insert rti_SSP_Equates
$insert logical
equ UDP_TIMEDATA$ to "@_TIMEDATA"
if assigned( object ) else object = ""
if assigned( method ) else method = ""
if assigned( param1 ) else param1 = ""
if assigned( param2 ) else param2 = ""
if assigned( param3 ) else param3 = ""
if assigned( param4 ) else param4 = ""
if assigned( param5 ) else param5 = ""
if assigned( param6 ) else param6 = ""
if assigned( param7 ) else param7 = ""
if assigned( param8 ) else param8 = ""
errorText = ""
abort = FALSE$
retVal = ""
atWindow = object[1,"."]
atCtrl = object[col2()+1,\00\]
if bLen( atWindow ) else
atWindow = @window
end
if bLen( method ) then
locate method in "CREATE,CLOSE,PROGRESS,READYSTATECHANGED,TIMEOUT" using "," setting pos then
on pos goSub onCreate,onClose,onProgress,onReadyStateChanged,onTimeout
end else
// ERR002: Invalid method "%1% passed to the %2% procedure
errorText = rti_Res2Str( RESID$, "ERR002", method : @fm : retStack()<1> )
abort = TRUE$
end
end else
// ERR001: No method passed to the %1% procedure
errorText = rti_Res2Str( RESID$, "ERR001", retStack()<1> )
abort = TRUE$
end
return retVal
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// onClose subroutine
//
// CLOSE event handler for the
//
// ----------------------------------------------------------------------------
onClose:
rs = .hcl_Download->readyState
begin case
case ( rs == PS_HCL_RS_UNSENT$ )
null
case ( rs == PS_HCL_RS_DONE$ )
null
case OTHERWISE$
@@window->$@_ABORT = TRUE$
.hcl_Download->abort( "" )
goSub hclDownload_ReturnResponse
end case
return
///////////////////////////////////////////////////////////////////////////////
// onCreate subroutine
//
// CREATE event handler
//
// ----------------------------------------------------------------------------
// [i] param1 : CreateParam. Contains an @fm delimited list UI information
// : as passed to the RTI_HTTP_DOWNLOAD proc
// ----------------------------------------------------------------------------
onCreate:
@@window->$@_CREATEPARAM = param1
startTime = msWin_GetTickCount64()
prevTime = startTime
timeData = startTime : @fm : prevTime
@@window->$@_TIMEDATA = timeData
if ( param1<HDL_UIPARAM_POS_SYNCPROGRESS$> ) then
.prb_Download->SyncTaskBar = TRUE$
end
// The form's visibility is controlled from rti_HTTP_Download()
// @atWindow->visible = TRUE$
if ( param1<HDL_UIPARAM_POS_MODAL$> ) then
call set_Property( param1<HDL_UIPARAM_POS_PARENTWIN$>, "ENABLED", FALSE$ )
end
// We're all set - return to the caller to set the HCL_DOWNLOAD properties
// execute the OPEN/SEND methods ...
return
///////////////////////////////////////////////////////////////////////////////
// onProgress subroutine
//
// PROGRESS event dispatch handler
//
// ----------------------------------------------------------------------------
// [i] param1 : bytesReceived. Number of bytes received between this PROGRESS
// : event and the previous one
// [i] param2 : bytesDownloaded. Total Number of bytes downloaded so far
// [i] param3 : bytesExpected. Total number of bytes expected from the server
// ----------------------------------------------------------------------------
onProgress:
bytesReceived = param1
bytesDownloaded = param2
bytesExpected = param3
begin case
case ( atCtrl == "HCL_DOWNLOAD" )
goSub hclDownload_OnProgress
end case
return
///////////////////////////////////////////////////////////////////////////////
// onReadyStateChanged subroutine
//
// READYSTATECHANGED event dispatch handler
//
// ----------------------------------------------------------------------------
// [i] param1 : newState
// ----------------------------------------------------------------------------
onReadyStateChanged:
newState = param1
begin case
case ( atCtrl == "HCL_DOWNLOAD" )
goSub hclDownload_OnReadyStateChanged
end case
return
///////////////////////////////////////////////////////////////////////////////
// onTimeout subroutine
//
// TIMEOUT event dispatch handler
//
// ----------------------------------------------------------------------------
// [i] param1 : StatusID, identifies the handle that timed out (connect, open,
// : request)
// ----------------------------------------------------------------------------
onTimeout:
statusID = param1
begin case
case ( atCtrl == "HCL_DOWNLOAD" )
goSub hclDownload_OnTimeout
end case
return
///////////////////////////////////////////////////////////////////////////////
#region HCL_DOWNLOAD
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// hclDownload_OnProgress subroutine
//
// PROGRESS event handler for the HCL_DOWNLOAD control
//
// * Update the progress bar
// * Update the Estimated Time Left (ETL)
// * Update the Transfer Rate
//
// ----------------------------------------------------------------------------
// [i] : bytesReceived. Number of bytes received between this PROGRESS event
// : and the previous one
// [i] : bytesDownloaded. Total Number of bytes downloaded so far
// [i] : bytesExpected. Total number of bytes expected from the server
// ----------------------------------------------------------------------------
hclDownload_OnProgress:
timeData = @@window->$@_TIMEDATA
startTime = timeData<1>
prevTime = timeData<2>
prevRate = timeData<3>
now = msWin_GetTickCount64()
if ( now > prevTime ) else
now = prevTime + 1
end
elapsedTime = now - startTime
transferRate = int( ( bytesDownloaded / elapsedTime ) * 1000 ) ; // in secs
etlText = ""
trText = ""
if ( bytesExpected ) then
// If we know how much we're expected to deal with we can
// calculate how much time is left and ho far we are
// through
if ( .prb_download->marquee ) then
.prb_download->marquee = 0 ; // ms
.prb_download->showText = TRUE$
end
.prb_download->value = int( ( bytesDownloaded / bytesExpected ) * 100 )
etlSecs = ( bytesExpected - bytesDownloaded ) / transferRate ; // seconds to complete
etlHours = 0
etlMins = 0
if ( etlSecs > 3600 ) then
etlHours = int( etlSecs / 3600 )
etlSecs = mod( etlSecs , 3600 )
end
if ( etlSecs > 60 ) then
etlMins = int( etlSecs / 60 )
etlSecs = mod( etlSecs , 60 )
end
etlSecs = int( etlSecs )
if ( etlHours ) then
etlText := etlHours : " hours "
end
if ( etlMins ) then
etlText := etlMins : " minutes "
end
if ( etlSecs ) then
etlText := etlSecs : " seconds "
end
cb = bytesDownloaded
goSub hclDownload_OnProgress_bytesToText
etlText := " (" : cb : " " : sf : " of "
cb = bytesExpected
goSub hclDownload_OnProgress_bytesToText
etlText := cb : " " : sf : " downloaded)"
end else
// We can't calculate the ETL or the progress done because we don't
// how much we've got left to down load
// Ensure we set the progress bar to a marquee
if ( .prb_download->marquee ) else
.prb_download->showText = FALSE$
.prb_download->marquee = 20 ; // ms
end
// We can however show the amount copied....
cb = bytesDownloaded
goSub hclDownload_OnProgress_bytesToText
etlText = cb : " " : sf : " downloaded"
end
cb = transferRate
goSub hclDownload_OnProgress_bytesToText
begin case
case ( transferRate > 0x100000 )
// We're working in MB
sf = "Mb/s"
case ( transferRate > 0x400 )
// We're working in KB
sf = "Kb/s"
case OTHERWISE$
sf = "b/s"
end case
trText = cb : " " : sf
.txt_ETL->text = etlText
.txt_TR->text = trText
timeData<2> = now
timeData<3> = transferRate
@@window->$@_TIMEDATA = timeData
return
///////////////////////////////////////////////////////////////////////////////
// hclDownload_OnProgress_bytesToText subroutine
//
// Simple routine to translate the number of bytes into MB, KB etc ...
//
// ----------------------------------------------------------------------------
// [i,o] cb : Number of bytes in, translated amount out
// [o] sf : Suffic to append to the translated amount - MB, KB or "Bytes"
// ----------------------------------------------------------------------------
hclDownload_OnProgress_bytesToText:
// We can however show the amount copied....
begin case
case ( cb > 0x100000 )
cb = oconv( ( cb / 0x100000 ) * 100, "MD2" )
sf = "MB"
case ( cb > 0x400 )
cb = oconv( ( cb / 0x400 ) * 100, "MD2" )
sf = "KB"
case OTHERWISE$
sf = "Bytes"
end case
return
///////////////////////////////////////////////////////////////////////////////
hclDownload_OnReadyStateChanged:
begin case
case ( newState == PS_HCL_RS_DONE$ )
// When we get this notification the client has finished downloading
// from theserver so we need to grab the content and then pass it to
// the parent's ENDDIALOG event or the specified callback proc.
goSub hclDownload_ReturnResponse
case OTHERWISE$
null
end case
return
///////////////////////////////////////////////////////////////////////////////
// hclDownload_OnTimeout subroutine
//
// TIMEOUT event handler for the HCL_DOWNLOAD control
//
// Return what we have to the caller - the status code returned should be 408
//
// ----------------------------------------------------------------------------
hclDownload_OnTimeout:
goSub hclDownload_ReturnResponse
return
///////////////////////////////////////////////////////////////////////////////
// hclDownload_ReturnResponse subroutine
//
// Call back with the reponse content and close the dialog.
//
// ----------------------------------------------------------------------------
hclDownload_ReturnResponse:
// Details we need were passed to the create event which we saved in a UDP:
createParam = @@window->$@_CREATEPARAM
parentID = createParam<HDL_UIPARAM_POS_PARENTWIN$>
bModal = createParam<HDL_UIPARAM_POS_MODAL$>
asyncID = createParam<HDL_UIPARAM_POS_ENDDIALOGASYNCID$>
// Renable the parent window if we have one...
if bLen( parentID ) then
if bModal then
@parentID->enabled = TRUE$
end
end
// Remove this dialog from screen
@@window->hide( "" )
if ( createParam<HDL_UIPARAM_POS_SYNCPROGRESS$> ) then
.prb_Download->value = 0
.prb_Download->syncTaskbar = FALSE$
end
// We send back two parameters to the callback event/proc
//
// 1) An array of response data
//
// <1> AsyncID or CallBackID
// <2> Response Status Code
// <3> Response Status Text
// <4> Content Length
// <5> Response Header Names
// <6> Bytes received for the response content
//
// 2) The response content (unless this was a file download)
rspInfo = ""
tmp = .hcl_Download->responseStatus
rspInfo<HDL_RSPINFO_POS_STATUSCODE$> = tmp<PS_HCL_RSPSTAT_POS_CODE$>
rspInfo<HDL_RSPINFO_POS_STATUSTEXT$> = tmp<PS_HCL_RSPSTAT_POS_TEXT$>
rspInfo<HDL_RSPINFO_POS_CONTENTLEN$> = tmp<PS_HCL_RSPSTAT_POS_CNTLEN$>
rspInfo<HDL_RSPINFO_POS_HEADERS$> = rti_Convert( .hcl_Download->responseHeaders, @fm, @vm )
responseFile = .hcl_Download->responseFile
if bLen( responseFile ) then
rspInfo<HDL_RSPINFO_POS_BYTESRECEIVED$> = dir( responseFile )<1>
rspContent = ""
end else
rspContent = .hcl_Download->GetResponseContent( "" )
rspInfo<HDL_RSPINFO_POS_BYTESRECEIVED$> = bLen( rspContent )
end
// If ww're here because of an Abort() call then we don't bother closing...
if ( @@window->$@_ABORT ) else
call post_Event( @window, "CLOSE" )
end
// Now decide where to send the data
if bLen( asyncID ) then
// Send to the parent's ENDDIALOG
if ( @parentID->handle ) then
rspInfo<HDL_RSPINFO_POS_ID$> = asyncID
call send_Event( parentID, "ENDDIALOG", atWindow, rspContent, rspInfo )
end
end else
// Send to the callback proc
procID = createParam<HDL_UIPARAM_POS_CALLBACKPROC$>
if bLen( procID ) then
rspInfo<HDL_RSPINFO_POS_ID$> = createParam<HDL_UIPARAM_POS_CALLBACKID$>
call @procID( rspInfo, rspContent )
end
end
return
///////////////////////////////////////////////////////////////////////////////
#endregion HCL_DOWNLOAD
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
$insert copyright
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////