DecodeToStream в Indy10

Я хочу обновить свое приложение с Indy 9 до 10 с помощью Delphi 2007. Теперь это больше не компилируется, так как DecodeToStream не найден. В коде используется выделение жирным шрифтом, поскольку есть ссылка на BoldElement.

Есть ли альтернативные методы вызова?

ОБНОВЛЕНИЕ (мне кажется, я слишком упрощаю предыдущий пример)

Исходный код:

    BlobStreamStr  : String;
    MIMEDecoder    : TidDecoderMIME; 

    if (BoldElement is TBATypedBlob) then
    begin
      BlobStreamStr := copy(ChangeValue,pos(']',ChangeValue)+1,maxint);
      (BoldElement as TBATypedBlob).ContentType := copy(ChangeValue,2,pos(']',ChangeValue)-2);

      MIMEDecoder := TidDecoderMIME.Create(nil);
      try
        MIMEDecoder.DecodeToStream(BlobStreamStr,(BoldElement as TBATypedBlob).CreateBlobStream(bmWrite));
      finally
        FreeAndNil(MIMEDecoder);
      end;
    end

После моего изменения:

    BlobStreamStr  : String;
    MIMEDecoder    : TidDecoderMIME; 
    LStream        : TIdMemoryStream;

    if (BoldElement is TBATypedBlob) then
    begin
      BlobStreamStr := copy(ChangeValue, pos(']', ChangeValue) + 1, maxint);
      (BoldElement as TBATypedBlob).ContentType := copy(ChangeValue, 2, pos(']',ChangeValue)-2);

      MIMEDecoder := TidDecoderMIME.Create(nil);
      LStream := TIdMemoryStream.Create;
      try
        MIMEDecoder.DecodeBegin(LStream);
        MIMEDecoder.Decode(BlobStreamStr, 0, Length(BlobStreamStr));
        LStream.Position := 0;
        ReadTIdBytesFromStream(LStream, DecodedBytes, Length(BlobStreamStr));

        // Should memory for this stream be released ??
        (BoldElement as TBATypedBlob).CreateBlobStream(bmWrite).Write(DecodedBytes[0], Length(DecodedBytes));
      finally
        MIMEDecoder.DecodeEnd;
        FreeAndNil(LStream);
        FreeAndNil(MIMEDecoder);
      end;
    end

Но я не уверен во всех своих изменениях, потому что я мало знаю Инди. Так что все комментарии приветствуются. Я не понимаю одного вызова CreateBlobStream. Я должен проверить с FastMM, чтобы это не утечка памяти.


person Roland Bengtsson    schedule 08.01.2010    source источник
comment
Да, вызов CreateBlobStream () - это утечка памяти. Вам нужно Free () поток, когда вы закончите его использовать.   -  person Remy Lebeau    schedule 09.01.2010


Ответы (2)


Использование TIdDecoder.DecodeBegin () - правильный способ декодирования в TStream. Однако вам не нужен промежуточный TIdMemoryStream (который, кстати, давно не существует в Indy 10 - рассмотрите возможность обновления до более новой версии). Вместо этого вы можете передать поток Blob напрямую, например:

var
  BlobElement    : TBATypedBlob;
  BlobStreamStr  : String; 
  BlobStream     : TStream;
  MIMEDecoder    : TidDecoderMIME;  
begin 
  ...
  if BoldElement is TBATypedBlob then 
  begin 
    BlobElement := BoldElement as TBATypedBlob;

    BlobStreamStr := Copy(ChangeValue, Pos(']',ChangeValue)+1, Maxint); 
    BlobElement.ContentType := Copy(ChangeValue, 2, Pos(']',ChangeValue)-2); 

    BlobStream := BlobElement.CreateBlobStream(bmWrite);
    try
      MIMEDecoder := TidDecoderMIME.Create(nil); 
      try 
        MIMEDecoder.DecodeBegin(BlobStream);
        try
          MIMEDecoder.Decode(BlobStreamStr); 
        finally
          MIMEDecoder.DecodeEnd;
        end;
      finally 
        FreeAndNil(MIMEDecoder); 
      end; 
    finally
      FreeAndNil(BlobStream);
    end;
  end;
  ...
end;
person Remy Lebeau    schedule 08.01.2010
comment
Что-то мне действительно нужно для локального интерфейса, например, переменных. Они уберут так много шаблонного. Например, BlobStream просто освободится, когда выйдет за пределы области видимости. - person Runner; 09.01.2010
comment
Спасибо за пример, теперь он компилируется нормально, но я еще не проверил результат. Возможно, это принадлежит другому потоку, но, наконец, в коде есть 3 вложенных. Это обычное дело? Могут ли быть проблемы с производительностью при большом количестве кода try / finally? - person Roland Bengtsson; 10.01.2010

Да, они сильно изменились между 9 и 10.

Думаю, теперь у вас есть DecodeBytes вместо DecodeToStream. Так должно получиться что-то вроде этого:

var
  DecodedBytes: TIdBytes;
begin
  MIMEDecoder := TidDecoderMIME.Create(nil);
  try
    DecodedBytes := MIMEDecoder.DecodeBytes(vString);
    vStream.Write(DecodedBytes[0], Length(DecodedBytes));
  finally
    FreeAndNil(MIMEDecoder);
  end;
end;
person Runner    schedule 08.01.2010
comment
Я не нашел метода DecodeBytes, но ответ вдохновил меня изменить код, чтобы получать баллы :) - person Roland Bengtsson; 09.01.2010
comment
Хорошо, теперь ваш пример немного другой, да. Ну, потому что Реми - один из авторов Инди, я думаю, было бы разумно его послушать;) - person Runner; 09.01.2010