-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathUTILITIES_STRING.st
430 lines (341 loc) · 9.08 KB
/
UTILITIES_STRING.st
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
UNIT UTILITIES_STRING;
// This unit 'UTILITIES_STRING' contains some common string functions and types which are missing in standard library.
// Please check Git repository for updates from time to time.
INTERFACE
FUNCTION CONCAT3;
FUNCTION CONCAT4;
FUNCTION CONCAT5;
FUNCTION CONCAT6;
FUNCTION CONCAT7;
FUNCTION CONCAT8;
FUNCTION CONCAT9;
FUNCTION STRING_STARTSWITH;
FUNCTION STRING_ENDSWITH;
FUNCTION COMPARE_STRINGS;
FUNCTION PAD_STRING_LEFT;
FUNCTION PAD_STRING_RIGHT;
FUNCTION ENCODE_STRING;
FUNCTION DECODE_STRING;
FUNCTION USINT_TO_STRING;
FUNCTION SINT_TO_STRING;
FUNCTION UINT_TO_STRING;
FUNCTION INT_TO_STRING;
FUNCTION STRING_TO_USINT;
FUNCTION STRING_TO_SINT;
FUNCTION STRING_TO_UINT;
FUNCTION STRING_TO_INT;
TYPE
STRING_ENCODING : (
ASCII, // 7-Bit US-ASCII (American Standard Code FOR Information Interchange)
ISO8859_1 // 8-Bit ISO 8859-1 (Latin-1; Western-Europe)
);
END_TYPE
END_INTERFACE
IMPLEMENTATION
FUNCTION CONCAT3 : STRING[254]
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
in3 : STRING[254];
END_VAR
CONCAT3 := CONCAT(CONCAT(in1, in2), in3);
END_FUNCTION
FUNCTION CONCAT4 : STRING[254]
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
in3 : STRING[254];
in4 : STRING[254];
END_VAR
CONCAT4 := CONCAT(CONCAT(CONCAT(in1, in2), in3), in4);
END_FUNCTION
FUNCTION CONCAT5 : STRING[254]
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
in3 : STRING[254];
in4 : STRING[254];
in5 : STRING[254];
END_VAR
CONCAT5 := CONCAT(CONCAT(CONCAT(CONCAT(in1, in2), in3), in4), in5);
END_FUNCTION
FUNCTION CONCAT6 : STRING[254]
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
in3 : STRING[254];
in4 : STRING[254];
in5 : STRING[254];
in6 : STRING[254];
END_VAR
CONCAT6 := CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(in1, in2), in3), in4), in5), in6);
END_FUNCTION
FUNCTION CONCAT7 : STRING[254]
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
in3 : STRING[254];
in4 : STRING[254];
in5 : STRING[254];
in6 : STRING[254];
in7 : STRING[254];
END_VAR
CONCAT7 := CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(in1, in2), in3), in4), in5), in6), in7);
END_FUNCTION
FUNCTION CONCAT8 : STRING[254]
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
in3 : STRING[254];
in4 : STRING[254];
in5 : STRING[254];
in6 : STRING[254];
in7 : STRING[254];
in8 : STRING[254];
END_VAR
CONCAT8 := CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(in1, in2), in3), in4), in5), in6), in7), in8);
END_FUNCTION
FUNCTION CONCAT9 : STRING[254]
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
in3 : STRING[254];
in4 : STRING[254];
in5 : STRING[254];
in6 : STRING[254];
in7 : STRING[254];
in8 : STRING[254];
in9 : STRING[254];
END_VAR
CONCAT9 := CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(CONCAT(in1, in2), in3), in4), in5), in6), in7), in8), in9);
END_FUNCTION
// Returns TRUE if given string in first parameter starts with given string in second parameter.
// This function is case-sensitive.
FUNCTION STRING_STARTSWITH : BOOL
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
END_VAR
VAR_TEMP
in1_len : INT;
in2_len : INT;
END_VAR
in1_len := LEN(in1);
in2_len := LEN(in2);
IF in1_len < in2_len THEN
STRING_STARTSWITH := FALSE;
ELSE
STRING_STARTSWITH := LEFT(in1, in2_len) = in2;
END_IF;
END_FUNCTION
// Returns TRUE if given string in first parameter ends with given string in second parameter.
// This function is case-sensitive.
FUNCTION STRING_ENDSWITH : BOOL
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
END_VAR
VAR_TEMP
in1_len : INT;
in2_len : INT;
END_VAR
in1_len := LEN(in1);
in2_len := LEN(in2);
IF in1_len < in2_len THEN
STRING_ENDSWITH := FALSE;
ELSE
STRING_ENDSWITH := RIGHT(in1, in2_len) = in2;
END_IF;
END_FUNCTION
// Compares two strings lexicographically (based on the ISO 8859-1 / Latin 1 representation).
// Returns 0 if the both strings are equal, a negative value if string 1 is less than the string 2 or a positive value if string 1 is greater than string 2.
// This function is case-sensitive.
FUNCTION COMPARE_STRINGS : INT
VAR_INPUT
in1 : STRING[254];
in2 : STRING[254];
END_VAR
VAR_TEMP
in1_len : INT;
in2_len : INT;
i : DINT;
i_end : INT;
END_VAR
in1_len := LEN(in1);
in2_len := LEN(in2);
i_end := MIN(in1_len, in2_len);
FOR i := 0 TO i_end DO
IF in1[i] <> in2[i] THEN
COMPARE_STRINGS := BYTE_TO_INT(in1[i]) - BYTE_TO_INT(in2[i]);
RETURN;
END_IF;
END_FOR;
COMPARE_STRINGS := in1_len - in2_len;
END_FUNCTION
// Pads given string to specified length with given padding (from the left).
// If original string's length is already equal or greater than required length, it will be returned unchanged.
FUNCTION PAD_STRING_LEFT : STRING[254]
VAR_INPUT
in : STRING[254];
length_req : USINT;
padding : STRING;
END_VAR
VAR_TEMP
in_len : INT;
out : STRING[254];
out_len : INT;
END_VAR
in_len := LEN(in);
IF in_len >= length_req THEN
PAD_STRING_LEFT := in;
RETURN;
END_IF;
out := in;
out_len := LEN(out);
WHILE out_len < length_req DO
out := CONCAT(padding, out);
out_len := LEN(out);
END_WHILE;
IF out_len > length_req THEN
out := RIGHT(out, length_req);
END_IF;
PAD_STRING_LEFT := out;
END_FUNCTION
// Pads given string to specified length with given padding (from the right).
// If original string's length is already equal or greater than required length, it will be returned unchanged.
FUNCTION PAD_STRING_RIGHT : STRING[254]
VAR_INPUT
in : STRING[254];
length_req : USINT;
padding : STRING;
END_VAR
VAR_TEMP
in_len : INT;
out : STRING[254];
out_len : INT;
END_VAR
in_len := LEN(in);
IF in_len >= length_req THEN
PAD_STRING_RIGHT := in;
RETURN;
END_IF;
out := in;
out_len := LEN(out);
WHILE out_len < length_req DO
out := CONCAT(out, padding);
out_len := LEN(out);
END_WHILE;
IF out_len > length_req THEN
out := LEFT(out, length_req);
END_IF;
PAD_STRING_RIGHT := out;
END_FUNCTION
// Encodes given string into given BYTE array using given encoding.
// If target array is too small, given string will be cut. If target array is too large, remaining bytes will be set to NULL (0).
FUNCTION ENCODE_STRING : VOID
VAR_INPUT
in : STRING[254];
encoding : STRING_ENCODING;
END_VAR
VAR_IN_OUT
out : ARRAY[..] OF BYTE;
END_VAR
VAR_TEMP
in_len : INT;
out_len : DINT;
out_start : DINT;
out_end : DINT;
i : DINT;
END_VAR
in_len := LEN(in);
out_start := _firstIndexOf(out);
out_end := _lastIndexOf(out);
out_len := out_end - out_start + 1;
FOR i := 1 TO out_len DO
IF i > in_len THEN
out[out_start + i - 1] := 0; // NULL
ELSIF encoding = ASCII AND in[i] > 127 THEN
out[out_start + i - 1] := 63; // Questionmark '?'
ELSE
out[out_start + i - 1] := in[i];
END_IF;
END_FOR;
END_FUNCTION
// Decodes given BYTE array to a string using given encoding. Decoding stops on first NULL (0; if present).
// If source array is bigger than 254 bytes, returned string will be cut to string's max. length of 254.
FUNCTION DECODE_STRING : STRING[254]
VAR_INPUT
in : ARRAY[..] OF BYTE;
encoding : STRING_ENCODING;
END_VAR
VAR_TEMP
out : STRING[254];
in_start : DINT;
in_end : DINT;
i_in : DINT;
i_out : DINT;
END_VAR
in_start := _firstIndexOf(in);
in_end := _lastIndexOf(in);
FOR i_in := in_start TO in_end DO
i_out := i_in - in_start + 1;
IF in[i_in] = 0 OR i_out > 254 THEN
DECODE_STRING := LEFT(out, DINT_TO_INT(i_out -1));
RETURN;
ELSIF encoding = ASCII AND in[i_in] > 127 THEN
out[i_out] := 63; // Questionmark '?'
ELSE
out[i_out] := in[i_in];
END_IF;
END_FOR;
DECODE_STRING := LEFT(out, DINT_TO_INT(i_out));
END_FUNCTION
FUNCTION USINT_TO_STRING : STRING[3]
VAR_INPUT
in : USINT;
END_VAR
USINT_TO_STRING := UDINT_TO_STRING(USINT_TO_UDINT(in));
END_FUNCTION
FUNCTION SINT_TO_STRING : STRING[4]
VAR_INPUT
in : SINT;
END_VAR
SINT_TO_STRING := DINT_TO_STRING(SINT_TO_DINT(in));
END_FUNCTION
FUNCTION UINT_TO_STRING : STRING[5]
VAR_INPUT
in : UINT;
END_VAR
UINT_TO_STRING := UDINT_TO_STRING(UINT_TO_UDINT(in));
END_FUNCTION
FUNCTION INT_TO_STRING : STRING[6]
VAR_INPUT
in : INT;
END_VAR
INT_TO_STRING := DINT_TO_STRING(INT_TO_DINT(in));
END_FUNCTION
FUNCTION STRING_TO_USINT : USINT
VAR_INPUT
in : STRING[3];
END_VAR
STRING_TO_USINT := UDINT_TO_USINT(STRING_TO_UDINT(in));
END_FUNCTION
FUNCTION STRING_TO_SINT : SINT
VAR_INPUT
in : STRING[4];
END_VAR
STRING_TO_SINT := DINT_TO_SINT(STRING_TO_DINT(in));
END_FUNCTION
FUNCTION STRING_TO_UINT : UINT
VAR_INPUT
in : STRING[5];
END_VAR
STRING_TO_UINT := UDINT_TO_UINT(STRING_TO_UDINT(in));
END_FUNCTION
FUNCTION STRING_TO_INT : INT
VAR_INPUT
in : STRING[6];
END_VAR
STRING_TO_INT := DINT_TO_INT(STRING_TO_DINT(in));
END_FUNCTION
END_IMPLEMENTATION