source: trunk/NewView/StringUtilsUnit.pas@ 102

Last change on this file since 102 was 102, checked in by RBRi, 18 years ago

improved StringUtilsUnit

  • Property svn:eol-style set to native
File size: 13.6 KB
RevLine 
[35]1Unit StringUtilsUnit;
2
3// NewView - a new OS/2 Help Viewer
[75]4// Copyright 2006-2007 Ronald Brill (rbri at rbri dot de)
5// This software is released under the GNU Public License - see readme.txt
[35]6
7// Helper functions to work with strings
8
9Interface
10
11uses
12 Classes;
13
[43]14const
15 StrCR = chr(13);
16 StrLF = chr(10);
17 StrCRLF = StrCR + StrLF;
[102]18 Quote = '''';
19 DoubleQuote = '"';
[43]20
21
22 TYPE
[35]23 TSerializableStringList = class
24 private
25 stringList : TStringList;
26
27 public
28 CONSTRUCTOR Create;
29 DESTRUCTOR Destroy; override;
30 FUNCTION getCount : LongInt;
31 PROCEDURE add(const aString : String);
32 FUNCTION get(const anIndex : LongInt) : String;
33 FUNCTION getSerializedString : String;
34 PROCEDURE readValuesFromSerializedString(const aSerializedString : String);
35 end;
36
[43]37 TYPE
38 TSetOfChars = set of char;
39
[35]40 // prefices all occurences of one of the chars in aStringWithChars with anEscape char
41 // if the escapeChar itself is found, then it is doubled
[43]42 Function StrEscapeAllCharsBy(Const aReceiver: String; const aSetOfChars: TSetOfChars; const anEscapeChar: char): String;
[35]43
[43]44 // Extract all fields in a String given a set of delimiter characters and
45 // an optional escape character usable to escape field delimits.
46 // Example:
[102]47 // StrExtractStrings('1x2x3\x4', 'x', '\') ->
48 // returns 4 strings: '1', '', '2' and '3x4'
[82]49 Procedure StrExtractStrings(Var aResult : TStrings; Const aReceiver: String; const aSetOfChars: TSetOfChars; const anEscapeChar: char);
[43]50
[82]51 // same as StrExtractStrings but ignores empty strings
52 Procedure StrExtractStringsIgnoreEmpty(Var aResult : TStrings; Const aReceiver: String; const aSetOfChars: TSetOfChars; const anEscapeChar: char);
53
[43]54 // removes all occurences of char from aSetOfChars from the beginning
[82]55 // of a String.
56 Function StrTrimLeftChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
57
58 // removes all occurences of char from aSetOfChars from the end
59 // of a String.
60 Function StrTrimRightChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
61
62 // removes all occurences of char from aSetOfChars from the beginning
[43]63 // end the end of a String.
64 Function StrTrimChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
65
66 // removes all blanks from beginning and end
67 Function StrTrim(const aReceiver: String): String;
68
[82]69 // Returns the aCount leftmost chars of aString
70 Function StrLeft(const aString : String; const aCount : Integer) : String;
71
[102]72 // Returns a copy of the string without aCount chars from right
73 Function StrLeftWithout(const aString : String; const aCount : Integer) : String;
74
75 // Returns a copy of the string including all characters until one from aSetOfChars found
76 Function StrLeftUntil(const aReceiver: String; const aSetOfChars: TSetOfChars) : String;
77
78 // returns true if the String starts with the provides one
79 // this is case SENSITIVE
80 Function StrStartsWith(const aReceiver: String; const aStartString: String): Boolean;
81
82 // returns true if the String starts with the provides one
83 // this is case INsensitive
84 Function StrStartsWithIgnoringCase(const aReceiver: String; const aStartString: String): Boolean;
85
[43]86 // returns true if the String ends with the provides one
87 // this is case SENSITIVE
88 Function StrEndsWith(const aReceiver: String; const anEndString: String): Boolean;
89
90 // returns true if the String ends with the provides one
91 // this is case INsensitive
[102]92 Function StrEndsWithIgnoringCase(const aReceiver: String; const anEndString: String): Boolean;
[43]93
[68]94 // the IntToStr generates wrong results
95 // in normal cases IntToStr returns a negative value
96 // and somtimes completly wrong values
97 Function LongWordToStr(const aLongWord: LongWord) : String;
98
[65]99 Function BoolToStr(const aBoolean : boolean ): string;
[43]100
[102]101 // Returns aString enclosed in double quotes
102 Function StrInDoubleQuotes(const aString : String) : String;
[65]103
[102]104
[35]105Implementation
106
[65]107 uses
108 DebugUnit;
109
[35]110 constructor TSerializableStringList.Create;
111 begin
[65]112 LogEvent(LogObjConstDest, 'TSerializableStringList createdestroy');
113
[35]114 inherited Create;
115 stringList := TStringList.Create;
116 end;
117
118
119 destructor TSerializableStringList.Destroy;
120 begin
[65]121 LogEvent(LogObjConstDest, 'TSerializableStringList destroy');
122 if Nil <> stringList then stringList.Destroy;
123
[35]124 inherited Destroy;
125 end;
126
127
128 FUNCTION TSerializableStringList.getCount : LongInt;
129 begin
130 result := stringList.count;
131 end;
132
133
134 PROCEDURE TSerializableStringList.add(const aString : String);
135 begin
136 stringList.add(aString);
137 end;
138
139 FUNCTION TSerializableStringList.get(const anIndex : LongInt) : String;
140 begin
141 result := stringList[anIndex];
142 end;
143
144 FUNCTION TSerializableStringList.getSerializedString : String;
145 Var
146 i : Integer;
147 begin
148 result := '';
[82]149 for i := 0 to stringList.count-1 do
[35]150 begin
151 if (i > 0) then result := result + '&';
[43]152 result := result + StrEscapeAllCharsBy(stringList[i], ['&'], '\');
[35]153 end;
154 end;
155
156
157 PROCEDURE TSerializableStringList.readValuesFromSerializedString(const aSerializedString : String);
[43]158 Begin
159 if (length(aSerializedString) < 1) then exit;
160
[65]161 LogEvent(LogObjConstDest, 'readValuesFromSerializedString');
162 stringList.Destroy;
163 LogEvent(LogObjConstDest, 'readValuesFromSerializedString destroy done');
[43]164 stringList := TStringList.Create;
165 StrExtractStrings(stringList, aSerializedString, ['&'], '\');
166 end;
167
168
169 // ----------------------------------------------------------
170
171
172 Function StrEscapeAllCharsBy(Const aReceiver: String; const aSetOfChars: TSetOfChars; const anEscapeChar: char): String;
[35]173 Var
174 i : Integer;
[43]175 tmpChar : Char;
176 Begin
177 Result := '';
178
179 for i := 1 To length(aReceiver) do
180 begin
181 tmpChar := aReceiver[i];
182
183 if (tmpChar = anEscapeChar) or (tmpChar IN aSetOfChars) then
184 result := result + anEscapeChar + tmpChar
185 else
186 result := result + tmpChar;
187 end;
188 end;
189
190
[82]191 Procedure PrivateStrExtractStrings( Var aResult: TStrings;
192 const aReceiver: String;
193 const aSetOfChars: TSetOfChars;
194 const anEscapeChar: char;
195 const anIgnoreEmptyFlag : boolean);
[43]196 Var
197 i : Integer;
[35]198 tmpChar,tmpNextChar : Char;
199 tmpPart: String;
[43]200 Begin
201 if (length(aReceiver) < 1) then exit;
[35]202
203 tmpPart := '';
204
205 i := 1;
[43]206 while i <= length(aReceiver) do
[35]207 begin
[43]208 tmpChar := aReceiver[i];
209 if i < length(aReceiver) then
210 tmpNextChar := aReceiver[i+1]
[35]211 else
212 tmpNextChar := #0;
213
[43]214 if (tmpChar = anEscapeChar) and (tmpNextChar = anEscapeChar) then
[35]215 begin
[43]216 tmpPart := tmpPart + anEscapeChar;
[35]217 i := i + 2;
218 end
219 else
[43]220 if (tmpChar = anEscapeChar) and (tmpNextChar IN aSetOfChars) then
[35]221 begin
[43]222 tmpPart := tmpPart + tmpNextChar;
[35]223 i := i + 2;
224 end
225 else
[43]226 if (tmpChar IN aSetOfChars) then
[35]227 begin
[82]228 if (NOT anIgnoreEmptyFlag) OR ('' <> tmpPart) then
229 begin
230 aResult.add(tmpPart);
231 end;
[35]232 tmpPart := '';
233 i := i + 1;
234 end
235 else
236 begin
237 tmpPart := tmpPart + tmpChar;
238 i := i + 1;
239 end;
240 end;
[82]241
242 if (NOT anIgnoreEmptyFlag) OR ('' <> tmpPart) then
243 begin
244 aResult.add(tmpPart);
245 end;
[35]246 end;
247
248
[82]249 Procedure StrExtractStrings(Var aResult: TStrings; Const aReceiver: String; const aSetOfChars: TSetOfChars; const anEscapeChar: char);
250 Begin
251 PrivateStrExtractStrings(aResult, aReceiver, aSetOfChars, anEscapeChar, false);
252 end;
253
254
255 Procedure StrExtractStringsIgnoreEmpty(Var aResult: TStrings; Const aReceiver: String; const aSetOfChars: TSetOfChars; const anEscapeChar: char);
256 Begin
257 PrivateStrExtractStrings(aResult, aReceiver, aSetOfChars, anEscapeChar, true);
258 end;
259
260
261 Function StrTrimLeftChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
262 Var
263 i : Longint;
264 Begin
265 i := 1;
266 // mem optimization
267 if aReceiver[i] in aSetOfChars then
268 begin
269 while i <= Length(aReceiver) do
270 begin
271 if aReceiver[i] in aSetOfChars then
272 inc(i)
273 else
274 break;
275 end;
276 result := Copy(aReceiver, i, Length(aReceiver)-i+1);
277 end
278 else
279 begin
280 result := aReceiver;
281 end;
282 end;
283
284
285 Function StrTrimRightChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
286 Var
287 i : Longint;
288 Begin
289 i := Length(aReceiver);
290
291 // mem optimization
292 if aReceiver[i] in aSetOfChars then
293 begin
294 while i > 0 do
295 begin
296 if aReceiver[i] in aSetOfChars then
297 dec(i)
298 else
299 break;
300 end;
301 result := Copy(aReceiver, 1, i);
302 end
303 else
304 begin
305 result := aReceiver;
306 end;
307 end;
308
309
[43]310 Function StrTrimChars(const aReceiver: String; const aSetOfChars: TSetOfChars): String;
[35]311 Var
[43]312 i : Longint;
313 j : Longint;
[82]314 tmpNeedCopy : boolean;
[35]315 Begin
[82]316 tmpNeedCopy := false;
[43]317 i := 1;
318 while i < Length(aReceiver) do
319 begin
320 if aReceiver[i] in aSetOfChars then
[82]321 begin
322 inc(i);
323 tmpNeedCopy := true;
324 end
325 else
326 begin
327 break;
328 end;
[43]329 end;
[35]330
[43]331 j := Length(aReceiver);
332 while j >= i do
[35]333 begin
[43]334 if aReceiver[j] in aSetOfChars then
[82]335 begin
336 dec(j);
337 tmpNeedCopy := true;
338 end
[43]339 else
[82]340 begin
[43]341 break;
[82]342 end;
[43]343 end;
344
[82]345 if tmpNeedCopy then
346 begin
347 result := Copy(aReceiver, i, j-i+1);
348 end
349 else
350 begin
351 result := aReceiver;
352 end;
[43]353 end;
354
355
356 Function StrTrim(const aReceiver: String): String;
357 Begin
358 result := StrTrimChars(aReceiver, [' ']);
359 end;
360
361
[82]362 Function StrLeft(const aString : String; const aCount : Integer) : String;
363 Begin
364 if aCount >= Length(aString) then
365 Result := aString
366 else
367 Result := copy(aString, 1, aCount);
368 end;
369
370
[102]371 Function StrLeftWithout(const aString : String; const aCount : Integer) : String;
372 Begin
373 Result:= copy(aString, 1, length(aString) - aCount );
374 End;
375
376
377 Function StrLeftUntil(const aReceiver: String; const aSetOfChars: TSetOfChars) : String;
378 Var
379 i : integer;
380 Begin
381 Result := aReceiver;
382
383 for i := 1 To Length(aReceiver) do
384 begin
385 if aReceiver[i] in aSetOfChars then
386 begin
387 Result := Copy(aReceiver, 1, i-1 );
388 break;
389 end;
390 end;
391 end;
392
393
394 Function StrStartsWith(const aReceiver: String; const aStartString: String) : Boolean;
395 Var
396 tmpStringPos : integer;
397 tmpStartStringLength : integer;
398 Begin
399 tmpStartStringLength := Length(aStartString);
400
401 if Length(aReceiver) < tmpStartStringLength then
402 begin
403 result := false;
404 exit;
405 end;
406
407 for tmpStringPos := 1 to tmpStartStringLength do
408 begin
409 if aReceiver[tmpStringPos] <> aStartString[tmpStringPos] then
410 begin
411 result := false;
412 exit;
413 end;
414 end;
415
416 result := true;
417 end;
418
419
420 Function StrStartsWithIgnoringCase(const aReceiver: String; const aStartString: String) : Boolean;
421 Var
422 tmpStringPos : integer;
423 tmpStartStringLength : integer;
424 Begin
425 tmpStartStringLength := Length(aStartString);
426
427 if Length(aReceiver) < tmpStartStringLength then
428 begin
429 result := false;
430 exit;
431 end;
432
433 for tmpStringPos := 1 to tmpStartStringLength do
434 begin
435 if UpCase(aReceiver[tmpStringPos]) <> UpCase(aStartString[tmpStringPos]) then
436 begin
437 result := false;
438 exit;
439 end;
440 end;
441
442 result := true;
443 end;
444
445
[43]446 Function StrEndsWith(const aReceiver: String; const anEndString: String): Boolean;
447 Var
448 tmpStringPos : Longint;
449 tmpMatchPos : Longint;
450 Begin
451 tmpStringPos := length(aReceiver);
452 tmpMatchPos := length(anEndString);
453
454 if tmpMatchPos > tmpStringPos then
455 begin
456 result := false;
457 exit;
458 end;
459
460 while tmpMatchPos > 0 do
461 begin
462 if aReceiver[tmpStringPos] <> anEndString[tmpMatchPos] then
[35]463 begin
[43]464 result := false;
465 exit;
466 end;
467 dec(tmpMatchPos);
468 dec(tmpStringPos);
469 end;
[35]470
[43]471 result := true;
472 end;
473
474
475 Function StrEndsWithIgnoringCase(const aReceiver: String; const anEndString: String): Boolean;
476 Var
477 tmpStringPos : Longint;
478 tmpMatchPos : Longint;
479 Begin
[102]480 tmpStringPos := length(aReceiver);
[43]481 tmpMatchPos := length(anEndString);
482
483 if tmpMatchPos > tmpStringPos then
484 begin
485 result := false;
486 exit;
487 end;
488
489 while tmpMatchPos > 0 do
490 begin
[102]491 if upcase(aReceiver[tmpStringPos]) <> upcase(anEndString[tmpMatchPos]) then
[43]492 begin
493 result := false;
494 exit;
[35]495 end;
[43]496 dec(tmpMatchPos);
497 dec(tmpStringPos);
[35]498 end;
[43]499
500 result := true;
[35]501 end;
502
[102]503
[68]504 Function LongWordToStr(const aLongWord: LongWord) : String;
505 Var
506 l : LongWord;
507 i : Integer;
508 Begin
509 Result := '';
510 l := aLongWord;
511
512 if l = 0 then
513 begin
514 result := '0';
515 exit;
516 end;
517
518 while l > 0 do
519 begin
520 i := l mod 10;
521 l := l div 10;
522 Case i of
523 0 : result := '0' + result;
524 1 : result := '1' + result;
525 2 : result := '2' + result;
526 3 : result := '3' + result;
527 4 : result := '4' + result;
528 5 : result := '5' + result;
529 6 : result := '6' + result;
530 7 : result := '7' + result;
531 8 : result := '8' + result;
532 9 : result := '9' + result;
533 end;
534 end;
535
536 end;
537
538
[65]539 Function BoolToStr(const aBoolean : boolean ): string;
540 begin
541 if aBoolean then
542 Result := 'True'
543 else
544 Result := 'False';
545 end;
546
[102]547 Function StrInDoubleQuotes(const aString : String) : String;
548 begin
549 Result := DoubleQuote + aString + DoubleQuote;
550 end;
551
552
[35]553END.
Note: See TracBrowser for help on using the repository browser.