{ ----------------------------------- 2003/06/15 GetTextメソッドが大分古い形式だったので Winの#13#10だけから#13、#10単独での場合も動作するように改造した MyStringRecordListのものを修正コピーした //----------------------------------- } unit StringClassList; interface uses StringUnit, ListClone, ConstUnit, MathUnit, uses_end; type TStringClass = class(TObject) private FItem: String; public constructor Create; overload; constructor Create(const S: String); overload; property Item: String read FItem write FItem; end; TClassListItem = TStringClass; //////////////////////////////////////////////////////////// {$include ClassList.inc.pas} //////////////////////////////////////////////////////////// TDelimitedTextFlag = set of (dtfIncludeDelimiter); //TStringClassList = TMyClassList; TStringClassList = class(TClassList) protected procedure SetText(const Value: String); function GetText: String; procedure SetBaseText(const Value: String; Delimiters: array of String; Flag: TDelimitedTextFlag); public procedure SetDelimitedText(const Value: String; Delimiters: array of String); property Text: String read GetText write SetText; end; implementation const EmptyStr: string = ''; //////////////////////////////////////////////////////////// {$include ClassList.inc.pas} //////////////////////////////////////////////////////////// { TStringClassList } {---------------------------------------- function TStringClassList.GetText: String; var i: Integer; begin Result := ''; for i := 0 to Self.Count-1 do begin Result := Result + Self.Items[i].Item; end; end; //----------------------------------------} function TStringClassList.GetText: String; var StringLength, ResultIndex: Integer; i, j: Integer; begin StringLength := 0; for i := 0 to Self.Count - 1 do begin Inc(StringLength, Length(Self.Items[i].Item)); end; SetLength(Result, StringLength); ResultIndex := 1; for i := 0 to Self.Count - 1 do begin for j := 1 to Length(Self.Items[i].Item) do begin Result[ResultIndex] := Self.Items[i].Item[j]; Inc(ResultIndex); end; end; end; procedure TStringClassList.SetText(const Value: String); const LineBreakStrs: array[0..2] of String = (#13#10, #13, #10); {↑#13#10,#13,#10の順番だから、CRLFを見つけて区切り CRかLFに一致しない場合にCRかLFで判定して区切る事ができる #13,#10,#13#10などという並びではいけない} begin SetBaseText(Value, LineBreakStrs, [dtfIncludeDelimiter]); end; procedure TStringClassList.SetBaseText(const Value: String; Delimiters: array of String; Flag: TDelimitedTextFlag); var i, j, Len, StrStartIndex, StrEndIndex: Integer; Delimiter: String; StrClass1: TStringClass; begin Self.Clear; if Value = EmptyStr then begin Exit; end; Len := Length(Value); StrStartIndex := 1; StrEndIndex := 0; i := 1; while (i <= Len) do begin Delimiter := ''; for j := Low(Delimiters) to High(Delimiters) do begin if StringPartsCompare(Delimiters[j], Value, i, ccCaseSensitive) then begin Delimiter := Delimiters[j]; break; end; end; if Delimiter <> '' Then begin //動作の詳細についてのコメントは //CommonStringRecordList.inc.pasを参照のこと if (dtfIncludeDelimiter in Flag) then begin StrEndIndex := i + Length(Delimiter) - 1; StrClass1 := TStringClass.Create; StrClass1.Item := CopyIndex(Value, StrStartIndex, StrEndIndex); Self.Add(StrClass1); i := StrEndIndex + 1; StrStartIndex := i; end else begin StrEndIndex := i - 1; StrClass1 := TStringClass.Create; StrClass1.Item := CopyIndex(Value, StrStartIndex, StrEndIndex); Self.Add(StrClass1); i := i + Length(Delimiter); StrStartIndex := i; end; end else begin StrEndIndex := i; Inc(i); end; end; if 1 <= StrEndIndex-StrStartIndex + 1 then begin StrClass1 := TStringClass.Create; StrClass1.Item := CopyIndex(Value, StrStartIndex, StrEndIndex); Self.Add(StrClass1); end; end; {---------------------------------------- procedure TStringClassList.SetText(const Value: String); const LineBreakStrs: array[0..2] of String = (#13#10, #13, #10); var i, j, Len, StrStartIndex, StrEndIndex: Integer; LineBreakStr: String; StrClass1: TStringClass; begin Self.Clear; if Value = EmptyStr then begin Exit; end; Len := Length(Value); StrStartIndex := 1; StrEndIndex := 0; i := 1; while (i <= Len) do begin LineBreakStr := ''; for j := Low(LineBreakStrs) to High(LineBreakStrs) do begin if AnsiStringPartsCompare(LineBreakStrs[j], Value, i) then begin LineBreakStr := LineBreakStrs[j]; break; end; end; if LineBreakStr <> '' Then begin StrEndIndex := i + length(LineBreakStr)-1; StrClass1 := TStringClass.Create; StrClass1.Item := Copy(Value, StrStartIndex, StrEndIndex-StrStartIndex+1); Self.Add(StrClass1); i := StrEndIndex + 1; StrStartIndex := i; end else begin StrEndIndex := i; Inc(i); end; end; if 1 <= StrEndIndex-StrStartIndex+1 then begin StrClass1 := TStringClass.Create; StrClass1.Item := Copy(Value, StrStartIndex, StrEndIndex-StrStartIndex+1); Self.Add(StrClass1); end; end; //----------------------------------------} procedure TStringClassList.SetDelimitedText(const Value: String; Delimiters: array of String); begin SetBaseText(Value, Delimiters, []); end; { TStringClass } constructor TStringClass.Create(const S: String); begin inherited Create; FItem := S; end; constructor TStringClass.Create; begin inherited; end; initialization finalization end.