BASE64 (FUN)

FUNCTION BASE64 : PT_SIZE

encodes 8 bit binary data into ASCII data

A text block (string, binary, array of bytes) will be base64 encoded. The maximum of the block is set in the TextBlockSize parameter. This size can be changed but must be divisible by 3.

If the text block is only a part of a text and followed by more text, the size must be TextBlockSize.iBlockSize and the isLastBlock variable must be set to FALSE. If a text is not followed by another block, the specific length of it must be used and isLastBlock has to be set to TRUE, as shown in the following example. The reason is three 8-bit letters will become four 6-bit letters. If only two 8-Bit letters are remaining at the end, the encoded text is filled with “=”. This must only be at the end of a text.

Example 1:

StringToConvert : PT_SIZE;
EncodedString  : PT_SIZE;
byError        : BYTE;
sText          : STRING := 'This is a test string.';

StringToConvert.uiSize := LEN(sText); (* When another block follows, use the size TextBlockSize.iBlockSize
                                      and set isLastBlock to FALSE. *)
StringToConvert.pString := ADR(sText);
EncodedString := Base64(TextToEncode := StringToConvert, isLastBlock := TRUE, pbyError := ADR(byError));

Example 2:

VAR
    abyData : ARRAY[0..63] OF BYTE; // := [ (* some binary data *) ];
    udiDataIndex : UDINT;
END_VAR
VAR CONSTANT
    c_udiWindowSize : UDINT := 24; // c_udiWindowSize MOD 3 = 0 AND c_udiWindowSize <= TextBlockSize.iBlockSize !!
    c_udiDataSize : UDINT := SIZEOF(abyData);
    c_udiBufferSize : UDINT := 4 * ((c_udiDataSize + 2) / 3);
END_VAR
VAR
    sBuffer : STRING(c_udiBufferSize);
    udiBufferIndex : UDINT;
    stData, stBuffer : PT_SIZE;
    xLastBlock : BOOL;
    byError : BYTE;
END_VAR

WHILE udiDataIndex < c_udiDataSize DO
    stData.pString := ADR(abyData[udiDataIndex]);
    IF (c_udiDataSize - udiDataIndex) > c_udiWindowSize THEN
        stData.uiSize := TO_UINT(c_udiWindowSize);
        xLastBlock := FALSE;
    ELSE
        stData.uiSize := TO_UINT(c_udiDataSize - udiDataIndex);
        xLastBlock := TRUE;
    END_IF
    stBuffer := Base64(stData, xLastBlock, ADR(byError));
    IF byError <> 0 THEN
        EXIT;
    END_IF
    SysMemCpy(ADR(sBuffer[udiBufferIndex]), stBuffer.pString, stBuffer.uiSize);
    udiBufferIndex := udiBufferIndex + stBuffer.uiSize-1; // Not counting the terminating NULL
    udiDataIndex := udiDataIndex + stData.uiSize;
END_WHILE
InOut:

Scope

Name

Type

Comment

Return

BASE64

PT_SIZE

A structure with a pointer to the text and its size (comprising the terminating character)

Input

TextToEncode

PT_SIZE

The text block which should be encoded

isLastBlock

BOOL

TRUE: The current text block is the end of a text
FALSE: The current text block is just a small text

pbyError

POINTER TO BYTE

0: No error
1: Text block is too long
2: Not divisible through 3
4: Empty string