{$MODE FPC}
{$MODESWITCH ADVANCEDRECORDS}
{$MODESWITCH OUT}
{$MODESWITCH RESULT}
unit dansibuffer_ansiview;

interface

uses
  dansiview,
  dansibuffer;

// Handy constructors
function AnsiView(const S: TAnsiBuffer): TAnsiView; inline; overload;

// Constructs TAnsiBuffer from TAnsiView
procedure AnsiBufferInit(out B: TAnsiBuffer; const S: TAnsiView); overload;
procedure AnsiBufferReInit(var B: TAnsiBuffer; const S: TAnsiView); inline; overload;

// Concatanates list of strings and saves result to AnsiBuffer
// B must be initialized
procedure Concat(B: PAnsiBuffer; const S1, S2: TAnsiView); overload;
procedure Concat(var B: TAnsiBuffer; const S1, S2: TAnsiView); overload;
procedure Concat(var B: TAnsiBuffer; const S1, S2, S3: TAnsiView); overload;
procedure Concat(var B: TAnsiBuffer; const S: array of TAnsiView); overload;

// Implicit conversion
operator := (const B: TAnsiBuffer): TAnsiView; inline;

implementation

function AnsiView(const S: TAnsiBuffer): TAnsiView;
begin
  Result := AnsiView(S.Data, S.Length);
end;

procedure AnsiBufferInit(out B: TAnsiBuffer; const S: TAnsiView);
begin
  B.Init(S.Data, S.Length);
end;

procedure AnsiBufferReInit(var B: TAnsiBuffer; const S: TAnsiView);
begin
  B.ReInit(S.Data, S.Length);
end;

procedure Concat(B: PAnsiBuffer; const S1, S2: TAnsiView);
begin
  B^.SetLength(S1.Length + S2.Length);
  if B^.Data <> nil then begin
    Move(S1.Data^, B^.Data[0], S1.Length);
    Move(S2.Data^, B^.Data[S1.Length], S2.Length);
  end;
end;

procedure Concat(var B: TAnsiBuffer; const S1, S2: TAnsiView);
begin
  B.SetLength(S1.Length + S2.Length);
  if B.Data <> nil then begin
    Move(S1.Data^, B.Data[0], S1.Length);
    Move(S2.Data^, B.Data[S1.Length], S2.Length);
  end;
end;

procedure Concat(var B: TAnsiBuffer; const S1, S2, S3: TAnsiView);
begin
  B.SetLength(S1.Length + S2.Length + S3.Length);
  if B.Data <> nil then begin
    Move(S1.Data^, B.Data[0], S1.Length);
    Move(S2.Data^, B.Data[S1.Length], S2.Length);
    Move(S3.Data^, B.Data[S1.Length + S2.Length], S3.Length);
  end;
end;

procedure Concat(var B: TAnsiBuffer; const S: array of TAnsiView); overload;
var
  I: LongInt;
  Total: SizeUInt;
  P: PAnsiChar;
begin
  Total := 0;
  for I := System.Low(S) to System.High(S) do
    Inc(Total, S[I].Length);
  B.SetLength(Total);
  P := B.Data;
  for I := System.Low(S) to System.High(S) do begin
    Move(S[I].Data^, P^, S[I].Length);
    Inc(P, S[I].Length);
  end;
end;

operator := (const B: TAnsiBuffer): TAnsiView;
begin
  Result.Data := B.Data;
  Result.Length := B.Length;
end;

end.
