RightOfUtf16String
Short summary
This function edits a utf-16 string, so only the count of size rightmost characters of the string remain.
If size is greater than the length of string, the string is unchanged.
It returns the new size of the string in words
Attention: All strings are handled as null-terminated byte streams
Example:
myString :WString(10) := "Test";
lengthOfMyString :UDINT := 4;
------------------
RightOfUtf16String(
stringAdress := ADR(myString),
length := 3,
newStringLength => lengthOfMyString
); // myString will be "est" with length 3
- Return type:
UDINT
Parameters
| Name | Type | Comment | Kind |
|---|---|---|---|
| stringAddress | POINTER TO WORD | pointer to the utf-16 string | input |
| length | UDINT | count of characters in in new substring | input |
| normalizeString | BOOL | normalize the string before creating subtring | input |
| newStringLength | UDINT | new length of the string in bytes | output |
Code
Declaration
FUNCTION RightOfUtf16String :UDINT
VAR_INPUT
(* pointer to the utf-16 string *)
stringAddress :POINTER TO WORD;
(* count of characters in in new substring *)
length :UDINT;
(* normalize the string before creating subtring *)
normalizeString :BOOL := TRUE;
END_VAR
VAR_OUTPUT
(* new length of the string in bytes *)
newStringLength :UDINT;
END_VAR
VAR
(* word count of string *)
wordsOfString :UDINT;
(* codepoints of string *)
codepoints :POINTER TO UnicodeCodePoint;
(* codepoints of string after normalization*)
normalizedCodepoints :POINTER TO UnicodeCodePoint;
(* codepoint count of string *)
codepointCountOfString :UDINT;
(* codepoint count of normalized string *)
normalizedCodepointCountOfString :UDINT;
n :UDINT;
END_VAR
VAR CONSTANT
NULL :USINT := 0;
END_VAR
Implementation
RETURN(stringAddress = 0);
wordsOfString := GetUtf16StringLength(stringAddress);
// if string is empty or length is 0: substring is empty string
IF wordsOfString = 0 OR length = 0 THEN
Tc2_System.MEMSET(
destAddr := stringAddress,
fillByte := NULL,
n := SIZEOF(WORD)
);
RightOfUtf16String := 0;
newStringLength := 0;
RETURN;
END_IF
codepoints := __NEW(UnicodeCodePoint, (wordsOfString + 1));
IF (codepoints = 0) THEN
RETURN;
END_IF
GetCodepointsFromUtf16String(
utf16StringAddress := stringAddress,
utf16StringWordCount := wordsOfString,
codePointBuffer := codepoints,
bufferSize := (wordsOfString + 1) * SIZEOF(UnicodeCodepoint),
codePointCount => codepointCountOfString
);
IF (normalizeString) THEN
normalizedCodepoints := __NEW(UnicodeCodePoint, (wordsOfString*4));
IF (normalizedCodepoints = 0) THEN
__DELETE(codepoints);
RETURN;
END_IF
NormalizeCodepointsFormC(
codePoints := codepoints,
codePointsCount := codepointCountOfString,
normalizedCodepoints := normalizedCodepoints,
bufferSize := (wordsOfString*4) * SIZEOF(UnicodeCodePoint),
normalizedCodepointsCount => normalizedCodepointCountOfString
);
__DELETE(codepoints);
codepoints := normalizedCodepoints;
codepointCountOfString := normalizedCodepointCountOfString;
END_IF
IF (length > codepointCountOfString) THEN
newStringLength := wordsOfString;
RightOfUtf16String := newStringLength;
__DELETE(codepoints);
RETURN;
END_IF
n := length * SIZEOF(UnicodeCodePoint);
IF Tc2_System.MEMMOVE(
destAddr := codepoints,
srcAddr := codepoints + (codepointCountOfString - length) * SIZEOF(UnicodeCodePoint),
n := n
) <> n
THEN
__DELETE(codepoints);
RETURN;
END_IF
GetUtf16StringFromCodepoints(
addressOfCodePoints := codepoints,
codePointCount := length,
stringBuffer := stringAddress,
bufferSize := (wordsOfString + 1) * SIZEOF(WORD),
utf16StringWordCount => newStringLength
);
RightOfUtf16String := newStringLength;
__DELETE(codepoints);