Hi,
I had reported this to Harm before, but as I got no reply... sharing this with the community.
Perhaps I'm overlooking something silly (wouldn''t be the first time)
This is on DataFlex 20.1 (latest), 32 bit.
The following code works on 64 bit and the project now also works fine under 64 bit, so one could argue that this is all hypothetical.
However I'm wondering why I'm getting a Out Of Memory error (OOM Error) when using this.
Demo Code:
Code:
Use Windows.pkg
Use Dfpanel.pkg
Use Batchdd.pkg
Use File_dlg.pkg
Object oMain is a Panel
Set Size to 100 300
Set Label to "Base64 OOM Error demo"
Use seq_chnl.pkg
Use cCharTranslate.pkg
Object oCharTranslate is a cCharTranslate
End_Object
Object oBase64 is a cObject
Function BinaryEncodeFileToUChar String sFileSource Returns UChar[]
UChar[] ucFile
UChar[] ucEncoded
Boolean bExists
Integer iChIn
If (sFileSource <> "") Begin
Get Seq_New_Channel to iChIn
If (iChIn <> DF_SEQ_CHANNEL_NOT_AVAILABLE) Begin
Direct_Input channel iChIn ("BINARY:" + sFileSource)
Read_Block channel iChIn ucFile -1
Close_Input channel iChIn
Send Seq_Release_Channel iChIn
Get Base64EncodeUCharArray of oCharTranslate ucFile to ucEncoded /// <--- crashing here
End
End
Function_Return ucEncoded
End_Function
End_Object
Object oXmlUpload_bp is a BusinessProcess
Function UploadFile String sFileName Returns Boolean
UChar[] ucEncoded
Get BinaryEncodeFileToUChar of oBase64 sFileName to ucEncoded
// more code here... for the actual chunked upload
End_Function
End_Object
Object oOpenDialog is a OpenDialog
Set Dialog_Caption to "Select a file"
Set CreatePrompt_State to False
Set FileMustExist_State to True
Set NoChangeDir_State to True
Set Filter_String to 'All Files|*.*'
End_Object
Object oFileForm is a Form
Set Label to "Select File:"
Set Location to 10 75
Set Size to 13 150
Set peAnchors to anBottomLeftRight
Set Prompt_Button_Mode to pb_PromptOn
Set Form_Button_Bitmap Item 0 to "GlobePlug.ico"
Procedure Prompt
Boolean bOk
String sFileName
Get Show_Dialog of oOpenDialog to bOk
If (bOk) Begin
Get File_Name of oOpenDialog to sFileName
Set Value to sFileName // as we do not want to save that
Set Item_Changed_State to True // in here.
End
End_Procedure
End_Object
Object oUploadButton is a Button
Set Label to "Upload file"
Set Size to 14 62
Set Location to 45 122
Set peAnchors to anBottomRight
Procedure OnClick
String sFileName
Boolean bExists
Get Value of oFileForm to sFileName
Send doUploadFile sFileName
End_Procedure
End_Object
Procedure doUploadFile String sFileName
Boolean bUploadOk
String sMsg
Send Cursor_Wait of Cursor_Control
Get UploadFile of oXmlUpload_Bp sFileName to bUploadOk
Send Cursor_Ready of Cursor_Control
If (bUploadOk) Move (sFileName*"upload to the server successfully.\n" ) to sMsg
Else Move (sFileName*"upload to the server FAILED. Please try again\n" ) to sMsg
Send Info_box sMsg "Upload status"
End_Procedure
End_Object
Start_UI
The code above comes from a heavily trimmed down webservice client to upload any kind of file to a DataFlex webservice.
One of the things I tested it with was the 230MB sized DataFlex installer.. Not because we need to upload that kind of file, but because it was available and I wanted to see the performance and/or see if my code had an obvious issue in the webservice somewhere.
So it's not exactly a small file to test with.
However.. it isn't close to a 2GB limit either.
As pointed out above it crashes on the line:
Code:
Get Base64EncodeUCharArray of oCharTranslate ucFile to ucEncoded /// <--- crashing here
If you put a breakpoint in that function itself then the crash is on the ResizeArray line below:

So this is just the code above, no webservice in sight or needed to reproduce this.
I though I remembered that arrays are passed as pass by reference when used as a parameter to a function and then via "copy on write" expanded when changed. (see discussions from Sonny https://support.dataaccess.com/Forum...n-depth-Part-V ) but I might misremember and I guess I have to reread that blog series again.
So if what I remember is true, it shouldn't -in theory- use more than 500MB in memory.
If OTOH all of the data goes onto the stack on every call then I suppose it makes more sense.. but I'm still not counting 2GB.
To be frank (Frank help?) it would make sense if the data goes on the stack.
--
Wil