昨天装了个D2010,发现2010中的StringBuilder对象用的比较爽快!于是稍作了一些修改(增加了几个函数和属性)然后移植到D2007中来使用了!效果不错,共享一下!
代码
unit
DxStringBuilder;
interface
uses RTLConsts,Classes,SysUtils;
type
EExternal = class (Exception)
public
{ $IFDEF MSWINDOWS }
ExceptionRecord: PExceptionRecord platform;
{ $ENDIF }
{ $IF defined(LINUX) or defined(MACOSX) }
ExceptionAddress: LongWord platform;
AccessAddress: LongWord platform;
SignalNumber: Integer platform;
{ $IFEND LINUX or MACOSX }
end ;
EIntError = class (EExternal);
ERangeError = class (EIntError);
TCharArray = array of Char;
TStringBuilder = class
private
const DefaultCapacity = $ 10 ;
function GetCapacity: Integer;
procedure SetCapacity( const Value: Integer);
function GetLength: Integer;
procedure Set_Length( const Value: Integer);
function GetMaxCapacity: Integer;
procedure ReduceCapacity;
procedure ExpandCapacity;
procedure CheckBounds(Index: Integer);
function _Replace(Index: Integer; const Old, New: string ): Boolean;
function GetChars(index: Integer): Char;
procedure SetChars(index: Integer; const Value: Char);
protected
FData: TCharArray;
FLength: Integer;
FMaxCapacity: Integer;
public
constructor Create; overload ;
constructor Create(aCapacity: Integer); overload ;
constructor Create( const Value: string ); overload ;
function Append( const Value: Boolean): TStringBuilder; overload ;
function Append( const Value: Byte): TStringBuilder; overload ;
function Append( const Value: Char): TStringBuilder; overload ;
function Append( const Value: Currency): TStringBuilder; overload ;
function Append( const Value: Double): TStringBuilder; overload ;
function Append( const Value: Smallint): TStringBuilder; overload ;
function Append( const Value: Integer): TStringBuilder; overload ;
function Append( const Value: Int64): TStringBuilder; overload ;
function Append( const Value: TObject): TStringBuilder; overload ;
function Append( const Value: Shortint): TStringBuilder; overload ;
function Append( const Value: Single): TStringBuilder; overload ;
function Append( const Value: string ): TStringBuilder; overload ;
function Append( const Value: UInt64): TStringBuilder; overload ;
function Append( const Value: TCharArray): TStringBuilder; overload ;
function Append( const Value: Word): TStringBuilder; overload ;
function Append( const Value: Cardinal): TStringBuilder; overload ;
function Append( const Value: Char; RepeatCount: Integer): TStringBuilder; overload ;
function Append( const Value: TCharArray; StartIndex: Integer; CharCount: Integer): TStringBuilder; overload ;
function Append( const Value: string ; StartIndex: Integer; Count: Integer): TStringBuilder; overload ;
function AppendFormat( const Format: string ; const Args: array of const ): TStringBuilder; overload ;
function AppendLine: TStringBuilder; overload ;
function AppendLine( const Value: string ): TStringBuilder; overload ;
procedure Clear;
procedure CopyTo(SourceIndex: Integer; const Destination: TCharArray; DestinationIndex: Integer; Count: Integer);
function EnsureCapacity(aCapacity: Integer): Integer;
function Equals(StringBuilder: TStringBuilder): Boolean; reintroduce ;
function Insert(Index: Integer; const Value: Boolean): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Byte): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Char): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Currency): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Double): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Smallint): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Integer): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: TCharArray): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Int64): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: TObject): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Shortint): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Single): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: string ): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Word): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Cardinal): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: UInt64): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: string ; count: Integer): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: TCharArray; startIndex: Integer; charCount: Integer): TStringBuilder; overload ;
function Remove(StartIndex: Integer; RemLength: Integer): TStringBuilder;
function Replace( const OldChar: Char; const NewChar: Char): TStringBuilder; overload ;
function Replace( const OldValue: string ; const NewValue: string ): TStringBuilder; overload ;
function Replace( const OldChar: Char; const NewChar: Char; StartIndex: Integer; Count: Integer): TStringBuilder; overload ;
function Replace( const OldValue: string ; const NewValue: string ; StartIndex: Integer; Count: Integer): TStringBuilder; overload ;
function ToString: string ; overload ;
function ToString(StartIndex: Integer; StrLength: Integer): string ; reintroduce ; overload ;
procedure SaveToStream(Stream: TStream);
procedure SaveToFile(FileName: string );
procedure LoadFromStream(Stream: TStream);
procedure LoadFromFile(FileName: string );
property Capacity: Integer read GetCapacity write SetCapacity;
property Chars[index: Integer]: Char read GetChars write SetChars; default ;
property Length: Integer read GetLength write Set_Length;
property MaxCapacity: Integer read GetMaxCapacity;
end ;
function UIntToStr(Value: Cardinal): string ; overload ;
function UIntToStr(Value: UInt64): string ; overload ;
resourcestring
SParamIsNegative = ' Parameter %s cannot be a negative value ' ;
SInputBufferExceed = ' Input buffer exceeded for %s = %d, %s = %d ' ;
implementation
function UIntToStr(Value: Cardinal): string ;
begin
FmtStr(Result, ' %u ' , [Value]);
end ;
function UIntToStr(Value: UInt64): string ;
begin
FmtStr(Result, ' %u ' , [Value]);
end ;
{ TStringBuilder }
constructor TStringBuilder.Create;
begin
inherited Create;
FMaxCapacity : = MaxInt;
Capacity : = DefaultCapacity;
FLength : = 0 ;
end ;
constructor TStringBuilder.Create(aCapacity: Integer);
begin
inherited Create;
FMaxCapacity : = MaxInt;
Capacity : = aCapacity;
FLength : = 0 ;
end ;
function TStringBuilder.Append( const Value: string ): TStringBuilder;
begin
Length : = Length + System.Length(Value);
Move(PChar(Value)^, FData[Length - System.Length(Value)], System.Length(Value) * SizeOf(Char));
Result : = self;
end ;
function TStringBuilder.Append( const Value: Currency): TStringBuilder;
begin
Append(CurrToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Double): TStringBuilder;
begin
Append(FloatToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Char): TStringBuilder;
begin
Length : = Length + 1 ;
FData[Length - 1 ] : = Value;
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Boolean): TStringBuilder;
begin
Append(BoolToStr(Value, True));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Byte): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Smallint): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Shortint): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Single): TStringBuilder;
begin
Append(FloatToStr(Value));
Result : = self;
end ;
function TStringBuilder.Append( const Value: TObject): TStringBuilder;
begin
{ $if CompilerVersion >= 19 }
Append(Value.ToString());
{ $else }
if Value.InheritsFrom(TComponent) then
Append(TComponent(Value).Name + ' : ' + Value.ClassName)
else Append(Value.ClassName);
{ $ifend }
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Integer): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Int64): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
procedure TStringBuilder.CheckBounds(Index: Integer);
begin
if Cardinal(Index) >= Cardinal(Length) then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
end ;
procedure TStringBuilder.Clear;
begin
Length : = 0 ;
Capacity : = DefaultCapacity;
end ;
procedure TStringBuilder.CopyTo(SourceIndex: Integer;
const Destination: TCharArray; DestinationIndex, Count: Integer);
begin
if Count < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Count ' ]); // DO NOT LOCALIZE
if DestinationIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' DestinationIndex ' ]); // DO NOT LOCALIZE
if DestinationIndex + Count > System.Length(Destination) then
raise ERangeError.CreateResFmt(@SInputBufferExceed,
[ ' DestinationIndex ' , DestinationIndex, ' Count ' , Count]);
if Count > 0 then
begin
CheckBounds(SourceIndex);
CheckBounds(SourceIndex + Count - 1 );
Move(FData[SourceIndex], Destination[DestinationIndex], Count * SizeOf(Char));
end ;
end ;
constructor TStringBuilder.Create( const Value: string );
begin
Create;
Append(Value);
end ;
function TStringBuilder.EnsureCapacity(aCapacity: Integer): Integer;
begin
if Cardinal(aCapacity) > Cardinal(MaxCapacity) then
raise ERangeError.CreateResFmt(@SListIndexError, [aCapacity]);
if Capacity < aCapacity then
Capacity : = aCapacity;
Result : = Capacity;
end ;
function TStringBuilder.Equals(StringBuilder: TStringBuilder): Boolean;
begin
Result : = (StringBuilder <> nil ) and (Length = StringBuilder.Length) and
(MaxCapacity = StringBuilder.MaxCapacity) and
CompareMem(@FData[ 0 ], @StringBuilder.FData[ 0 ], Length * SizeOf(Char));
end ;
procedure TStringBuilder.ExpandCapacity;
var
NewCapacity: Integer;
begin
NewCapacity : = Capacity * 2 ;
if Length > NewCapacity then
NewCapacity : = Length * 2 ; // this line may overflow NewCapacity to a negative value
if NewCapacity > MaxCapacity then
NewCapacity : = MaxCapacity;
if NewCapacity < 0 then // if NewCapacity has been overflowed
NewCapacity : = Length;
Capacity : = NewCapacity;
end ;
function TStringBuilder.GetCapacity: Integer;
begin
Result : = System.Length(FData);
end ;
function TStringBuilder.GetChars(index: Integer): Char;
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
CheckBounds(Index);
Result : = FData[Index];
end ;
function TStringBuilder.GetLength: Integer;
begin
Result : = FLength;
end ;
function TStringBuilder.GetMaxCapacity: Integer;
begin
Result : = FMaxCapacity;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Integer): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Smallint): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Int64): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: TCharArray): TStringBuilder;
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
if Index > Length then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
Length : = Length + System.Length(Value);
Move(FData[Index], FData[Index + System.Length(Value)], System.Length(Value) * SizeOf(Char));
Move(Value[ 0 ], FData[Index], System.Length(Value) * SizeOf(Char));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Double): TStringBuilder;
begin
Insert(Index, FloatToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Byte): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Boolean): TStringBuilder;
begin
Insert(Index, BoolToStr(Value, True));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Currency): TStringBuilder;
begin
Insert(Index, CurrToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Char): TStringBuilder;
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
if Index > Length then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
Length : = Length + 1 ;
Move(FData[Index], FData[Index + 1 ], (Length - Index - 1 ) * SizeOf(Char));
FData[Index] : = Value;
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: UInt64): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Cardinal): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Insert(Index: Integer; const Value: TCharArray;
startIndex, charCount: Integer): TStringBuilder;
begin
if Index - 1 >= Length then
raise ERangeError.CreateResFmt(@SListIndexError, [Index])
else if Index < 0 then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if CharCount < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' CharCount ' ]); // DO NOT LOCALIZE
if StartIndex + CharCount > System.Length(Value) then
raise ERangeError.CreateResFmt(@SInputBufferExceed,
[ ' StartIndex ' , StartIndex, ' CharCount ' , CharCount]);
Length : = Length + CharCount;
if Length - Index > 0 then
Move(FData[Index], FData[Index + CharCount], (Length - Index) * SizeOf(Char));
Move(Value[StartIndex], FData[Index], CharCount * SizeOf(Char));
Result : = Self;
end ;
procedure TStringBuilder.LoadFromFile(FileName: string );
var
F: TFileStream;
begin
F : = TFileStream.Create(FileName,fmOpenRead);
LoadFromStream(F);
F.Free;
end ;
procedure TStringBuilder.LoadFromStream(Stream: TStream);
begin
Capacity : = Stream.Size;
Stream.Position : = 0 ;
Stream.ReadBuffer(FData[ 0 ],Stream.Size);
Length : = Stream.Size;
end ;
procedure TStringBuilder.ReduceCapacity;
var
NewCapacity: Integer;
begin
if Length > Capacity div 4 then
Exit;
NewCapacity : = Capacity div 2 ;
if NewCapacity < Length then
NewCapacity : = Length;
Capacity : = NewCapacity;
end ;
function TStringBuilder.Remove(StartIndex, RemLength: Integer): TStringBuilder;
begin
if RemLength <> 0 then
begin
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if RemLength < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' RemLength ' ]); // DO NOT LOCALIZE
CheckBounds(StartIndex);
CheckBounds(StartIndex + RemLength - 1 );
if (Length - (StartIndex + RemLength)) > 0 then
Move(FData[StartIndex + RemLength], FData[StartIndex], (Length - (StartIndex + RemLength)) * SizeOf(Char));
Length : = Length - RemLength;
ReduceCapacity;
end ;
Result : = Self;
end ;
function TStringBuilder.Replace( const OldValue,
NewValue: string ): TStringBuilder;
begin
Result : = self;
Replace(OldValue, NewValue, 0 , Length);
end ;
function TStringBuilder.Replace( const OldChar, NewChar: Char): TStringBuilder;
var
Ptr: PChar;
EndPtr: PChar;
begin
EndPtr : = @FData[Length - 1 ];
Ptr : = @FData[ 0 ];
while Ptr <= EndPtr do
begin
if Ptr^ = OldChar then
Ptr^ : = NewChar;
Inc(Ptr);
end ;
Result : = Self;
end ;
function TStringBuilder.Replace( const OldValue, NewValue: string ; StartIndex,
Count: Integer): TStringBuilder;
var
CurPtr: PChar;
EndPtr: PChar;
Index: Integer;
EndIndex: Integer;
oldLen, newLen: Integer;
begin
Result : = Self;
if Count <> 0 then
begin
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if Count < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Count ' ]); // DO NOT LOCALIZE
if StartIndex + Count > Length then
raise ERangeError.CreateResFmt(@SInputBufferExceed,
[ ' StartIndex ' , StartIndex, ' Count ' , Count]);
oldLen : = System.Length(OldValue);
newLen : = System.Length(NewValue);
Index : = StartIndex;
CurPtr : = @FData[StartIndex];
EndIndex : = StartIndex + Count - oldLen;
EndPtr : = @FData[EndIndex];
while CurPtr <= EndPtr do
begin
if CurPtr^ = OldValue[ 1 ] then
begin
if StrLComp(CurPtr, PChar(OldValue), oldLen) = 0 then
begin
if _Replace(Index, OldValue, NewValue) then
begin
CurPtr : = @FData[Index];
EndPtr : = @FData[EndIndex];
end ;
Inc(CurPtr, newLen - 1 );
Inc(Index, newLen - 1 );
Inc(EndPtr, newLen - oldLen);
Inc(EndIndex, newLen - oldLen);
end ;
end ;
Inc(CurPtr);
Inc(Index);
end ;
end ;
end ;
function TStringBuilder.Replace( const OldChar, NewChar: Char; StartIndex,
Count: Integer): TStringBuilder;
var
Ptr: PChar;
EndPtr: PChar;
begin
if Count <> 0 then
begin
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if Count < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Count ' ]); // DO NOT LOCALIZE
CheckBounds(StartIndex);
CheckBounds(StartIndex + Count - 1 );
EndPtr : = @FData[StartIndex + Count - 1 ];
Ptr : = @FData[StartIndex];
while Ptr <= EndPtr do
begin
if Ptr^ = OldChar then
Ptr^ : = NewChar;
Inc(Ptr);
end ;
end ;
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer; const Value: string ;
count: Integer): TStringBuilder;
var
I: Integer;
begin
for I : = 0 to Count - 1 do
Insert(Index, Value);
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Word): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Shortint): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: TObject): TStringBuilder;
begin
{ $if CompilerVersion >= 19 }
Insert(Index, Value.ToString());
{ $else }
Insert(Index, IntToStr(Integer(Value)));
{ $ifend }
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: string ): TStringBuilder;
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
if Index > Length then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
Length : = Length + System.Length(Value);
Move(FData[Index], FData[Index + System.Length(Value)], (Length - System.Length(Value) - Index) * SizeOf(Char));
Move(Value[ 1 ], FData[Index], System.Length(Value) * SizeOf(Char));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Single): TStringBuilder;
begin
Insert(Index, FloatToStr(Value));
Result : = Self;
end ;
procedure TStringBuilder.SaveToFile(FileName: string );
var
FileStream: TFileStream;
begin
FileStream : = TFileStream.Create(FileName,fmOpenWrite);
SaveToStream(FileStream);
FileStream.Free;
end ;
procedure TStringBuilder.SaveToStream(Stream: TStream);
begin
Stream.WriteBuffer(FData[ 0 ],Length * SizeOf(Char));
end ;
procedure TStringBuilder.SetCapacity( const Value: Integer);
begin
if Value < Length then
raise ERangeError.CreateResFmt(@SListCapacityError, [Value]);
if Value > FMaxCapacity then
raise ERangeError.CreateResFmt(@SListCapacityError, [Value]);
SetLength(FData, Value);
end ;
procedure TStringBuilder.SetChars(index: Integer; const Value: Char);
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
CheckBounds(Index);
FData[Index] : = Value;
end ;
procedure TStringBuilder.Set_Length( const Value: Integer);
var
LOldLength: Integer;
begin
if Value < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Value ' ]); // DO NOT LOCALIZE
if Value > MaxCapacity then
raise ERangeError.CreateResFmt(@SListCapacityError, [Value]);
LOldLength : = FLength;
try
FLength : = Value;
if FLength > Capacity then
ExpandCapacity;
except
on E: EOutOfMemory do
FLength : = LOldLength;
end ;
end ;
function TStringBuilder.ToString: string ;
begin
SetLength(Result, Length);
Move(FData[ 0 ], Result[ 1 ], Length * SizeOf(Char));
end ;
function TStringBuilder.ToString(StartIndex, StrLength: Integer): string ;
begin
if StrLength <> 0 then
begin
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if StrLength < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StrLength ' ]); // DO NOT LOCALIZE
CheckBounds(StartIndex);
CheckBounds(StartIndex + StrLength - 1 );
SetLength(Result, StrLength);
Move(FData[StartIndex], Result[ 1 ], StrLength * SizeOf(Char));
end
else Result : = '' ;
end ;
function TStringBuilder._Replace(Index: Integer; const Old,
New: string ): Boolean;
var
OldCapacity: Integer;
SizeChange: Integer;
begin
Result : = False;
SizeChange : = System.Length(New) - System.Length(Old);
if SizeChange = 0 then
begin
Move(New[ 1 ], FData[Index], System.Length(New) * SizeOf(Char));
end
else
begin
if SizeChange > 0 then
begin
OldCapacity : = Capacity;
Length : = Length + SizeChange;
if OldCapacity <> Capacity then
Result : = True;
end ;
Move(FData[Index + System.Length(Old)], FData[Index + System.Length(New)], (Length - (System.Length(Old) + Index)) * SizeOf(Char));
Move(New[ 1 ], FData[Index], System.Length(New) * SizeOf(Char));
if SizeChange < 0 then
Length : = Length + SizeChange;
end ;
end ;
function TStringBuilder.Append( const Value: Word): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Append( const Value: TCharArray): TStringBuilder;
var
I: Integer;
begin
Result : = self;
for I : = 0 to System.Length(Value) - 1 do
if Value[I] = # 0 then
Break;
Append(Value, 0 , I);
end ;
function TStringBuilder.Append( const Value: UInt64): TStringBuilder;
begin
Append(UIntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Append( const Value: Cardinal): TStringBuilder;
begin
Append(UIntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Append( const Value: string ; StartIndex,
Count: Integer): TStringBuilder;
begin
if StartIndex + Count > System.Length(Value) then
raise ERangeError.CreateResFmt(@SListIndexError, [StartIndex]);
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SListIndexError, [StartIndex]);
Length : = Length + Count;
Move(Value[StartIndex + 1 ], FData[Length - Count], Count * SizeOf(Char));
Result : = Self;
end ;
function TStringBuilder.AppendFormat( const Format: string ;
const Args: array of const ): TStringBuilder;
begin
Append(SysUtils.Format(Format, Args));
Result : = Self;
end ;
function TStringBuilder.AppendLine: TStringBuilder;
begin
Append(sLineBreak);
Result : = Self;
end ;
function TStringBuilder.AppendLine( const Value: string ): TStringBuilder;
begin
Append(Value);
AppendLine;
Result : = Self;
end ;
function TStringBuilder.Append( const Value: TCharArray; StartIndex,
CharCount: Integer): TStringBuilder;
begin
if StartIndex + CharCount > System.Length(Value) then
raise ERangeError.CreateResFmt(@SListIndexError, [StartIndex]);
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SListIndexError, [StartIndex]);
Length : = Length + CharCount;
Move(Value[StartIndex], FData[Length - CharCount], CharCount * SizeOf(Char));
Result : = self;
end ;
function TStringBuilder.Append( const Value: Char;
RepeatCount: Integer): TStringBuilder;
begin
Append(System.StringOfChar(Value, RepeatCount));
Result : = Self;
end ;
end .
interface
uses RTLConsts,Classes,SysUtils;
type
EExternal = class (Exception)
public
{ $IFDEF MSWINDOWS }
ExceptionRecord: PExceptionRecord platform;
{ $ENDIF }
{ $IF defined(LINUX) or defined(MACOSX) }
ExceptionAddress: LongWord platform;
AccessAddress: LongWord platform;
SignalNumber: Integer platform;
{ $IFEND LINUX or MACOSX }
end ;
EIntError = class (EExternal);
ERangeError = class (EIntError);
TCharArray = array of Char;
TStringBuilder = class
private
const DefaultCapacity = $ 10 ;
function GetCapacity: Integer;
procedure SetCapacity( const Value: Integer);
function GetLength: Integer;
procedure Set_Length( const Value: Integer);
function GetMaxCapacity: Integer;
procedure ReduceCapacity;
procedure ExpandCapacity;
procedure CheckBounds(Index: Integer);
function _Replace(Index: Integer; const Old, New: string ): Boolean;
function GetChars(index: Integer): Char;
procedure SetChars(index: Integer; const Value: Char);
protected
FData: TCharArray;
FLength: Integer;
FMaxCapacity: Integer;
public
constructor Create; overload ;
constructor Create(aCapacity: Integer); overload ;
constructor Create( const Value: string ); overload ;
function Append( const Value: Boolean): TStringBuilder; overload ;
function Append( const Value: Byte): TStringBuilder; overload ;
function Append( const Value: Char): TStringBuilder; overload ;
function Append( const Value: Currency): TStringBuilder; overload ;
function Append( const Value: Double): TStringBuilder; overload ;
function Append( const Value: Smallint): TStringBuilder; overload ;
function Append( const Value: Integer): TStringBuilder; overload ;
function Append( const Value: Int64): TStringBuilder; overload ;
function Append( const Value: TObject): TStringBuilder; overload ;
function Append( const Value: Shortint): TStringBuilder; overload ;
function Append( const Value: Single): TStringBuilder; overload ;
function Append( const Value: string ): TStringBuilder; overload ;
function Append( const Value: UInt64): TStringBuilder; overload ;
function Append( const Value: TCharArray): TStringBuilder; overload ;
function Append( const Value: Word): TStringBuilder; overload ;
function Append( const Value: Cardinal): TStringBuilder; overload ;
function Append( const Value: Char; RepeatCount: Integer): TStringBuilder; overload ;
function Append( const Value: TCharArray; StartIndex: Integer; CharCount: Integer): TStringBuilder; overload ;
function Append( const Value: string ; StartIndex: Integer; Count: Integer): TStringBuilder; overload ;
function AppendFormat( const Format: string ; const Args: array of const ): TStringBuilder; overload ;
function AppendLine: TStringBuilder; overload ;
function AppendLine( const Value: string ): TStringBuilder; overload ;
procedure Clear;
procedure CopyTo(SourceIndex: Integer; const Destination: TCharArray; DestinationIndex: Integer; Count: Integer);
function EnsureCapacity(aCapacity: Integer): Integer;
function Equals(StringBuilder: TStringBuilder): Boolean; reintroduce ;
function Insert(Index: Integer; const Value: Boolean): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Byte): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Char): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Currency): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Double): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Smallint): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Integer): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: TCharArray): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Int64): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: TObject): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Shortint): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Single): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: string ): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Word): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: Cardinal): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: UInt64): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: string ; count: Integer): TStringBuilder; overload ;
function Insert(Index: Integer; const Value: TCharArray; startIndex: Integer; charCount: Integer): TStringBuilder; overload ;
function Remove(StartIndex: Integer; RemLength: Integer): TStringBuilder;
function Replace( const OldChar: Char; const NewChar: Char): TStringBuilder; overload ;
function Replace( const OldValue: string ; const NewValue: string ): TStringBuilder; overload ;
function Replace( const OldChar: Char; const NewChar: Char; StartIndex: Integer; Count: Integer): TStringBuilder; overload ;
function Replace( const OldValue: string ; const NewValue: string ; StartIndex: Integer; Count: Integer): TStringBuilder; overload ;
function ToString: string ; overload ;
function ToString(StartIndex: Integer; StrLength: Integer): string ; reintroduce ; overload ;
procedure SaveToStream(Stream: TStream);
procedure SaveToFile(FileName: string );
procedure LoadFromStream(Stream: TStream);
procedure LoadFromFile(FileName: string );
property Capacity: Integer read GetCapacity write SetCapacity;
property Chars[index: Integer]: Char read GetChars write SetChars; default ;
property Length: Integer read GetLength write Set_Length;
property MaxCapacity: Integer read GetMaxCapacity;
end ;
function UIntToStr(Value: Cardinal): string ; overload ;
function UIntToStr(Value: UInt64): string ; overload ;
resourcestring
SParamIsNegative = ' Parameter %s cannot be a negative value ' ;
SInputBufferExceed = ' Input buffer exceeded for %s = %d, %s = %d ' ;
implementation
function UIntToStr(Value: Cardinal): string ;
begin
FmtStr(Result, ' %u ' , [Value]);
end ;
function UIntToStr(Value: UInt64): string ;
begin
FmtStr(Result, ' %u ' , [Value]);
end ;
{ TStringBuilder }
constructor TStringBuilder.Create;
begin
inherited Create;
FMaxCapacity : = MaxInt;
Capacity : = DefaultCapacity;
FLength : = 0 ;
end ;
constructor TStringBuilder.Create(aCapacity: Integer);
begin
inherited Create;
FMaxCapacity : = MaxInt;
Capacity : = aCapacity;
FLength : = 0 ;
end ;
function TStringBuilder.Append( const Value: string ): TStringBuilder;
begin
Length : = Length + System.Length(Value);
Move(PChar(Value)^, FData[Length - System.Length(Value)], System.Length(Value) * SizeOf(Char));
Result : = self;
end ;
function TStringBuilder.Append( const Value: Currency): TStringBuilder;
begin
Append(CurrToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Double): TStringBuilder;
begin
Append(FloatToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Char): TStringBuilder;
begin
Length : = Length + 1 ;
FData[Length - 1 ] : = Value;
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Boolean): TStringBuilder;
begin
Append(BoolToStr(Value, True));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Byte): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Smallint): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Shortint): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Single): TStringBuilder;
begin
Append(FloatToStr(Value));
Result : = self;
end ;
function TStringBuilder.Append( const Value: TObject): TStringBuilder;
begin
{ $if CompilerVersion >= 19 }
Append(Value.ToString());
{ $else }
if Value.InheritsFrom(TComponent) then
Append(TComponent(Value).Name + ' : ' + Value.ClassName)
else Append(Value.ClassName);
{ $ifend }
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Integer): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Append( const Value: Int64): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = Self;
end ;
procedure TStringBuilder.CheckBounds(Index: Integer);
begin
if Cardinal(Index) >= Cardinal(Length) then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
end ;
procedure TStringBuilder.Clear;
begin
Length : = 0 ;
Capacity : = DefaultCapacity;
end ;
procedure TStringBuilder.CopyTo(SourceIndex: Integer;
const Destination: TCharArray; DestinationIndex, Count: Integer);
begin
if Count < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Count ' ]); // DO NOT LOCALIZE
if DestinationIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' DestinationIndex ' ]); // DO NOT LOCALIZE
if DestinationIndex + Count > System.Length(Destination) then
raise ERangeError.CreateResFmt(@SInputBufferExceed,
[ ' DestinationIndex ' , DestinationIndex, ' Count ' , Count]);
if Count > 0 then
begin
CheckBounds(SourceIndex);
CheckBounds(SourceIndex + Count - 1 );
Move(FData[SourceIndex], Destination[DestinationIndex], Count * SizeOf(Char));
end ;
end ;
constructor TStringBuilder.Create( const Value: string );
begin
Create;
Append(Value);
end ;
function TStringBuilder.EnsureCapacity(aCapacity: Integer): Integer;
begin
if Cardinal(aCapacity) > Cardinal(MaxCapacity) then
raise ERangeError.CreateResFmt(@SListIndexError, [aCapacity]);
if Capacity < aCapacity then
Capacity : = aCapacity;
Result : = Capacity;
end ;
function TStringBuilder.Equals(StringBuilder: TStringBuilder): Boolean;
begin
Result : = (StringBuilder <> nil ) and (Length = StringBuilder.Length) and
(MaxCapacity = StringBuilder.MaxCapacity) and
CompareMem(@FData[ 0 ], @StringBuilder.FData[ 0 ], Length * SizeOf(Char));
end ;
procedure TStringBuilder.ExpandCapacity;
var
NewCapacity: Integer;
begin
NewCapacity : = Capacity * 2 ;
if Length > NewCapacity then
NewCapacity : = Length * 2 ; // this line may overflow NewCapacity to a negative value
if NewCapacity > MaxCapacity then
NewCapacity : = MaxCapacity;
if NewCapacity < 0 then // if NewCapacity has been overflowed
NewCapacity : = Length;
Capacity : = NewCapacity;
end ;
function TStringBuilder.GetCapacity: Integer;
begin
Result : = System.Length(FData);
end ;
function TStringBuilder.GetChars(index: Integer): Char;
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
CheckBounds(Index);
Result : = FData[Index];
end ;
function TStringBuilder.GetLength: Integer;
begin
Result : = FLength;
end ;
function TStringBuilder.GetMaxCapacity: Integer;
begin
Result : = FMaxCapacity;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Integer): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Smallint): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Int64): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: TCharArray): TStringBuilder;
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
if Index > Length then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
Length : = Length + System.Length(Value);
Move(FData[Index], FData[Index + System.Length(Value)], System.Length(Value) * SizeOf(Char));
Move(Value[ 0 ], FData[Index], System.Length(Value) * SizeOf(Char));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Double): TStringBuilder;
begin
Insert(Index, FloatToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Byte): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Boolean): TStringBuilder;
begin
Insert(Index, BoolToStr(Value, True));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Currency): TStringBuilder;
begin
Insert(Index, CurrToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Char): TStringBuilder;
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
if Index > Length then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
Length : = Length + 1 ;
Move(FData[Index], FData[Index + 1 ], (Length - Index - 1 ) * SizeOf(Char));
FData[Index] : = Value;
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: UInt64): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Cardinal): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Insert(Index: Integer; const Value: TCharArray;
startIndex, charCount: Integer): TStringBuilder;
begin
if Index - 1 >= Length then
raise ERangeError.CreateResFmt(@SListIndexError, [Index])
else if Index < 0 then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if CharCount < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' CharCount ' ]); // DO NOT LOCALIZE
if StartIndex + CharCount > System.Length(Value) then
raise ERangeError.CreateResFmt(@SInputBufferExceed,
[ ' StartIndex ' , StartIndex, ' CharCount ' , CharCount]);
Length : = Length + CharCount;
if Length - Index > 0 then
Move(FData[Index], FData[Index + CharCount], (Length - Index) * SizeOf(Char));
Move(Value[StartIndex], FData[Index], CharCount * SizeOf(Char));
Result : = Self;
end ;
procedure TStringBuilder.LoadFromFile(FileName: string );
var
F: TFileStream;
begin
F : = TFileStream.Create(FileName,fmOpenRead);
LoadFromStream(F);
F.Free;
end ;
procedure TStringBuilder.LoadFromStream(Stream: TStream);
begin
Capacity : = Stream.Size;
Stream.Position : = 0 ;
Stream.ReadBuffer(FData[ 0 ],Stream.Size);
Length : = Stream.Size;
end ;
procedure TStringBuilder.ReduceCapacity;
var
NewCapacity: Integer;
begin
if Length > Capacity div 4 then
Exit;
NewCapacity : = Capacity div 2 ;
if NewCapacity < Length then
NewCapacity : = Length;
Capacity : = NewCapacity;
end ;
function TStringBuilder.Remove(StartIndex, RemLength: Integer): TStringBuilder;
begin
if RemLength <> 0 then
begin
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if RemLength < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' RemLength ' ]); // DO NOT LOCALIZE
CheckBounds(StartIndex);
CheckBounds(StartIndex + RemLength - 1 );
if (Length - (StartIndex + RemLength)) > 0 then
Move(FData[StartIndex + RemLength], FData[StartIndex], (Length - (StartIndex + RemLength)) * SizeOf(Char));
Length : = Length - RemLength;
ReduceCapacity;
end ;
Result : = Self;
end ;
function TStringBuilder.Replace( const OldValue,
NewValue: string ): TStringBuilder;
begin
Result : = self;
Replace(OldValue, NewValue, 0 , Length);
end ;
function TStringBuilder.Replace( const OldChar, NewChar: Char): TStringBuilder;
var
Ptr: PChar;
EndPtr: PChar;
begin
EndPtr : = @FData[Length - 1 ];
Ptr : = @FData[ 0 ];
while Ptr <= EndPtr do
begin
if Ptr^ = OldChar then
Ptr^ : = NewChar;
Inc(Ptr);
end ;
Result : = Self;
end ;
function TStringBuilder.Replace( const OldValue, NewValue: string ; StartIndex,
Count: Integer): TStringBuilder;
var
CurPtr: PChar;
EndPtr: PChar;
Index: Integer;
EndIndex: Integer;
oldLen, newLen: Integer;
begin
Result : = Self;
if Count <> 0 then
begin
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if Count < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Count ' ]); // DO NOT LOCALIZE
if StartIndex + Count > Length then
raise ERangeError.CreateResFmt(@SInputBufferExceed,
[ ' StartIndex ' , StartIndex, ' Count ' , Count]);
oldLen : = System.Length(OldValue);
newLen : = System.Length(NewValue);
Index : = StartIndex;
CurPtr : = @FData[StartIndex];
EndIndex : = StartIndex + Count - oldLen;
EndPtr : = @FData[EndIndex];
while CurPtr <= EndPtr do
begin
if CurPtr^ = OldValue[ 1 ] then
begin
if StrLComp(CurPtr, PChar(OldValue), oldLen) = 0 then
begin
if _Replace(Index, OldValue, NewValue) then
begin
CurPtr : = @FData[Index];
EndPtr : = @FData[EndIndex];
end ;
Inc(CurPtr, newLen - 1 );
Inc(Index, newLen - 1 );
Inc(EndPtr, newLen - oldLen);
Inc(EndIndex, newLen - oldLen);
end ;
end ;
Inc(CurPtr);
Inc(Index);
end ;
end ;
end ;
function TStringBuilder.Replace( const OldChar, NewChar: Char; StartIndex,
Count: Integer): TStringBuilder;
var
Ptr: PChar;
EndPtr: PChar;
begin
if Count <> 0 then
begin
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if Count < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Count ' ]); // DO NOT LOCALIZE
CheckBounds(StartIndex);
CheckBounds(StartIndex + Count - 1 );
EndPtr : = @FData[StartIndex + Count - 1 ];
Ptr : = @FData[StartIndex];
while Ptr <= EndPtr do
begin
if Ptr^ = OldChar then
Ptr^ : = NewChar;
Inc(Ptr);
end ;
end ;
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer; const Value: string ;
count: Integer): TStringBuilder;
var
I: Integer;
begin
for I : = 0 to Count - 1 do
Insert(Index, Value);
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Word): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Shortint): TStringBuilder;
begin
Insert(Index, IntToStr(Value));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: TObject): TStringBuilder;
begin
{ $if CompilerVersion >= 19 }
Insert(Index, Value.ToString());
{ $else }
Insert(Index, IntToStr(Integer(Value)));
{ $ifend }
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: string ): TStringBuilder;
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
if Index > Length then
raise ERangeError.CreateResFmt(@SListIndexError, [Index]);
Length : = Length + System.Length(Value);
Move(FData[Index], FData[Index + System.Length(Value)], (Length - System.Length(Value) - Index) * SizeOf(Char));
Move(Value[ 1 ], FData[Index], System.Length(Value) * SizeOf(Char));
Result : = Self;
end ;
function TStringBuilder.Insert(Index: Integer;
const Value: Single): TStringBuilder;
begin
Insert(Index, FloatToStr(Value));
Result : = Self;
end ;
procedure TStringBuilder.SaveToFile(FileName: string );
var
FileStream: TFileStream;
begin
FileStream : = TFileStream.Create(FileName,fmOpenWrite);
SaveToStream(FileStream);
FileStream.Free;
end ;
procedure TStringBuilder.SaveToStream(Stream: TStream);
begin
Stream.WriteBuffer(FData[ 0 ],Length * SizeOf(Char));
end ;
procedure TStringBuilder.SetCapacity( const Value: Integer);
begin
if Value < Length then
raise ERangeError.CreateResFmt(@SListCapacityError, [Value]);
if Value > FMaxCapacity then
raise ERangeError.CreateResFmt(@SListCapacityError, [Value]);
SetLength(FData, Value);
end ;
procedure TStringBuilder.SetChars(index: Integer; const Value: Char);
begin
if Index < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Index ' ]); // DO NOT LOCALIZE
CheckBounds(Index);
FData[Index] : = Value;
end ;
procedure TStringBuilder.Set_Length( const Value: Integer);
var
LOldLength: Integer;
begin
if Value < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' Value ' ]); // DO NOT LOCALIZE
if Value > MaxCapacity then
raise ERangeError.CreateResFmt(@SListCapacityError, [Value]);
LOldLength : = FLength;
try
FLength : = Value;
if FLength > Capacity then
ExpandCapacity;
except
on E: EOutOfMemory do
FLength : = LOldLength;
end ;
end ;
function TStringBuilder.ToString: string ;
begin
SetLength(Result, Length);
Move(FData[ 0 ], Result[ 1 ], Length * SizeOf(Char));
end ;
function TStringBuilder.ToString(StartIndex, StrLength: Integer): string ;
begin
if StrLength <> 0 then
begin
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StartIndex ' ]); // DO NOT LOCALIZE
if StrLength < 0 then
raise ERangeError.CreateResFmt(@SParamIsNegative, [ ' StrLength ' ]); // DO NOT LOCALIZE
CheckBounds(StartIndex);
CheckBounds(StartIndex + StrLength - 1 );
SetLength(Result, StrLength);
Move(FData[StartIndex], Result[ 1 ], StrLength * SizeOf(Char));
end
else Result : = '' ;
end ;
function TStringBuilder._Replace(Index: Integer; const Old,
New: string ): Boolean;
var
OldCapacity: Integer;
SizeChange: Integer;
begin
Result : = False;
SizeChange : = System.Length(New) - System.Length(Old);
if SizeChange = 0 then
begin
Move(New[ 1 ], FData[Index], System.Length(New) * SizeOf(Char));
end
else
begin
if SizeChange > 0 then
begin
OldCapacity : = Capacity;
Length : = Length + SizeChange;
if OldCapacity <> Capacity then
Result : = True;
end ;
Move(FData[Index + System.Length(Old)], FData[Index + System.Length(New)], (Length - (System.Length(Old) + Index)) * SizeOf(Char));
Move(New[ 1 ], FData[Index], System.Length(New) * SizeOf(Char));
if SizeChange < 0 then
Length : = Length + SizeChange;
end ;
end ;
function TStringBuilder.Append( const Value: Word): TStringBuilder;
begin
Append(IntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Append( const Value: TCharArray): TStringBuilder;
var
I: Integer;
begin
Result : = self;
for I : = 0 to System.Length(Value) - 1 do
if Value[I] = # 0 then
Break;
Append(Value, 0 , I);
end ;
function TStringBuilder.Append( const Value: UInt64): TStringBuilder;
begin
Append(UIntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Append( const Value: Cardinal): TStringBuilder;
begin
Append(UIntToStr(Value));
Result : = self;
end ;
function TStringBuilder.Append( const Value: string ; StartIndex,
Count: Integer): TStringBuilder;
begin
if StartIndex + Count > System.Length(Value) then
raise ERangeError.CreateResFmt(@SListIndexError, [StartIndex]);
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SListIndexError, [StartIndex]);
Length : = Length + Count;
Move(Value[StartIndex + 1 ], FData[Length - Count], Count * SizeOf(Char));
Result : = Self;
end ;
function TStringBuilder.AppendFormat( const Format: string ;
const Args: array of const ): TStringBuilder;
begin
Append(SysUtils.Format(Format, Args));
Result : = Self;
end ;
function TStringBuilder.AppendLine: TStringBuilder;
begin
Append(sLineBreak);
Result : = Self;
end ;
function TStringBuilder.AppendLine( const Value: string ): TStringBuilder;
begin
Append(Value);
AppendLine;
Result : = Self;
end ;
function TStringBuilder.Append( const Value: TCharArray; StartIndex,
CharCount: Integer): TStringBuilder;
begin
if StartIndex + CharCount > System.Length(Value) then
raise ERangeError.CreateResFmt(@SListIndexError, [StartIndex]);
if StartIndex < 0 then
raise ERangeError.CreateResFmt(@SListIndexError, [StartIndex]);
Length : = Length + CharCount;
Move(Value[StartIndex], FData[Length - CharCount], CharCount * SizeOf(Char));
Result : = self;
end ;
function TStringBuilder.Append( const Value: Char;
RepeatCount: Integer): TStringBuilder;
begin
Append(System.StringOfChar(Value, RepeatCount));
Result : = Self;
end ;
end .
本文转自 不得闲 博客园博客,原文链接: http://www.cnblogs.com/DxSoft/archive/2010/01/03/1638242.html ,如需转载请自行联系原作者