IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Décompression de chaînes défaillante sous IOS


Sujet :

Langage Delphi

  1. #1
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut Décompression de chaînes défaillante sous IOS
    Bonjour

    J'ai récupéré sur le net deux fonctions de compression/décompression de chaînes.
    La chaîne est compressée par le serveur pour être envoyée au client en JSON par datasnap.
    Le serveur est toujours utilisé sous Windows.
    Le client peut-être utilisé dans sa version Windows ou IOS.

    La chaîne compressée sous Windows et récupérée par le client sous Windows ne pose aucun problème.
    Mais la même chaîne récupérée par le client en version IOS renvoie une erreur de décompression de chaîne.

    ---------------------------
    Notification des exceptions du débogueur
    ---------------------------
    Le projet truc a déclenché la classe d'exception EZDecompressionError avec le message 'data error'.
    ---------------------------
    Arrêter Continuer Aide
    ---------------------------
    sur vDecompressor.Read


    Quelqu'un aurait une idée sur l'origine du problème ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    // Compresse la chaîne reçue en paramètre et renvoie le résultat
    function Compressed(ASrc: string): string;
    var
      B: array[1..2048] of byte;
      R: Integer;
      vSrc: TStream;        // source stream
      vDest: TStream;       // destination stream
      vCompressor: TStream; // compression stream
    begin
      vDest := TStringStream.Create('');
      try
        vCompressor := TCompressionStream.Create(clMax, vDest);
        try
          vSrc := TStringStream.Create(ASrc);
          try
            repeat
              R := vSrc.Read(B, SizeOf(B));
              if R > 0 then
                vCompressor.Write(B, R);
            until R < SizeOf(B);
          finally
            vSrc.Free;
          end;
        finally
          vCompressor.Free;
        end;
      finally
        vDest.Seek(0, 0);
        Result := TStringStream(vDest).DataString;
        vDest.Free;
      end;
    end;
     
    // Décompresse la chaîne reçue en paramètre et renvoie le résultat
    function Decompressed(ASrc: string): string;
    var
      B: array[1..2048] of byte;
      R: Integer;
      vSrc: TStream;          // source stream
      vDest: TStream;         // destination stream
      vDecompressor: TStream; // compression stream
    begin
      vSrc := TStringStream.Create(ASrc);
      try
        vDecompressor := TDecompressionStream.Create(vSrc);
        try
          vDest := TStringStream.Create('');
          try
            repeat
              R := vDecompressor.Read(B, SizeOf(B));
              if R > 0 then
                vDest.Write(B, R);
            until R < SizeOf(B);
          finally
            Result := TStringStream(vDest).DataString;
            FreeAndNil(vDest);
          end;
        finally
          FreeAndNil(vDecompressor);
        end;
      finally
        FreeAndNil(vSrc);
      end;
    end;
    Papy !

  2. #2
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 418
    Points : 5 816
    Points
    5 816
    Par défaut
    salut

    je vois déjà une différence entre la compression et la décompression
    tu fait un avant de retourner la valeur lors de la compression et tu ne le fait pas lors de la décompression
    peut être est ce simplement cela ton message d'erreur Windows étant peut être plus permissif que Ios
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    5
    Détails du profil
    Informations personnelles :
    Âge : 53
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 5
    Points : 5
    Points
    5
    Par défaut EZDecompressionError avec le message 'data error'
    Bonjour !
    J'ai le même problème avec un composant TRestClient/TrestRequest/TRestResponse.
    Ca marche impec sous windows, mais sous IOS j'ai le même message d'erreur de compression que vous ...

    J'ai pas mal cherché sur le net sans succès .. vous avez eu de nouvelles pistes ??
    Aide toi, le ciel t'aidera.

  4. #4
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    l'erreur vient peut-être de ceci "until R < SizeOf(B);"...j'aurais plutôt mis un "until R = 0" qui indique qu'il n'y a plus rien à lire...à tester.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Salut Paul

    Et il faudrait donc faire une différence entre Windows et iOS puisque ça fonctionne sur le premier et pas sur le second ?

    Je testerai dès que possible. Pour l'instant, j'avais mis la compression/decompression en commentaire dans le soft.

  6. #6
    Membre émérite
    Avatar de Thierry Laborde
    Homme Profil pro
    N/A
    Inscrit en
    Avril 2002
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : N/A

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 391
    Points : 2 529
    Points
    2 529
    Par défaut
    Bonjour,

    Question bête mais pourquoi ne pas utiliser les fonctions ZCompressStr et ZDecompressStr de l'unité Zlib qui sont en standard ?
    De plus selon comment on utilise Datasnap il y a des fonctions directement intégrés dans les composants.

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    Salut Paul

    Et il faudrait donc faire une différence entre Windows et iOS puisque ça fonctionne sur le premier et pas sur le second ?

    Je testerai dès que possible. Pour l'instant, j'avais mis la compression/decompression en commentaire dans le soft.
    ce n'est qu'une hypothèse qui part de l'idée que "vSrc.Read(B, SizeOf(B));" retourne 0 en cas de fin de fichier, et une valeur comprise entre 1 et SizeOf(B) dans les autres cas...que la valeur soit toujours SizeOf(B) sur certaines plateformes ne garanti pas que ce soit le cas sur toutes les plateformes.

    l'idée m'est venue de la fonction recv() des sockets qui a exactement le comportement donné ci-dessus. Quand tu testes cela sur une réseau local tu as de fortes chances de pouvoir lire tes données en un seul recv(), mais si tu pars sur un réseau 3G tu as toutes les chances de devoir boucler

    Sinon, comme le fait remarquer Thierry tu as des fonctions toute faites, y compris TStream.CopyFrom.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Citation Envoyé par Thierry Laborde Voir le message
    Bonjour,

    Question bête mais pourquoi ne pas utiliser les fonctions ZCompressStr et ZDecompressStr de l'unité Zlib qui sont en standard ?
    De plus selon comment on utilise Datasnap il y a des fonctions directement intégrés dans les composants.
    Salut Thierry.

    Bonne question ! Réponse : parce que je ne les connaissais pas

    Je vais me faire un plaisir de tester ça.

  9. #9
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    y compris TStream.CopyFrom.
    ???

    Pour compresser une chaîne ? Il y a un type spécial de TStream pour ça ?

  10. #10
    Membre émérite
    Avatar de Thierry Laborde
    Homme Profil pro
    N/A
    Inscrit en
    Avril 2002
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : N/A

    Informations forums :
    Inscription : Avril 2002
    Messages : 1 391
    Points : 2 529
    Points
    2 529
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    Salut Thierry.

    Bonne question ! Réponse : parce que je ne les connaissais pas

    Je vais me faire un plaisir de tester ça.
    Salut,

    Allez pour te faire gagner un peu de temps. Très simple en 2 lignes :

    Une Form avec 3 Edit (Edit1, Edit2 et Edit3), un bouton et sur le click du bouton on compresse ce qui est dans Edit1 et on met le résultat compressé dans Edit2, puis on décompresse ce qui est dans Edit2 et on met le résultat dans Edit3 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Edit2.Text:=TNetEncoding.Base64.EncodeBytesToString(ZcompressStr(Edit1.Text));
    Edit3.Text:=ZDecompressStr(TNetEncoding.Base64.DecodeStringToBytes(Edit2.Text));
    Ne pas oublier d'ajouter dans les uses les 2 unités : System.ZLib et System.NetEncoding.

    On peut pas faire plus simple.

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    392
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 392
    Points : 635
    Points
    635
    Par défaut
    il y a peut-être aussi un problème d'encodage de caractères différent suivant les systèmes vu que tu utilises l'encodage par défaut avec la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TStringStream.Create(ASrc)
    si on en crois la doc sous windows c'est ANSI et sous OS X UTF-8

    essayes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TStringStream.Create(ASrc,TEncoding.UTF8)

  12. #12
    Membre émérite

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 385
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 385
    Points : 2 999
    Points
    2 999
    Par défaut
    Thierry:

    Pour le test, il est facile comme tu l'indiques mais si le problème vient d'une compression sous Windows suivi d'une décompression sous IOS, ça ne me dira pas grand-chose. Comme exoseven, je soupçonnais une différence d'encodage sans avoir réussi à trouver la "bonne formule".

    En fait, une application serveur datasnap écrite en Delphi tourne sur Windows et fait office de serveur de mail.
    Les emails reçus sont stockés dans une base de données et quand l'iphone demande l'envoi d'email, le contenu html de chaque email est compressé avant envoi. Le décompression se fait sur l'Iphone au moment de la réception du contenu (format JSON).
    Enfin, ça c'était avant. J'ai supprimé la compression/décompression suite au problème décrit.

    Je remettrai ça en place avec les fonctions de ZLib pour voir si ça va mieux.
    Si ça ne change rien, j'essaierai de forcer l'encodage des 2 cotés.

  13. #13
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    euh...l'encodage n'intervient pas...on passe de Unicode à Bytes puis de Bytes à Unicode, la compression se fiche du contenu, ce n'est qu'une suite d'octets.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    function ZCompressStr(const s: string; level: TZCompressionLevel): TBytes;
    begin
      ZCompress(TEncoding.Unicode.GetBytes(s),Result);
    end;
     
    function ZDecompressStr(const s: TBytes): string;
    var
      BIn,BOut: TBytes;
    begin
      BIn := s;
      ZDecompress(BIn, BOut);
      Result := TEncoding.Unicode.GetString(BOut);
    end;
    de plus, EZDecompressionError intervient au niveau de la décompression en Bytes, bien avant la conversion en Unicode.

    maintenant l'erreur peut tout aussi bien être sur le transfert des données

    je viens de voir un bug dans le client HTTP sous iOS
    http://community.embarcadero.com/answers/error-rest
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

Discussions similaires

  1. Compression d'une image sous forme de byte[]
    Par pj_19 dans le forum ASP.NET MVC
    Réponses: 1
    Dernier message: 10/05/2011, 12h37
  2. Compression d'images satellites sous MATLAB
    Par soufiane121 dans le forum Images
    Réponses: 4
    Dernier message: 08/01/2008, 09h46
  3. Réponses: 1
    Dernier message: 13/04/2006, 12h21
  4. Compression des dump Oracle sous windows
    Par thomasjcj dans le forum Oracle
    Réponses: 5
    Dernier message: 28/10/2005, 14h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo