📄 qexport4emswidestrings.pas
字号:
unit QExport4EmsWideStrings;
{$I VerCtrl.inc}
interface
{$IFDEF QE_UNICODE}
{$IF NOT (RTLVersion >= 18)}
{$IFDEF VCL10}
{$MESSAGE FATAL 'Do not refer to EmsWideStrings.pas. It works correctly in Delphi 2006.'}
{$ENDIF}
uses
Classes;
type
TWideStrings = class;
{ IWideStringsAdapter interface }
IWideStringsAdapter = interface
['{25FE0E3B-66CB-48AA-B23B-BCFA67E8F5DA}']
procedure ReferenceStrings(S: TWideStrings);
procedure ReleaseStrings;
end;
TWideStringsEnumerator = class
private
FIndex: Integer;
FStrings: TWideStrings;
public
constructor Create(AStrings: TWideStrings);
function GetCurrent: WideString;
function MoveNext: Boolean;
property Current: WideString read GetCurrent;
end;
{ TWideStrings class }
TWideStrings = class(TPersistent)
private
FDefined: TStringsDefined;
FDelimiter: WideChar;
FQuoteChar: WideChar;
{$IFDEF VCL7}
FNameValueSeparator: WideChar;
{$ENDIF}
FUpdateCount: Integer;
FAdapter: IWideStringsAdapter;
function GetCommaText: WideString;
function GetDelimitedText: WideString;
function GetName(Index: Integer): WideString;
function GetValue(const Name: WideString): WideString;
procedure ReadData(Reader: TReader);
procedure SetCommaText(const Value: WideString);
procedure SetDelimitedText(const Value: WideString);
procedure SetStringsAdapter(const Value: IWideStringsAdapter);
procedure SetValue(const Name, Value: WideString);
procedure WriteData(Writer: TWriter);
function GetDelimiter: WideChar;
procedure SetDelimiter(const Value: WideChar);
function GetQuoteChar: WideChar;
procedure SetQuoteChar(const Value: WideChar);
function GetNameValueSeparator: WideChar;
{$IFDEF VCL7}
procedure SetNameValueSeparator(const Value: WideChar);
{$ENDIF}
function GetValueFromIndex(Index: Integer): WideString;
procedure SetValueFromIndex(Index: Integer; const Value: WideString);
protected
procedure AssignTo(Dest: TPersistent); override;
procedure DefineProperties(Filer: TFiler); override;
procedure Error(const Msg: WideString; Data: Integer); overload;
procedure Error(Msg: PResStringRec; Data: Integer); overload;
function ExtractName(const S: WideString): WideString;
function Get(Index: Integer): WideString; virtual; abstract;
function GetCapacity: Integer; virtual;
function GetCount: Integer; virtual; abstract;
function GetObject(Index: Integer): TObject; virtual;
function GetTextStr: WideString; virtual;
procedure Put(Index: Integer; const S: WideString); virtual;
procedure PutObject(Index: Integer; AObject: TObject); virtual;
procedure SetCapacity(NewCapacity: Integer); virtual;
procedure SetTextStr(const Value: WideString); virtual;
procedure SetUpdateState(Updating: Boolean); virtual;
property UpdateCount: Integer read FUpdateCount;
function CompareStrings(const S1, S2: WideString): Integer; virtual;
public
destructor Destroy; override;
function Add(const S: WideString): Integer; virtual;
function AddObject(const S: WideString; AObject: TObject): Integer; virtual;
procedure Append(const S: WideString);
procedure AddStrings(Strings: TStrings); overload; virtual;
procedure AddStrings(Strings: TWideStrings); overload; virtual;
procedure Assign(Source: TPersistent); override;
procedure BeginUpdate;
procedure Clear; virtual; abstract;
procedure Delete(Index: Integer); virtual; abstract;
procedure EndUpdate;
function Equals(Strings: TWideStrings): Boolean;
procedure Exchange(Index1, Index2: Integer); virtual;
function GetEnumerator: TWideStringsEnumerator;
function GetTextW: PWideChar; virtual;
function IndexOf(const S: WideString): Integer; virtual;
function IndexOfName(const Name: WideString): Integer; virtual;
function IndexOfObject(AObject: TObject): Integer; virtual;
procedure Insert(Index: Integer; const S: WideString); virtual; abstract;
procedure InsertObject(Index: Integer; const S: WideString;
AObject: TObject); virtual;
procedure LoadFromFile(const FileName: WideString); virtual;
procedure LoadFromStream(Stream: TStream); virtual;
procedure Move(CurIndex, NewIndex: Integer); virtual;
procedure SaveToFile(const FileName: WideString); virtual;
procedure SaveToStream(Stream: TStream); virtual;
procedure SetTextW(const Text: PWideChar); virtual;
property Capacity: Integer read GetCapacity write SetCapacity;
property CommaText: WideString read GetCommaText write SetCommaText;
property Count: Integer read GetCount;
property Delimiter: WideChar read GetDelimiter write SetDelimiter;
property DelimitedText: WideString read GetDelimitedText write SetDelimitedText;
property Names[Index: Integer]: WideString read GetName;
property Objects[Index: Integer]: TObject read GetObject write PutObject;
property QuoteChar: WideChar read GetQuoteChar write SetQuoteChar;
property Values[const Name: WideString]: WideString read GetValue write SetValue;
property ValueFromIndex[Index: Integer]: WideString read GetValueFromIndex write SetValueFromIndex;
property NameValueSeparator: WideChar read GetNameValueSeparator {$IFDEF VCL7} write SetNameValueSeparator {$ENDIF};
property Strings[Index: Integer]: WideString read Get write Put; default;
property Text: WideString read GetTextStr write SetTextStr;
property StringsAdapter: IWideStringsAdapter read FAdapter write SetStringsAdapter;
end;
PWideStringItem = ^TWideStringItem;
TWideStringItem = record
FString: WideString;
FObject: TObject;
end;
PWideStringItemList = ^TWideStringItemList;
TWideStringItemList = array[0..MaxListSize] of TWideStringItem;
{ TWideStringList class }
TWideStringList = class;
TWideStringListSortCompare = function(List: TWideStringList; Index1, Index2: Integer): Integer;
TWideStringList = class(TWideStrings)
private
FUpdating: Boolean;
FList: PWideStringItemList;
FCount: Integer;
FCapacity: Integer;
FSorted: Boolean;
FDuplicates: TDuplicates;
FCaseSensitive: Boolean;
FOnChange: TNotifyEvent;
FOnChanging: TNotifyEvent;
procedure ExchangeItems(Index1, Index2: Integer);
procedure Grow;
procedure QuickSort(L, R: Integer; SCompare: TWideStringListSortCompare);
procedure SetSorted(Value: Boolean);
procedure SetCaseSensitive(const Value: Boolean);
protected
procedure Changed; virtual;
procedure Changing; virtual;
function Get(Index: Integer): WideString; override;
function GetCapacity: Integer; override;
function GetCount: Integer; override;
function GetObject(Index: Integer): TObject; override;
procedure Put(Index: Integer; const S: WideString); override;
procedure PutObject(Index: Integer; AObject: TObject); override;
procedure SetCapacity(NewCapacity: Integer); override;
procedure SetUpdateState(Updating: Boolean); override;
function CompareStrings(const S1, S2: WideString): Integer; override;
procedure InsertItem(Index: Integer; const S: WideString; AObject: TObject); virtual;
public
destructor Destroy; override;
function Add(const S: WideString): Integer; override;
function AddObject(const S: WideString; AObject: TObject): Integer; override;
procedure Clear; override;
procedure Delete(Index: Integer); override;
procedure Exchange(Index1, Index2: Integer); override;
function Find(const S: WideString; var Index: Integer): Boolean; virtual;
function IndexOf(const S: WideString): Integer; override;
function IndexOfName(const Name: WideString): Integer; override;
procedure Insert(Index: Integer; const S: WideString); override;
procedure InsertObject(Index: Integer; const S: WideString;
AObject: TObject); override;
procedure Sort; virtual;
procedure CustomSort(Compare: TWideStringListSortCompare); virtual;
property Duplicates: TDuplicates read FDuplicates write FDuplicates;
property Sorted: Boolean read FSorted write SetSorted;
property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnChanging: TNotifyEvent read FOnChanging write FOnChanging;
end;
{$IFEND}
{$ENDIF}
implementation
{$IFDEF QE_UNICODE}
{$IF NOT (RTLVersion >= 18)}
uses
{$IFDEF VCL9} WideStrUtils, {$ELSE} QExport4EmsWideStrUtils, {$ENDIF}
{$IFDEF VCL6} RTLConsts, {$ENDIF}
Windows, SysUtils;
const
WideLineSeparator = WideChar($2028);
{$IFDEF VER130}
resourcestring
SDuplicateString = 'String list does not allow duplicates';
SListIndexError = 'List index out of bounds (%d)';
SSortedListError = 'Operation not allowed on sorted list';
{$ENDIF}
{ TWideStringsEnumerator }
constructor TWideStringsEnumerator.Create(AStrings: TWideStrings);
begin
inherited Create;
FIndex := -1;
FStrings := AStrings;
end;
function TWideStringsEnumerator.GetCurrent: WideString;
begin
Result := FStrings[FIndex];
end;
function TWideStringsEnumerator.MoveNext: Boolean;
begin
Result := FIndex < FStrings.Count - 1;
if Result then
Inc(FIndex);
end;
{ TWideStrings }
destructor TWideStrings.Destroy;
begin
StringsAdapter := nil;
inherited;
end;
function TWideStrings.Add(const S: WideString): Integer;
begin
Result := GetCount;
Insert(Result, S);
end;
function TWideStrings.AddObject(const S: WideString; AObject: TObject): Integer;
begin
Result := Add(S);
PutObject(Result, AObject);
end;
procedure TWideStrings.Append(const S: WideString);
begin
Add(S);
end;
procedure TWideStrings.AddStrings(Strings: TStrings);
var
I: Integer;
begin
BeginUpdate;
try
for I := 0 to Strings.Count - 1 do
AddObject(Strings[I], Strings.Objects[I]);
finally
EndUpdate;
end;
end;
procedure TWideStrings.AddStrings(Strings: TWideStrings);
var
I: Integer;
begin
BeginUpdate;
try
for I := 0 to Strings.Count - 1 do
AddObject(Strings[I], Strings.Objects[I]);
finally
EndUpdate;
end;
end;
procedure TWideStrings.Assign(Source: TPersistent);
begin
if Source is TWideStrings then
begin
BeginUpdate;
try
Clear;
FDefined := TWideStrings(Source).FDefined;
{$IFDEF VCL7}
FNameValueSeparator := TWideStrings(Source).FNameValueSeparator;
{$ENDIF}
FQuoteChar := TWideStrings(Source).FQuoteChar;
FDelimiter := TWideStrings(Source).FDelimiter;
AddStrings(TWideStrings(Source));
finally
EndUpdate;
end;
end
else if Source is TStrings then
begin
BeginUpdate;
try
Clear;
{$IFDEF VCL7}
FNameValueSeparator := WideChar(TStrings(Source).NameValueSeparator);
{$ENDIF}
FQuoteChar := WideChar(TStrings(Source).QuoteChar);
FDelimiter := WideChar(TStrings(Source).Delimiter);
AddStrings(TStrings(Source));
finally
EndUpdate;
end;
end
else
inherited Assign(Source);
end;
procedure TWideStrings.AssignTo(Dest: TPersistent);
var
I: Integer;
begin
if Dest is TWideStrings then Dest.Assign(Self)
else if Dest is TStrings then
begin
TStrings(Dest).BeginUpdate;
try
TStrings(Dest).Clear;
{$IFDEF VCL7}
TStrings(Dest).NameValueSeparator := AnsiChar(NameValueSeparator);
{$ENDIF}
TStrings(Dest).QuoteChar := AnsiChar(QuoteChar);
TStrings(Dest).Delimiter := AnsiChar(Delimiter);
for I := 0 to Count - 1 do
TStrings(Dest).AddObject(Strings[I], Objects[I]);
finally
TStrings(Dest).EndUpdate;
end;
end
else
inherited AssignTo(Dest);
end;
procedure TWideStrings.BeginUpdate;
begin
if FUpdateCount = 0 then SetUpdateState(True);
Inc(FUpdateCount);
end;
procedure TWideStrings.DefineProperties(Filer: TFiler);
function DoWrite: Boolean;
begin
if Filer.Ancestor <> nil then
begin
Result := True;
if Filer.Ancestor is TWideStrings then
Result := not Equals(TWideStrings(Filer.Ancestor))
end
else Result := Count > 0;
end;
begin
Filer.DefineProperty('Strings', ReadData, WriteData, DoWrite);
end;
procedure TWideStrings.EndUpdate;
begin
Dec(FUpdateCount);
if FUpdateCount = 0 then SetUpdateState(False);
end;
function TWideStrings.Equals(Strings: TWideStrings): Boolean;
var
I, Count: Integer;
begin
Result := False;
Count := GetCount;
if Count <> Strings.GetCount then Exit;
for I := 0 to Count - 1 do if Get(I) <> Strings.Get(I) then Exit;
Result := True;
end;
procedure TWideStrings.Error(const Msg: WideString; Data: Integer);
function ReturnAddr: Pointer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -