tags:

views:

260

answers:

2

I want to upgrade my application from Indy 9 to 10 with Delphi 2007. Now this don't compile anymore as DecodeToStream is not found. The code use Bold framwork as there is reference to BoldElement.

Any alternative methods to call ?

UPDATE (I think I simplify previous example too much)

Original code:

    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

After my change:

    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

But I'm not confident at all of my changes as I don't know Indy so much. So all comments are welcome. One thing I don't understand is the call to CreateBlobStream. I should check with FastMM so it isn't a memleak.

+2  A: 

Yes they changed a lot between 9 and 10.

Now you have "DecodeBytes" instead of DecodeToStream I think. So something like this should do it:

var
  DecodedBytes: TIdBytes;
begin
  MIMEDecoder := TidDecoderMIME.Create(nil);
  try
    DecodedBytes := MIMEDecoder.DecodeBytes(vString);
    vStream.Write(DecodedBytes[0], Length(DecodedBytes));
  finally
    FreeAndNil(MIMEDecoder);
  end;
end;
Runner
I didn't find a DecodeBytes method, but the answer gave me inspiration to change the code so you get points :)
Roland Bengtsson
Ah ok, now you example is a little different yes. Well because Remy is one of the Indy authors I think listening to him would be wise ;)
Runner
+1  A: 

Using TIdDecoder.DecodeBegin() is the correct way to decode to a TStream. However, you do not need the intermediate TIdMemoryStream (which, BTW, has not existed in Indy 10 for a long time now - consider upgrading to a newer release). You can pass the Blob stream directly instead, for example:

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;
Remy Lebeau - TeamB
Somethines I really wish for local "interface" like variables. They would take so much boilerplate away. BlobStream for instance would just free itself when it goes out of scope
Runner
Thanks for the example, now it compiles ok, but I haven't verified the result yet. This maybe belong to another thread but there is 3 nested finally in the code. Is this common to do so ? Can there be performance issues with a lot of try/finally code ?
Roland Bengtsson