2010-01-08 13 views
1

Je veux mettre à jour mon application d'Indy 9 à 10 avec Delphi 2007. Maintenant, cela ne compile plus que DecodeToStream est introuvable. Le code utilise Bold framwork car il est fait référence à BoldElement.DecodeToStream dans Indy10

Des méthodes alternatives à appeler?

MISE À JOUR (Je pense que je simplifie exemple précédent trop)

Code d'origine:

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 

Après mon changement:

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 

Mais je ne suis pas du tout confiance de mes changements car je ne connais pas tellement Indy. Donc, tous les commentaires sont les bienvenus. Une chose que je ne comprends pas est l'appel à CreateBlobStream. Je devrais vérifier avec FastMM donc ce n'est pas un mémleak.

+0

Oui, l'appel à CreateBlobStream() est une fuite de mémoire. Vous devez Free() le flux lorsque vous avez fini de l'utiliser. –

Répondre

2

En utilisant TIdDecoder.DecodeBegin() est la bonne façon de décoder à un TStream. Cependant, vous n'avez pas besoin de l'intermédiaire TIdMemoryStream (qui, BTW, n'existe plus depuis longtemps dans Indy 10 - envisagez de passer à une version plus récente). Vous pouvez passer le flux Blob directement à la place, par exemple:

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; 
+0

Somethines Je souhaite vraiment des variables "interface" locales. Ils prendraient tellement de passe-partout. BlobStream par exemple se libérerait juste quand il sortirait du cadre – Runner

+0

Merci pour l'exemple, maintenant il compile ok, mais je n'ai pas encore vérifié le résultat. Cela peut appartenir à un autre thread mais il y en a finalement 3 imbriqués dans le code. Est-ce commun de le faire? Peut-il y avoir des problèmes de performance avec beaucoup de code try/finally? –

2

Oui, ils beaucoup changé entre 9 et 10.

Maintenant, vous avez « DecodeBytes » au lieu de DecodeToStream je pense. Donc, quelque chose comme ça devrait le faire:

var 
    DecodedBytes: TIdBytes; 
begin 
    MIMEDecoder := TidDecoderMIME.Create(nil); 
    try 
    DecodedBytes := MIMEDecoder.DecodeBytes(vString); 
    vStream.Write(DecodedBytes[0], Length(DecodedBytes)); 
    finally 
    FreeAndNil(MIMEDecoder); 
    end; 
end; 
+0

Je n'ai pas trouvé une méthode DecodeBytes, mais la réponse m'a donné l'inspiration pour changer le code afin que vous obteniez des points :) –

+0

Ah ok, maintenant vous exemple est un peu différent oui. Eh bien parce que Rémy est l'un des auteurs d'Indy, je pense que l'écouter serait sage;) – Runner