source: cprs/branches/tmg-cprs/TntWare/Delphi Unicode Controls/Source/TntWideStrings.pas@ 1531

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

Initial upload of TMG-CPRS 1.0.26.69

File size: 22.7 KB
RevLine 
[453]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 TntWideStrings;
13
14{$INCLUDE TntCompilers.inc}
15
16interface
17
18{$IFDEF COMPILER_10_UP}
19 {$MESSAGE FATAL 'Do not refer to TntWideStrings.pas. It works correctly in Delphi 2006.'}
20{$ENDIF}
21
22uses
23 Classes;
24
25{******************************************************************************}
26{ }
27{ Delphi 2005 introduced TWideStrings in WideStrings.pas. }
28{ Unfortunately, it was not ready for prime time. }
29{ Setting CommaText is not consistent, and it relies on CharNextW }
30{ Which is only available on Windows NT+. }
31{ }
32{******************************************************************************}
33
34type
35 TWideStrings = class;
36
37{ IWideStringsAdapter interface }
38{ Maintains link between TWideStrings and IWideStrings implementations }
39
40 IWideStringsAdapter = interface
41 ['{25FE0E3B-66CB-48AA-B23B-BCFA67E8F5DA}']
42 procedure ReferenceStrings(S: TWideStrings);
43 procedure ReleaseStrings;
44 end;
45
46 TWideStringsEnumerator = class
47 private
48 FIndex: Integer;
49 FStrings: TWideStrings;
50 public
51 constructor Create(AStrings: TWideStrings);
52 function GetCurrent: WideString;
53 function MoveNext: Boolean;
54 property Current: WideString read GetCurrent;
55 end;
56
57{ TWideStrings class }
58
59 TWideStrings = class(TPersistent)
60 private
61 FDefined: TStringsDefined;
62 FDelimiter: WideChar;
63 FQuoteChar: WideChar;
64 {$IFDEF COMPILER_7_UP}
65 FNameValueSeparator: WideChar;
66 {$ENDIF}
67 FUpdateCount: Integer;
68 FAdapter: IWideStringsAdapter;
69 function GetCommaText: WideString;
70 function GetDelimitedText: WideString;
71 function GetName(Index: Integer): WideString;
72 function GetValue(const Name: WideString): WideString;
73 procedure ReadData(Reader: TReader);
74 procedure SetCommaText(const Value: WideString);
75 procedure SetDelimitedText(const Value: WideString);
76 procedure SetStringsAdapter(const Value: IWideStringsAdapter);
77 procedure SetValue(const Name, Value: WideString);
78 procedure WriteData(Writer: TWriter);
79 function GetDelimiter: WideChar;
80 procedure SetDelimiter(const Value: WideChar);
81 function GetQuoteChar: WideChar;
82 procedure SetQuoteChar(const Value: WideChar);
83 function GetNameValueSeparator: WideChar;
84 {$IFDEF COMPILER_7_UP}
85 procedure SetNameValueSeparator(const Value: WideChar);
86 {$ENDIF}
87 function GetValueFromIndex(Index: Integer): WideString;
88 procedure SetValueFromIndex(Index: Integer; const Value: WideString);
89 protected
90 procedure AssignTo(Dest: TPersistent); override;
91 procedure DefineProperties(Filer: TFiler); override;
92 procedure Error(const Msg: WideString; Data: Integer); overload;
93 procedure Error(Msg: PResStringRec; Data: Integer); overload;
94 function ExtractName(const S: WideString): WideString;
95 function Get(Index: Integer): WideString; virtual; abstract;
96 function GetCapacity: Integer; virtual;
97 function GetCount: Integer; virtual; abstract;
98 function GetObject(Index: Integer): TObject; virtual;
99 function GetTextStr: WideString; virtual;
100 procedure Put(Index: Integer; const S: WideString); virtual;
101 procedure PutObject(Index: Integer; AObject: TObject); virtual;
102 procedure SetCapacity(NewCapacity: Integer); virtual;
103 procedure SetTextStr(const Value: WideString); virtual;
104 procedure SetUpdateState(Updating: Boolean); virtual;
105 property UpdateCount: Integer read FUpdateCount;
106 function CompareStrings(const S1, S2: WideString): Integer; virtual;
107 public
108 destructor Destroy; override;
109 function Add(const S: WideString): Integer; virtual;
110 function AddObject(const S: WideString; AObject: TObject): Integer; virtual;
111 procedure Append(const S: WideString);
112 procedure AddStrings(Strings: TStrings{TNT-ALLOW TStrings}); overload; virtual;
113 procedure AddStrings(Strings: TWideStrings); overload; virtual;
114 procedure Assign(Source: TPersistent); override;
115 procedure BeginUpdate;
116 procedure Clear; virtual; abstract;
117 procedure Delete(Index: Integer); virtual; abstract;
118 procedure EndUpdate;
119 function Equals(Strings: TWideStrings): Boolean;
120 procedure Exchange(Index1, Index2: Integer); virtual;
121 function GetEnumerator: TWideStringsEnumerator;
122 function GetTextW: PWideChar; virtual;
123 function IndexOf(const S: WideString): Integer; virtual;
124 function IndexOfName(const Name: WideString): Integer; virtual;
125 function IndexOfObject(AObject: TObject): Integer; virtual;
126 procedure Insert(Index: Integer; const S: WideString); virtual; abstract;
127 procedure InsertObject(Index: Integer; const S: WideString;
128 AObject: TObject); virtual;
129 procedure LoadFromFile(const FileName: WideString); virtual;
130 procedure LoadFromStream(Stream: TStream); virtual;
131 procedure Move(CurIndex, NewIndex: Integer); virtual;
132 procedure SaveToFile(const FileName: WideString); virtual;
133 procedure SaveToStream(Stream: TStream); virtual;
134 procedure SetTextW(const Text: PWideChar); virtual;
135 property Capacity: Integer read GetCapacity write SetCapacity;
136 property CommaText: WideString read GetCommaText write SetCommaText;
137 property Count: Integer read GetCount;
138 property Delimiter: WideChar read GetDelimiter write SetDelimiter;
139 property DelimitedText: WideString read GetDelimitedText write SetDelimitedText;
140 property Names[Index: Integer]: WideString read GetName;
141 property Objects[Index: Integer]: TObject read GetObject write PutObject;
142 property QuoteChar: WideChar read GetQuoteChar write SetQuoteChar;
143 property Values[const Name: WideString]: WideString read GetValue write SetValue;
144 property ValueFromIndex[Index: Integer]: WideString read GetValueFromIndex write SetValueFromIndex;
145 property NameValueSeparator: WideChar read GetNameValueSeparator {$IFDEF COMPILER_7_UP} write SetNameValueSeparator {$ENDIF};
146 property Strings[Index: Integer]: WideString read Get write Put; default;
147 property Text: WideString read GetTextStr write SetTextStr;
148 property StringsAdapter: IWideStringsAdapter read FAdapter write SetStringsAdapter;
149 end;
150
151 PWideStringItem = ^TWideStringItem;
152 TWideStringItem = record
153 FString: WideString;
154 FObject: TObject;
155 end;
156
157 PWideStringItemList = ^TWideStringItemList;
158 TWideStringItemList = array[0..MaxListSize] of TWideStringItem;
159
160implementation
161
162uses
163 Windows, SysUtils, TntSystem, {$IFDEF COMPILER_9_UP} WideStrUtils, {$ELSE} TntWideStrUtils, {$ENDIF}
164 TntSysUtils, TntClasses;
165
166{ TWideStringsEnumerator }
167
168constructor TWideStringsEnumerator.Create(AStrings: TWideStrings);
169begin
170 inherited Create;
171 FIndex := -1;
172 FStrings := AStrings;
173end;
174
175function TWideStringsEnumerator.GetCurrent: WideString;
176begin
177 Result := FStrings[FIndex];
178end;
179
180function TWideStringsEnumerator.MoveNext: Boolean;
181begin
182 Result := FIndex < FStrings.Count - 1;
183 if Result then
184 Inc(FIndex);
185end;
186
187{ TWideStrings }
188
189destructor TWideStrings.Destroy;
190begin
191 StringsAdapter := nil;
192 inherited;
193end;
194
195function TWideStrings.Add(const S: WideString): Integer;
196begin
197 Result := GetCount;
198 Insert(Result, S);
199end;
200
201function TWideStrings.AddObject(const S: WideString; AObject: TObject): Integer;
202begin
203 Result := Add(S);
204 PutObject(Result, AObject);
205end;
206
207procedure TWideStrings.Append(const S: WideString);
208begin
209 Add(S);
210end;
211
212procedure TWideStrings.AddStrings(Strings: TStrings{TNT-ALLOW TStrings});
213var
214 I: Integer;
215begin
216 BeginUpdate;
217 try
218 for I := 0 to Strings.Count - 1 do
219 AddObject(Strings[I], Strings.Objects[I]);
220 finally
221 EndUpdate;
222 end;
223end;
224
225procedure TWideStrings.AddStrings(Strings: TWideStrings);
226var
227 I: Integer;
228begin
229 BeginUpdate;
230 try
231 for I := 0 to Strings.Count - 1 do
232 AddObject(Strings[I], Strings.Objects[I]);
233 finally
234 EndUpdate;
235 end;
236end;
237
238procedure TWideStrings.Assign(Source: TPersistent);
239begin
240 if Source is TWideStrings then
241 begin
242 BeginUpdate;
243 try
244 Clear;
245 FDefined := TWideStrings(Source).FDefined;
246 {$IFDEF COMPILER_7_UP}
247 FNameValueSeparator := TWideStrings(Source).FNameValueSeparator;
248 {$ENDIF}
249 FQuoteChar := TWideStrings(Source).FQuoteChar;
250 FDelimiter := TWideStrings(Source).FDelimiter;
251 AddStrings(TWideStrings(Source));
252 finally
253 EndUpdate;
254 end;
255 end
256 else if Source is TStrings{TNT-ALLOW TStrings} then
257 begin
258 BeginUpdate;
259 try
260 Clear;
261 {$IFDEF COMPILER_7_UP}
262 FNameValueSeparator := WideChar(TStrings{TNT-ALLOW TStrings}(Source).NameValueSeparator);
263 {$ENDIF}
264 FQuoteChar := WideChar(TStrings{TNT-ALLOW TStrings}(Source).QuoteChar);
265 FDelimiter := WideChar(TStrings{TNT-ALLOW TStrings}(Source).Delimiter);
266 AddStrings(TStrings{TNT-ALLOW TStrings}(Source));
267 finally
268 EndUpdate;
269 end;
270 end
271 else
272 inherited Assign(Source);
273end;
274
275procedure TWideStrings.AssignTo(Dest: TPersistent);
276var
277 I: Integer;
278begin
279 if Dest is TWideStrings then Dest.Assign(Self)
280 else if Dest is TStrings{TNT-ALLOW TStrings} then
281 begin
282 TStrings{TNT-ALLOW TStrings}(Dest).BeginUpdate;
283 try
284 TStrings{TNT-ALLOW TStrings}(Dest).Clear;
285 {$IFDEF COMPILER_7_UP}
286 TStrings{TNT-ALLOW TStrings}(Dest).NameValueSeparator := AnsiChar(NameValueSeparator);
287 {$ENDIF}
288 TStrings{TNT-ALLOW TStrings}(Dest).QuoteChar := AnsiChar(QuoteChar);
289 TStrings{TNT-ALLOW TStrings}(Dest).Delimiter := AnsiChar(Delimiter);
290 for I := 0 to Count - 1 do
291 TStrings{TNT-ALLOW TStrings}(Dest).AddObject(Strings[I], Objects[I]);
292 finally
293 TStrings{TNT-ALLOW TStrings}(Dest).EndUpdate;
294 end;
295 end
296 else
297 inherited AssignTo(Dest);
298end;
299
300procedure TWideStrings.BeginUpdate;
301begin
302 if FUpdateCount = 0 then SetUpdateState(True);
303 Inc(FUpdateCount);
304end;
305
306procedure TWideStrings.DefineProperties(Filer: TFiler);
307
308 function DoWrite: Boolean;
309 begin
310 if Filer.Ancestor <> nil then
311 begin
312 Result := True;
313 if Filer.Ancestor is TWideStrings then
314 Result := not Equals(TWideStrings(Filer.Ancestor))
315 end
316 else Result := Count > 0;
317 end;
318
319begin
320 Filer.DefineProperty('Strings', ReadData, WriteData, DoWrite);
321end;
322
323procedure TWideStrings.EndUpdate;
324begin
325 Dec(FUpdateCount);
326 if FUpdateCount = 0 then SetUpdateState(False);
327end;
328
329function TWideStrings.Equals(Strings: TWideStrings): Boolean;
330var
331 I, Count: Integer;
332begin
333 Result := False;
334 Count := GetCount;
335 if Count <> Strings.GetCount then Exit;
336 for I := 0 to Count - 1 do if Get(I) <> Strings.Get(I) then Exit;
337 Result := True;
338end;
339
340procedure TWideStrings.Error(const Msg: WideString; Data: Integer);
341
342 function ReturnAddr: Pointer;
343 asm
344 MOV EAX,[EBP+4]
345 end;
346
347begin
348 raise EStringListError.CreateFmt(Msg, [Data]) at ReturnAddr;
349end;
350
351procedure TWideStrings.Error(Msg: PResStringRec; Data: Integer);
352begin
353 Error(WideLoadResString(Msg), Data);
354end;
355
356procedure TWideStrings.Exchange(Index1, Index2: Integer);
357var
358 TempObject: TObject;
359 TempString: WideString;
360begin
361 BeginUpdate;
362 try
363 TempString := Strings[Index1];
364 TempObject := Objects[Index1];
365 Strings[Index1] := Strings[Index2];
366 Objects[Index1] := Objects[Index2];
367 Strings[Index2] := TempString;
368 Objects[Index2] := TempObject;
369 finally
370 EndUpdate;
371 end;
372end;
373
374function TWideStrings.ExtractName(const S: WideString): WideString;
375var
376 P: Integer;
377begin
378 Result := S;
379 P := Pos(NameValueSeparator, Result);
380 if P <> 0 then
381 SetLength(Result, P-1) else
382 SetLength(Result, 0);
383end;
384
385function TWideStrings.GetCapacity: Integer;
386begin // descendents may optionally override/replace this default implementation
387 Result := Count;
388end;
389
390function TWideStrings.GetCommaText: WideString;
391var
392 LOldDefined: TStringsDefined;
393 LOldDelimiter: WideChar;
394 LOldQuoteChar: WideChar;
395begin
396 LOldDefined := FDefined;
397 LOldDelimiter := FDelimiter;
398 LOldQuoteChar := FQuoteChar;
399 Delimiter := ',';
400 QuoteChar := '"';
401 try
402 Result := GetDelimitedText;
403 finally
404 FDelimiter := LOldDelimiter;
405 FQuoteChar := LOldQuoteChar;
406 FDefined := LOldDefined;
407 end;
408end;
409
410function TWideStrings.GetDelimitedText: WideString;
411var
412 S: WideString;
413 P: PWideChar;
414 I, Count: Integer;
415begin
416 Count := GetCount;
417 if (Count = 1) and (Get(0) = '') then
418 Result := WideString(QuoteChar) + QuoteChar
419 else
420 begin
421 Result := '';
422 for I := 0 to Count - 1 do
423 begin
424 S := Get(I);
425 P := PWideChar(S);
426 while not ((P^ in [WideChar(#0)..WideChar(' ')]) or (P^ = QuoteChar) or (P^ = Delimiter)) do
427 Inc(P);
428 if (P^ <> #0) then S := WideQuotedStr(S, QuoteChar);
429 Result := Result + S + Delimiter;
430 end;
431 System.Delete(Result, Length(Result), 1);
432 end;
433end;
434
435function TWideStrings.GetName(Index: Integer): WideString;
436begin
437 Result := ExtractName(Get(Index));
438end;
439
440function TWideStrings.GetObject(Index: Integer): TObject;
441begin
442 Result := nil;
443end;
444
445function TWideStrings.GetEnumerator: TWideStringsEnumerator;
446begin
447 Result := TWideStringsEnumerator.Create(Self);
448end;
449
450function TWideStrings.GetTextW: PWideChar;
451begin
452 Result := WStrNew(PWideChar(GetTextStr));
453end;
454
455function TWideStrings.GetTextStr: WideString;
456var
457 I, L, Size, Count: Integer;
458 P: PWideChar;
459 S, LB: WideString;
460begin
461 Count := GetCount;
462 Size := 0;
463 LB := sLineBreak;
464 for I := 0 to Count - 1 do Inc(Size, Length(Get(I)) + Length(LB));
465 SetString(Result, nil, Size);
466 P := Pointer(Result);
467 for I := 0 to Count - 1 do
468 begin
469 S := Get(I);
470 L := Length(S);
471 if L <> 0 then
472 begin
473 System.Move(Pointer(S)^, P^, L * SizeOf(WideChar));
474 Inc(P, L);
475 end;
476 L := Length(LB);
477 if L <> 0 then
478 begin
479 System.Move(Pointer(LB)^, P^, L * SizeOf(WideChar));
480 Inc(P, L);
481 end;
482 end;
483end;
484
485function TWideStrings.GetValue(const Name: WideString): WideString;
486var
487 I: Integer;
488begin
489 I := IndexOfName(Name);
490 if I >= 0 then
491 Result := Copy(Get(I), Length(Name) + 2, MaxInt) else
492 Result := '';
493end;
494
495function TWideStrings.IndexOf(const S: WideString): Integer;
496begin
497 for Result := 0 to GetCount - 1 do
498 if CompareStrings(Get(Result), S) = 0 then Exit;
499 Result := -1;
500end;
501
502function TWideStrings.IndexOfName(const Name: WideString): Integer;
503var
504 P: Integer;
505 S: WideString;
506begin
507 for Result := 0 to GetCount - 1 do
508 begin
509 S := Get(Result);
510 P := Pos(NameValueSeparator, S);
511 if (P <> 0) and (CompareStrings(Copy(S, 1, P - 1), Name) = 0) then Exit;
512 end;
513 Result := -1;
514end;
515
516function TWideStrings.IndexOfObject(AObject: TObject): Integer;
517begin
518 for Result := 0 to GetCount - 1 do
519 if GetObject(Result) = AObject then Exit;
520 Result := -1;
521end;
522
523procedure TWideStrings.InsertObject(Index: Integer; const S: WideString;
524 AObject: TObject);
525begin
526 Insert(Index, S);
527 PutObject(Index, AObject);
528end;
529
530procedure TWideStrings.LoadFromFile(const FileName: WideString);
531var
532 Stream: TStream;
533begin
534 Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
535 try
536 LoadFromStream(Stream);
537 finally
538 Stream.Free;
539 end;
540end;
541
542procedure TWideStrings.LoadFromStream(Stream: TStream);
543var
544 Size: Integer;
545 S: WideString;
546begin
547 BeginUpdate;
548 try
549 Size := Stream.Size - Stream.Position;
550 SetString(S, nil, Size div SizeOf(WideChar));
551 Stream.Read(Pointer(S)^, Length(S) * SizeOf(WideChar));
552 SetTextStr(S);
553 finally
554 EndUpdate;
555 end;
556end;
557
558procedure TWideStrings.Move(CurIndex, NewIndex: Integer);
559var
560 TempObject: TObject;
561 TempString: WideString;
562begin
563 if CurIndex <> NewIndex then
564 begin
565 BeginUpdate;
566 try
567 TempString := Get(CurIndex);
568 TempObject := GetObject(CurIndex);
569 Delete(CurIndex);
570 InsertObject(NewIndex, TempString, TempObject);
571 finally
572 EndUpdate;
573 end;
574 end;
575end;
576
577procedure TWideStrings.Put(Index: Integer; const S: WideString);
578var
579 TempObject: TObject;
580begin
581 TempObject := GetObject(Index);
582 Delete(Index);
583 InsertObject(Index, S, TempObject);
584end;
585
586procedure TWideStrings.PutObject(Index: Integer; AObject: TObject);
587begin
588end;
589
590procedure TWideStrings.ReadData(Reader: TReader);
591begin
592 if Reader.NextValue in [vaString, vaLString] then
593 SetTextStr(Reader.ReadString) {JCL compatiblity}
594 else if Reader.NextValue = vaWString then
595 SetTextStr(Reader.ReadWideString) {JCL compatiblity}
596 else begin
597 BeginUpdate;
598 try
599 Clear;
600 Reader.ReadListBegin;
601 while not Reader.EndOfList do
602 if Reader.NextValue in [vaString, vaLString] then
603 Add(Reader.ReadString) {TStrings compatiblity}
604 else
605 Add(Reader.ReadWideString);
606 Reader.ReadListEnd;
607 finally
608 EndUpdate;
609 end;
610 end;
611end;
612
613procedure TWideStrings.SaveToFile(const FileName: WideString);
614var
615 Stream: TStream;
616begin
617 Stream := TTntFileStream.Create(FileName, fmCreate);
618 try
619 SaveToStream(Stream);
620 finally
621 Stream.Free;
622 end;
623end;
624
625procedure TWideStrings.SaveToStream(Stream: TStream);
626var
627 SW: WideString;
628begin
629 SW := GetTextStr;
630 Stream.WriteBuffer(PWideChar(SW)^, Length(SW) * SizeOf(WideChar));
631end;
632
633procedure TWideStrings.SetCapacity(NewCapacity: Integer);
634begin
635 // do nothing - descendents may optionally implement this method
636end;
637
638procedure TWideStrings.SetCommaText(const Value: WideString);
639begin
640 Delimiter := ',';
641 QuoteChar := '"';
642 SetDelimitedText(Value);
643end;
644
645procedure TWideStrings.SetStringsAdapter(const Value: IWideStringsAdapter);
646begin
647 if FAdapter <> nil then FAdapter.ReleaseStrings;
648 FAdapter := Value;
649 if FAdapter <> nil then FAdapter.ReferenceStrings(Self);
650end;
651
652procedure TWideStrings.SetTextW(const Text: PWideChar);
653begin
654 SetTextStr(Text);
655end;
656
657procedure TWideStrings.SetTextStr(const Value: WideString);
658var
659 P, Start: PWideChar;
660 S: WideString;
661begin
662 BeginUpdate;
663 try
664 Clear;
665 P := Pointer(Value);
666 if P <> nil then
667 while P^ <> #0 do
668 begin
669 Start := P;
670 while not (P^ in [WideChar(#0), WideChar(#10), WideChar(#13)]) and (P^ <> WideLineSeparator) do
671 Inc(P);
672 SetString(S, Start, P - Start);
673 Add(S);
674 if P^ = #13 then Inc(P);
675 if P^ = #10 then Inc(P);
676 if P^ = WideLineSeparator then Inc(P);
677 end;
678 finally
679 EndUpdate;
680 end;
681end;
682
683procedure TWideStrings.SetUpdateState(Updating: Boolean);
684begin
685end;
686
687procedure TWideStrings.SetValue(const Name, Value: WideString);
688var
689 I: Integer;
690begin
691 I := IndexOfName(Name);
692 if Value <> '' then
693 begin
694 if I < 0 then I := Add('');
695 Put(I, Name + NameValueSeparator + Value);
696 end else
697 begin
698 if I >= 0 then Delete(I);
699 end;
700end;
701
702procedure TWideStrings.WriteData(Writer: TWriter);
703var
704 I: Integer;
705begin
706 Writer.WriteListBegin;
707 for I := 0 to Count-1 do begin
708 Writer.WriteWideString(Get(I));
709 end;
710 Writer.WriteListEnd;
711end;
712
713procedure TWideStrings.SetDelimitedText(const Value: WideString);
714var
715 P, P1: PWideChar;
716 S: WideString;
717begin
718 BeginUpdate;
719 try
720 Clear;
721 P := PWideChar(Value);
722 while P^ in [WideChar(#1)..WideChar(' ')] do
723 Inc(P);
724 while P^ <> #0 do
725 begin
726 if P^ = QuoteChar then
727 S := WideExtractQuotedStr(P, QuoteChar)
728 else
729 begin
730 P1 := P;
731 while (P^ > ' ') and (P^ <> Delimiter) do
732 Inc(P);
733 SetString(S, P1, P - P1);
734 end;
735 Add(S);
736 while P^ in [WideChar(#1)..WideChar(' ')] do
737 Inc(P);
738 if P^ = Delimiter then
739 begin
740 P1 := P;
741 Inc(P1);
742 if P1^ = #0 then
743 Add('');
744 repeat
745 Inc(P);
746 until not (P^ in [WideChar(#1)..WideChar(' ')]);
747 end;
748 end;
749 finally
750 EndUpdate;
751 end;
752end;
753
754function TWideStrings.GetDelimiter: WideChar;
755begin
756 if not (sdDelimiter in FDefined) then
757 Delimiter := ',';
758 Result := FDelimiter;
759end;
760
761function TWideStrings.GetQuoteChar: WideChar;
762begin
763 if not (sdQuoteChar in FDefined) then
764 QuoteChar := '"';
765 Result := FQuoteChar;
766end;
767
768procedure TWideStrings.SetDelimiter(const Value: WideChar);
769begin
770 if (FDelimiter <> Value) or not (sdDelimiter in FDefined) then
771 begin
772 Include(FDefined, sdDelimiter);
773 FDelimiter := Value;
774 end
775end;
776
777procedure TWideStrings.SetQuoteChar(const Value: WideChar);
778begin
779 if (FQuoteChar <> Value) or not (sdQuoteChar in FDefined) then
780 begin
781 Include(FDefined, sdQuoteChar);
782 FQuoteChar := Value;
783 end
784end;
785
786function TWideStrings.CompareStrings(const S1, S2: WideString): Integer;
787begin
788 Result := WideCompareText(S1, S2);
789end;
790
791function TWideStrings.GetNameValueSeparator: WideChar;
792begin
793 {$IFDEF COMPILER_7_UP}
794 if not (sdNameValueSeparator in FDefined) then
795 NameValueSeparator := '=';
796 Result := FNameValueSeparator;
797 {$ELSE}
798 Result := '=';
799 {$ENDIF}
800end;
801
802{$IFDEF COMPILER_7_UP}
803procedure TWideStrings.SetNameValueSeparator(const Value: WideChar);
804begin
805 if (FNameValueSeparator <> Value) or not (sdNameValueSeparator in FDefined) then
806 begin
807 Include(FDefined, sdNameValueSeparator);
808 FNameValueSeparator := Value;
809 end
810end;
811{$ENDIF}
812
813function TWideStrings.GetValueFromIndex(Index: Integer): WideString;
814begin
815 if Index >= 0 then
816 Result := Copy(Get(Index), Length(Names[Index]) + 2, MaxInt) else
817 Result := '';
818end;
819
820procedure TWideStrings.SetValueFromIndex(Index: Integer; const Value: WideString);
821begin
822 if Value <> '' then
823 begin
824 if Index < 0 then Index := Add('');
825 Put(Index, Names[Index] + NameValueSeparator + Value);
826 end
827 else
828 if Index >= 0 then Delete(Index);
829end;
830
831end.
Note: See TracBrowser for help on using the repository browser.