Delphi: How to encode TIdBytes to Base64 string?

jmp picture jmp · Dec 13, 2011 · Viewed 12.8k times · Source

How to encode TIdBytes to Base64 string (not AnsiString) ?

  ASocket.IOHandler.CheckForDataOnSource(5);

  if not ASocket.Socket.InputBufferIsEmpty then
  begin
    ASocket.Socket.InputBuffer.ExtractToBytes(data);
    // here I need to encode data to base64 string, how ? I don't need AnsiString!!
    // var s:string;
    s := EncodeBase64(data, Length(data)); // but it will be AnsiString :(

Or how to send AnsiString via AContext.Connection.Socket.Write() ?

Compiler saying Implicit string cast from 'AnsiString' to 'string'

"data" variable contains UTF-8 data from website.

Answer

Remy Lebeau picture Remy Lebeau · Dec 13, 2011

You can use Indy's TIdEncoderMIME class to encode String, TStream, and TIdByte data to base64 (and TIdDecoderMIME to decode from base64 back to String, TStream, or TIdBytes), eg:

s := TIdEncoderMIME.EncodeBytes(data);

As for sending AnsiString data, Indy in D2009+ simply does not have any TIdIOHandler.Write() overloads for handling AnsiString data at all, only UnicodeString data. To send an AnsiString as-is, you can either:

1) copy the AnsiString into a TIdBytes using RawToBytes() and then call TIdIOHandler.Write(TIdBytes):

var
  as: AnsiString;
begin
  as := ...;
  AContext.Connection.IOHandler.Write(RawToBytes(as[1], Length(as)));
end;

2) copy the AnsiString data into a TStream and then call TIdIOHandler.Write(TStream):

var
  as: AnsiString;
  strm: TStream;
begin
  strm := TMemoryStream.Create;
  try
    strm.WriteBuffer(as[1], Length(as));
    AContext.Connection.IOHandler.Write(strm);
  finally
    strm.Free;
  end;
end;

Or:

var
  as: AnsiString;
  strm: TStream;
begin
  as := ...;
  strm := TIdMemoryBufferStream.Create(as[1], Length(as));
  try
    AContext.Connection.IOHandler.Write(strm);
  finally
    strm.Free;
  end;
end;