Delphi: Как кодировать TIdBytes в строку Base64?

Как кодировать TIdBytes в строку Base64 (не 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 :(

Или как отправить AnsiString через AContext.Connection.Socket.Write()?

Компилятор говорит неявное приведение строки из 'AnsiString' в 'string'

Переменная data содержит данные UTF-8 с веб-сайта.

2 ответа

Решение

Вы можете использовать Инди TIdEncoderMIME класс для кодирования String, TStream, а также TIdByte данные в base64 (и TIdDecoderMIME декодировать из base64 обратно в String, TStream, или же TIdBytes), например:

s := TIdEncoderMIME.EncodeBytes(data);

Что касается отправки AnsiString данных, у Indy в D2009+ просто нет TIdIOHandler.Write() перегрузки для обработки AnsiString данные вообще только UnicodeString данные. Чтобы отправить AnsiString как есть, вы можете:

1) скопировать AnsiString в TIdBytes с помощью RawToBytes() а затем позвоните TIdIOHandler.Write(TIdBytes):

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

2) скопировать AnsiString данные в TStream а затем позвоните 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;

Или же:

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;

В более поздних версиях Delphi со строкой Unicode в качестве значения по умолчанию... вы можете спокойно приводить возвращаемое значение в виде String, чтобы избавиться от этого предупреждения. Base64 возвращает только небольшой набор значений (ascii) ..., который никогда не приведет к потере данных при преобразовании в Unicode.

s := String(EncodeBase64(data, Length(data))); 
Другие вопросы по тегам