Hi everyone
We're hitting an interesting "Unable to allocate memory for result from BASE64-ENCODE function (12118)" error when doing the following operation:
METHOD PUBLIC LOGICAL storeDocument
(INPUT ipcDocumentFilename AS CHARACTER)
DEFINE VARIABLE mDocument AS MEMPTR NO-UNDO.
DEFINE VARIABLE cDocument AS LONGCHAR NO-UNDO.
FILE-INFO:FILENAME = ipcDocumentFileName.
SET-SIZE(mDocument) = FILE-INFO:FILE-SIZE.
COPY-LOB FROM FILE ipcDocumentFilename TO mDocument NO-CONVERT.
ASSIGN cDocument = BASE64-ENCODE(mDocument).
.... store cDocument somewhere on a repository ...
FINALLY:
SET-SIZE(mDocument) = 0.
END FINALLY.
END METHOD.
This method normally works without any issue. But we had an interesting case where the input file was almost 600MB and in this case it's failing on the BASE64-ENCODE function with the error as above. We've reproduced this on Unix 64-bit and Windows 32-bit (OE11.3). In both instances there were plenty of memory available, below is for the Unix box:
free -m
total used free shared buffers cached
Mem: 48297 48197 100 0 13 18584
-/+ buffers/cache: 29600 18697
Swap: 16386 16386 0
Any ideas how to get past this?
Well, you're trying to address about approx 1,4GB in one method. That's quite a lot. I always say: when you want to eat an elephant slice it in little pieces. The problem is, I wouldn't know a way to partially read your 600MB file. Otherwise:
define variable m1 as memptr no-undo.
define variable m2 as memptr no-undo.
define variable m3 as memptr no-undo.
set-size(m1) = 3.
put-byte(m1, 1) = 30.
put-byte(m1, 2) = 31.
put-byte(m1, 3) = 32.
set-size(m2) = 3.
put-byte(m2, 1) = 40.
put-byte(m2, 2) = 41.
put-byte(m2, 3) = 42.
set-size(m3) = 6.
put-byte(m3, 1) = 30.
put-byte(m3, 2) = 31.
put-byte(m3, 3) = 32.
put-byte(m3, 4) = 40.
put-byte(m3, 5) = 41.
put-byte(m3, 6) = 42.
message
base64-encode(m1) + base64-encode(m2) = base64-encode(m3) // = true
.
PS always encode x*3 bytes at a time.
This has to be food for TechSupport.
Please open a case with Tech Support for this and provide a way to reproduce the behavior.
Well, you're trying to address about approx 1,4GB in one method. That's quite a lot. I always say: when you want to eat an elephant slice it in little pieces. The problem is, I wouldn't know a way to partially read your 600MB file. Otherwise:
define variable m1 as memptr no-undo.
define variable m2 as memptr no-undo.
define variable m3 as memptr no-undo.
set-size(m1) = 3.
put-byte(m1, 1) = 30.
put-byte(m1, 2) = 31.
put-byte(m1, 3) = 32.
set-size(m2) = 3.
put-byte(m2, 1) = 40.
put-byte(m2, 2) = 41.
put-byte(m2, 3) = 42.
set-size(m3) = 6.
put-byte(m3, 1) = 30.
put-byte(m3, 2) = 31.
put-byte(m3, 3) = 32.
put-byte(m3, 4) = 40.
put-byte(m3, 5) = 41.
put-byte(m3, 6) = 42.
message
base64-encode(m1) + base64-encode(m2) = base64-encode(m3) // = true
.
PS always encode x*3 bytes at a time.
Thanks Bronco, gonna try this and hope for the best.
if you are running 32-bit executables then no wonder it fails.
You need to allocate 600 MB of memory in one contiguous chunk to read in the data and then another 900 MB contiguous chunk to hold the base 64 encoded version.