source: cprs/branches/tmg-cprs/TntWare/Delphi Unicode Controls/Source/TntWideStrUtils.pas@ 667

Last change on this file since 667 was 453, checked in by Kevin Toppenberg, 16 years ago

Initial upload of TMG-CPRS 1.0.26.69

File size: 12.0 KB
Line 
1
2{*****************************************************************************}
3{ }
4{ Tnt Delphi Unicode Controls }
5{ http://www.tntware.com/delphicontrols/unicode/ }
6{ Version: 2.3.0 }
7{ }
8{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) }
9{ }
10{*****************************************************************************}
11
12unit TntWideStrUtils;
13
14{$INCLUDE TntCompilers.inc}
15
16interface
17
18{ Wide string manipulation functions }
19
20{$IFNDEF COMPILER_9_UP}
21function WStrAlloc(Size: Cardinal): PWideChar;
22function WStrBufSize(const Str: PWideChar): Cardinal;
23{$ENDIF}
24{$IFNDEF COMPILER_10_UP}
25function WStrMove(Dest: PWideChar; const Source: PWideChar; Count: Cardinal): PWideChar;
26{$ENDIF}
27{$IFNDEF COMPILER_9_UP}
28function WStrNew(const Str: PWideChar): PWideChar;
29procedure WStrDispose(Str: PWideChar);
30{$ENDIF}
31//---------------------------------------------------------------------------------------------
32{$IFNDEF COMPILER_9_UP}
33function WStrLen(Str: PWideChar): Cardinal;
34function WStrEnd(Str: PWideChar): PWideChar;
35{$ENDIF}
36{$IFNDEF COMPILER_10_UP}
37function WStrCat(Dest: PWideChar; const Source: PWideChar): PWideChar;
38{$ENDIF}
39{$IFNDEF COMPILER_9_UP}
40function WStrCopy(Dest, Source: PWideChar): PWideChar;
41function WStrLCopy(Dest, Source: PWideChar; MaxLen: Cardinal): PWideChar;
42function WStrPCopy(Dest: PWideChar; const Source: WideString): PWideChar;
43function WStrPLCopy(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar;
44{$ENDIF}
45{$IFNDEF COMPILER_10_UP}
46function WStrScan(const Str: PWideChar; Chr: WideChar): PWideChar;
47// WStrComp and WStrPos were introduced as broken in Delphi 2006, but fixed in Delphi 2006 Update 2
48function WStrComp(Str1, Str2: PWideChar): Integer;
49function WStrPos(Str, SubStr: PWideChar): PWideChar;
50{$ENDIF}
51function Tnt_WStrComp(Str1, Str2: PWideChar): Integer; deprecated;
52function Tnt_WStrPos(Str, SubStr: PWideChar): PWideChar; deprecated;
53
54{ ------------ introduced --------------- }
55function WStrECopy(Dest, Source: PWideChar): PWideChar;
56function WStrLComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer;
57function WStrLIComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer;
58function WStrIComp(Str1, Str2: PWideChar): Integer;
59function WStrLower(Str: PWideChar): PWideChar;
60function WStrUpper(Str: PWideChar): PWideChar;
61function WStrRScan(const Str: PWideChar; Chr: WideChar): PWideChar;
62function WStrLCat(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar;
63function WStrPas(const Str: PWideChar): WideString;
64
65{ SysUtils.pas } //-------------------------------------------------------------------------
66
67{$IFNDEF COMPILER_10_UP}
68function WideLastChar(const S: WideString): PWideChar;
69function WideQuotedStr(const S: WideString; Quote: WideChar): WideString;
70{$ENDIF}
71{$IFNDEF COMPILER_9_UP}
72function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): Widestring;
73{$ENDIF}
74{$IFNDEF COMPILER_10_UP}
75function WideDequotedStr(const S: WideString; AQuote: WideChar): WideString;
76{$ENDIF}
77
78implementation
79
80uses
81 {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} Math, Windows, TntWindows;
82
83{$IFNDEF COMPILER_9_UP}
84function WStrAlloc(Size: Cardinal): PWideChar;
85begin
86 Size := SizeOf(Cardinal) + (Size * SizeOf(WideChar));
87 GetMem(Result, Size);
88 PCardinal(Result)^ := Size;
89 Inc(PAnsiChar(Result), SizeOf(Cardinal));
90end;
91
92function WStrBufSize(const Str: PWideChar): Cardinal;
93var
94 P: PWideChar;
95begin
96 P := Str;
97 Dec(PAnsiChar(P), SizeOf(Cardinal));
98 Result := PCardinal(P)^ - SizeOf(Cardinal);
99 Result := Result div SizeOf(WideChar);
100end;
101{$ENDIF}
102
103{$IFNDEF COMPILER_10_UP}
104function WStrMove(Dest: PWideChar; const Source: PWideChar; Count: Cardinal): PWideChar;
105var
106 Length: Integer;
107begin
108 Result := Dest;
109 Length := Count * SizeOf(WideChar);
110 Move(Source^, Dest^, Length);
111end;
112{$ENDIF}
113
114{$IFNDEF COMPILER_9_UP}
115function WStrNew(const Str: PWideChar): PWideChar;
116var
117 Size: Cardinal;
118begin
119 if Str = nil then Result := nil else
120 begin
121 Size := WStrLen(Str) + 1;
122 Result := WStrMove(WStrAlloc(Size), Str, Size);
123 end;
124end;
125
126procedure WStrDispose(Str: PWideChar);
127begin
128 if Str <> nil then
129 begin
130 Dec(PAnsiChar(Str), SizeOf(Cardinal));
131 FreeMem(Str, Cardinal(Pointer(Str)^));
132 end;
133end;
134{$ENDIF}
135
136//---------------------------------------------------------------------------------------------
137
138{$IFNDEF COMPILER_9_UP}
139function WStrLen(Str: PWideChar): Cardinal;
140begin
141 Result := WStrEnd(Str) - Str;
142end;
143
144function WStrEnd(Str: PWideChar): PWideChar;
145begin
146 // returns a pointer to the end of a null terminated string
147 Result := Str;
148 While Result^ <> #0 do
149 Inc(Result);
150end;
151{$ENDIF}
152
153{$IFNDEF COMPILER_10_UP}
154function WStrCat(Dest: PWideChar; const Source: PWideChar): PWideChar;
155begin
156 Result := Dest;
157 WStrCopy(WStrEnd(Dest), Source);
158end;
159{$ENDIF}
160
161{$IFNDEF COMPILER_9_UP}
162function WStrCopy(Dest, Source: PWideChar): PWideChar;
163begin
164 Result := WStrLCopy(Dest, Source, MaxInt);
165end;
166
167function WStrLCopy(Dest, Source: PWideChar; MaxLen: Cardinal): PWideChar;
168var
169 Count: Cardinal;
170begin
171 // copies a specified maximum number of characters from Source to Dest
172 Result := Dest;
173 Count := 0;
174 While (Count < MaxLen) and (Source^ <> #0) do begin
175 Dest^ := Source^;
176 Inc(Source);
177 Inc(Dest);
178 Inc(Count);
179 end;
180 Dest^ := #0;
181end;
182
183function WStrPCopy(Dest: PWideChar; const Source: WideString): PWideChar;
184begin
185 Result := WStrLCopy(Dest, PWideChar(Source), Length(Source));
186end;
187
188function WStrPLCopy(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar;
189begin
190 Result := WStrLCopy(Dest, PWideChar(Source), MaxLen);
191end;
192{$ENDIF}
193
194{$IFNDEF COMPILER_10_UP}
195function WStrScan(const Str: PWideChar; Chr: WideChar): PWideChar;
196begin
197 Result := Str;
198 while Result^ <> Chr do
199 begin
200 if Result^ = #0 then
201 begin
202 Result := nil;
203 Exit;
204 end;
205 Inc(Result);
206 end;
207end;
208
209function WStrComp(Str1, Str2: PWideChar): Integer;
210begin
211 Result := WStrLComp(Str1, Str2, MaxInt);
212end;
213
214function WStrPos(Str, SubStr: PWideChar): PWideChar;
215var
216 PSave: PWideChar;
217 P: PWideChar;
218 PSub: PWideChar;
219begin
220 // returns a pointer to the first occurance of SubStr in Str
221 Result := nil;
222 if (Str <> nil) and (Str^ <> #0) and (SubStr <> nil) and (SubStr^ <> #0) then begin
223 P := Str;
224 While P^ <> #0 do begin
225 if P^ = SubStr^ then begin
226 // investigate possibility here
227 PSave := P;
228 PSub := SubStr;
229 While (P^ = PSub^) do begin
230 Inc(P);
231 Inc(PSub);
232 if (PSub^ = #0) then begin
233 Result := PSave;
234 exit; // found a match
235 end;
236 if (P^ = #0) then
237 exit; // no match, hit end of string
238 end;
239 P := PSave;
240 end;
241 Inc(P);
242 end;
243 end;
244end;
245{$ENDIF}
246
247function Tnt_WStrComp(Str1, Str2: PWideChar): Integer; deprecated;
248begin
249 Result := WStrComp(Str1, Str2);
250end;
251
252function Tnt_WStrPos(Str, SubStr: PWideChar): PWideChar; deprecated;
253begin
254 Result := WStrPos(Str, SubStr);
255end;
256
257//------------------------------------------------------------------------------
258
259function WStrECopy(Dest, Source: PWideChar): PWideChar;
260begin
261 Result := WStrEnd(WStrCopy(Dest, Source));
262end;
263
264function WStrComp_EX(Str1, Str2: PWideChar; MaxLen: Cardinal; dwCmpFlags: Cardinal): Integer;
265var
266 Len1, Len2: Integer;
267begin
268 if MaxLen = Cardinal(MaxInt) then begin
269 Len1 := -1;
270 Len2 := -1;
271 end else begin
272 Len1 := Min(WStrLen(Str1), MaxLen);
273 Len2 := Min(WStrLen(Str2), MaxLen);
274 end;
275 Result := Tnt_CompareStringW(GetThreadLocale, dwCmpFlags, Str1, Len1, Str2, Len2) - 2;
276end;
277
278function WStrLComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer;
279begin
280 Result := WStrComp_EX(Str1, Str2, MaxLen, 0);
281end;
282
283function WStrLIComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer;
284begin
285 Result := WStrComp_EX(Str1, Str2, MaxLen, NORM_IGNORECASE);
286end;
287
288function WStrIComp(Str1, Str2: PWideChar): Integer;
289begin
290 Result := WStrLIComp(Str1, Str2, MaxInt);
291end;
292
293function WStrLower(Str: PWideChar): PWideChar;
294begin
295 Result := Str;
296 Tnt_CharLowerBuffW(Str, WStrLen(Str))
297end;
298
299function WStrUpper(Str: PWideChar): PWideChar;
300begin
301 Result := Str;
302 Tnt_CharUpperBuffW(Str, WStrLen(Str))
303end;
304
305function WStrRScan(const Str: PWideChar; Chr: WideChar): PWideChar;
306var
307 MostRecentFound: PWideChar;
308begin
309 if Chr = #0 then
310 Result := WStrEnd(Str)
311 else
312 begin
313 Result := nil;
314 MostRecentFound := Str;
315 while True do
316 begin
317 while MostRecentFound^ <> Chr do
318 begin
319 if MostRecentFound^ = #0 then
320 Exit;
321 Inc(MostRecentFound);
322 end;
323 Result := MostRecentFound;
324 Inc(MostRecentFound);
325 end;
326 end;
327end;
328
329function WStrLCat(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar;
330begin
331 Result := Dest;
332 WStrLCopy(WStrEnd(Dest), Source, MaxLen - WStrLen(Dest));
333end;
334
335function WStrPas(const Str: PWideChar): WideString;
336begin
337 Result := Str;
338end;
339
340//---------------------------------------------------------------------------------------------
341
342{$IFNDEF COMPILER_10_UP}
343function WideLastChar(const S: WideString): PWideChar;
344begin
345 if S = '' then
346 Result := nil
347 else
348 Result := @S[Length(S)];
349end;
350
351function WideQuotedStr(const S: WideString; Quote: WideChar): WideString;
352var
353 P, Src,
354 Dest: PWideChar;
355 AddCount: Integer;
356begin
357 AddCount := 0;
358 P := WStrScan(PWideChar(S), Quote);
359 while (P <> nil) do
360 begin
361 Inc(P);
362 Inc(AddCount);
363 P := WStrScan(P, Quote);
364 end;
365
366 if AddCount = 0 then
367 Result := Quote + S + Quote
368 else
369 begin
370 SetLength(Result, Length(S) + AddCount + 2);
371 Dest := PWideChar(Result);
372 Dest^ := Quote;
373 Inc(Dest);
374 Src := PWideChar(S);
375 P := WStrScan(Src, Quote);
376 repeat
377 Inc(P);
378 Move(Src^, Dest^, 2 * (P - Src));
379 Inc(Dest, P - Src);
380 Dest^ := Quote;
381 Inc(Dest);
382 Src := P;
383 P := WStrScan(Src, Quote);
384 until P = nil;
385 P := WStrEnd(Src);
386 Move(Src^, Dest^, 2 * (P - Src));
387 Inc(Dest, P - Src);
388 Dest^ := Quote;
389 end;
390end;
391{$ENDIF}
392
393{$IFNDEF COMPILER_9_UP}
394function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): Widestring;
395var
396 P, Dest: PWideChar;
397 DropCount: Integer;
398begin
399 Result := '';
400 if (Src = nil) or (Src^ <> Quote) then Exit;
401 Inc(Src);
402 DropCount := 1;
403 P := Src;
404 Src := WStrScan(Src, Quote);
405 while Src <> nil do // count adjacent pairs of quote chars
406 begin
407 Inc(Src);
408 if Src^ <> Quote then Break;
409 Inc(Src);
410 Inc(DropCount);
411 Src := WStrScan(Src, Quote);
412 end;
413 if Src = nil then Src := WStrEnd(P);
414 if ((Src - P) <= 1) then Exit;
415 if DropCount = 1 then
416 SetString(Result, P, Src - P - 1)
417 else
418 begin
419 SetLength(Result, Src - P - DropCount);
420 Dest := PWideChar(Result);
421 Src := WStrScan(P, Quote);
422 while Src <> nil do
423 begin
424 Inc(Src);
425 if Src^ <> Quote then Break;
426 Move(P^, Dest^, (Src - P) * SizeOf(WideChar));
427 Inc(Dest, Src - P);
428 Inc(Src);
429 P := Src;
430 Src := WStrScan(Src, Quote);
431 end;
432 if Src = nil then Src := WStrEnd(P);
433 Move(P^, Dest^, (Src - P - 1) * SizeOf(WideChar));
434 end;
435end;
436{$ENDIF}
437
438{$IFNDEF COMPILER_10_UP}
439function WideDequotedStr(const S: WideString; AQuote: WideChar): WideString;
440var
441 LText : PWideChar;
442begin
443 LText := PWideChar(S);
444 Result := WideExtractQuotedStr(LText, AQuote);
445 if Result = '' then
446 Result := S;
447end;
448{$ENDIF}
449
450
451end.
Note: See TracBrowser for help on using the repository browser.