* Moved TWideCharBuf and associated functions from xmlread.pp to xmlutils.pp, so this stuff can be reused by other code.

git-svn-id: trunk@15718 -
This commit is contained in:
sergei 2010-08-06 08:00:45 +00:00
parent e1eec8c687
commit f39e793448
2 changed files with 59 additions and 49 deletions

View File

@ -177,13 +177,6 @@ type
FCharCount: Cardinal;
end;
PWideCharBuf = ^TWideCharBuf;
TWideCharBuf = record
Buffer: PWideChar;
Length: Integer;
MaxLength: Integer;
end;
TXMLReader = class;
TXMLCharSource = class(TObject)
@ -651,48 +644,6 @@ begin
SameText(AEncoding, 'ISO8859-1');
end;
procedure BufAllocate(var ABuffer: TWideCharBuf; ALength: Integer);
begin
ABuffer.MaxLength := ALength;
ABuffer.Length := 0;
ABuffer.Buffer := AllocMem(ABuffer.MaxLength*SizeOf(WideChar));
end;
procedure BufAppend(var ABuffer: TWideCharBuf; wc: WideChar);
begin
if ABuffer.Length >= ABuffer.MaxLength then
begin
ReallocMem(ABuffer.Buffer, ABuffer.MaxLength * 2 * SizeOf(WideChar));
FillChar(ABuffer.Buffer[ABuffer.MaxLength], ABuffer.MaxLength * SizeOf(WideChar),0);
ABuffer.MaxLength := ABuffer.MaxLength * 2;
end;
ABuffer.Buffer[ABuffer.Length] := wc;
Inc(ABuffer.Length);
end;
procedure BufAppendChunk(var ABuf: TWideCharBuf; pstart, pend: PWideChar);
var
Len: Integer;
begin
Len := PEnd - PStart;
if Len <= 0 then
Exit;
if Len >= ABuf.MaxLength - ABuf.Length then
begin
ABuf.MaxLength := (Len + ABuf.Length)*2;
// note: memory clean isn't necessary here.
// To avoid garbage, control Length field.
ReallocMem(ABuf.Buffer, ABuf.MaxLength * sizeof(WideChar));
end;
Move(pstart^, ABuf.Buffer[ABuf.Length], Len * sizeof(WideChar));
Inc(ABuf.Length, Len);
end;
function BufEquals(const ABuf: TWideCharBuf; const Arg: WideString): Boolean;
begin
Result := (ABuf.Length = Length(Arg)) and
CompareMem(ABuf.Buffer, Pointer(Arg), ABuf.Length*sizeof(WideChar));
end;
{ TDOMParseOptions }

View File

@ -146,6 +146,20 @@ type
procedure EndElement;
end;
{ Buffer builder, used to compose long strings without too much memory allocations }
PWideCharBuf = ^TWideCharBuf;
TWideCharBuf = record
Buffer: PWideChar;
Length: Integer;
MaxLength: Integer;
end;
procedure BufAllocate(var ABuffer: TWideCharBuf; ALength: Integer);
procedure BufAppend(var ABuffer: TWideCharBuf; wc: WideChar);
procedure BufAppendChunk(var ABuf: TWideCharBuf; pstart, pend: PWideChar);
function BufEquals(const ABuf: TWideCharBuf; const Arg: WideString): Boolean;
{$i names.inc}
implementation
@ -846,6 +860,51 @@ begin
Dec(FNesting);
end;
{ Buffer builder utils }
procedure BufAllocate(var ABuffer: TWideCharBuf; ALength: Integer);
begin
ABuffer.MaxLength := ALength;
ABuffer.Length := 0;
ABuffer.Buffer := AllocMem(ABuffer.MaxLength*SizeOf(WideChar));
end;
procedure BufAppend(var ABuffer: TWideCharBuf; wc: WideChar);
begin
if ABuffer.Length >= ABuffer.MaxLength then
begin
ReallocMem(ABuffer.Buffer, ABuffer.MaxLength * 2 * SizeOf(WideChar));
FillChar(ABuffer.Buffer[ABuffer.MaxLength], ABuffer.MaxLength * SizeOf(WideChar),0);
ABuffer.MaxLength := ABuffer.MaxLength * 2;
end;
ABuffer.Buffer[ABuffer.Length] := wc;
Inc(ABuffer.Length);
end;
procedure BufAppendChunk(var ABuf: TWideCharBuf; pstart, pend: PWideChar);
var
Len: Integer;
begin
Len := PEnd - PStart;
if Len <= 0 then
Exit;
if Len >= ABuf.MaxLength - ABuf.Length then
begin
ABuf.MaxLength := (Len + ABuf.Length)*2;
// note: memory clean isn't necessary here.
// To avoid garbage, control Length field.
ReallocMem(ABuf.Buffer, ABuf.MaxLength * sizeof(WideChar));
end;
Move(pstart^, ABuf.Buffer[ABuf.Length], Len * sizeof(WideChar));
Inc(ABuf.Length, Len);
end;
function BufEquals(const ABuf: TWideCharBuf; const Arg: WideString): Boolean;
begin
Result := (ABuf.Length = Length(Arg)) and
CompareMem(ABuf.Buffer, Pointer(Arg), ABuf.Length*sizeof(WideChar));
end;
initialization