project BLF > class Mail > method FileEncode
Description
Method to encode a file to base64.
Parameters
imIn | input | memptr | Memory pointer to the original file content |
ilLineBreaks | input | logical | Indication whether line breaks should be added after each 76 characters. This is necessary for attachments in mails via SMTP sockets (put it on true). |
omOut | output | memptr | Memory pointer to the encoded file content |
oiReturnStatus | output | integer | Return status of the method. |
Internal usage
BLF
program code (program1/mail.p)
assign oiReturnStatus = -98.
/* omOut should have the right length set */
ASSIGN viLength = GET-SIZE(imIn)
viMod = viLength MODULO 3.
IF viMod <> 0 THEN ASSIGN viLength = viLength + 3 - viMod.
ASSIGN viLength = viLength * 4 / 3.
IF ilLineBreaks THEN ASSIGN viLength = viLength + INTEGER(viLength / 76).
set-size(omOut) = 0.
SET-SIZE(omOut) = viLength.
/* Base64 encoding converts three bytes of input to
four bytes of output */
DO WHILE NOT vlDone :
ASSIGN viInBuffer[1] = GET-BYTE(imIn,viCount + 1)
viInBuffer[2] = GET-BYTE(imIn,viCount + 2)
viInBuffer[3] = GET-BYTE(imIn,viCount + 3).
/*
// Calculate the outBuffer
// The first byte of our in buffer will always be valid
// but we must check to make sure the other two bytes
// are not -1 before using them.
// The basic idea is that the three bytes get split into
// four bytes along these lines:
// [AAAAAABB] [BBBBCCCCC] [CCDDDDDD]
// [xxAAAAAA] [xxBBBBBB] [xxCCCCCC] [xxDDDDDD]
// bytes are considered to be zero when absent.
// the four bytes are then mapped to common ASCII symbols
*/
/* // A's: first six bits of first byte
*/
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = asc(vcBase64Chars[ get-bits(viInBuffer[1],3,6) + 1]).
if (viInBuffer[2] <> ?)
THEN DO :
/*
// B's: last two bits of first byte, first four bits of second byte
*/
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = asc(vcBase64Chars[ get-bits(viInBuffer[1],1,2) * 16 + get-bits(viInBuffer[2],5,4) + 1]).
if (viInBuffer[3] <> ?)
THEN DO :
/*
// C's: last four bits of second byte, first two bits of third byte
*/
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = asc(vcBase64Chars[ get-bits(viInBuffer[2],1,4) * 4 + get-bits(viInBuffer[3],7,2) + 1]).
/*
// D's: last six bits of third byte
*/
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = asc(vcBase64Chars[ get-bits(viInBuffer[3],1,6) + 1]).
END.
ELSE DO :
/*
// C's: last four bits of second byte
*/
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = asc(vcBase64Chars[ get-bits(viInBuffer[2],1,4) * 4 + 1]).
/*
// an equals sign for a character that is not a Base64 character
*/
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = ASC("=":U).
ASSIGN vlDone = TRUE.
END.
END.
ELSE DO :
/*
// B's: last two bits of first byte
*/
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = asc(vcBase64Chars[ get-bits(viInBuffer[1],1,2) * 16 + 1]).
/*
// an equal signs for characters that is not a Base64 characters
*/
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = ASC("=":U).
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = ASC("=":U).
ASSIGN vlDone = TRUE.
END.
IF ilLineBreaks
THEN DO :
ASSIGN viLineCount = viLineCount + 4.
IF viLineCount >= 76
THEN DO :
ASSIGN viPos = viPos + 1.
PUT-BYTE(omOut,viPos) = 10.
ASSIGN viLineCount = 0.
END.
END.
ASSIGN viCount = viCount + 3.
IF viCount >= GET-SIZE(imIn) THEN ASSIGN vlDone = TRUE.
END.
assign oiReturnStatus = 0.