p
u
b
l
i
c
i
t
é
publicité
  1. #1
    Membre du Club

    Inscrit en
    août 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : août 2003
    Messages : 207
    Points : 58
    Points
    58

    Par défaut Pos ou ansipos sur ansistring longueur > 255

    Bonjour à tous,

    J'utilise Delphi 2010 et je reçois d'une socket IP des données dont la longueur est d'environ 20 000 caractères UTF8.

    J'ai déclaré une variable XLMTextIN: RawByteString;

    Ensuite sur l'évevenement SocketServerClientRead
    je récupère les données reçues sur la socket

    XLMTextIN := Socket.ReceiveText;

    Pour info, XLMTextIN = '<?xml version="1.0" encoding="utf-8"?>....

    si je fais un pos('utf-8', XLMTextIN)
    ou ansipos('utf-8', XLMTextIN)

    la valeur renvoyée est toujours 0.

    Est ce parce que la longueur de XLMTextIN dépasse les 256 caractères ?
    Ou alors est ce pour une autre raison ?


    Merci d'avance pour vos réponses,
    Wilco

  2. #2
    Expert Confirmé Sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    6 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 6 086
    Points : 17 861
    Points
    17 861

    Par défaut

    je ne sais pas où est l'erreur, mais pas dans la limite de taille, les string ne sont plus limité à 255 caractères depuis Delphi 2
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal

  3. #3
    Expert Confirmé Sénior
    Avatar de Ph. B.
    Homme Profil pro
    Freelance
    Inscrit en
    avril 2002
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

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

    Informations forums :
    Inscription : avril 2002
    Messages : 1 563
    Points : 4 687
    Points
    4 687

    Par défaut

    Bonjour,
    Citation Envoyé par Wilco Voir le message
    J'ai déclaré une variable XLMTextIN: RawByteString;
    ...
    si je fais un pos('utf-8', XLMTextIN)
    ...
    la valeur renvoyée est toujours 0.
    Il faudrait peut être convertir XMLTextIN en string avant de faire le test ?
    Philippe.

  4. #4
    Expert Confirmé Sénior Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    juillet 2006
    Messages
    10 163
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juillet 2006
    Messages : 10 163
    Points : 14 561
    Points
    14 561

    Par défaut

    RawByteString est un type brut mais reste une AnsiString d'un point de vue mémoire

    je pense que c'est plus lié à un problème de conversion d'encodage !
    Quel variante utilise-t-il de Pos utilise-t-il ?

    Citation Envoyé par aide
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function Pos(const SubStr, Str: ShortString): Integer;
    function Pos(const SubStr, Str: UnicodeString): Integer; overload;
    function Pos(const SubStr, Str: WideString): Integer; overload;
    function Pos(const SubStr, Str: RawByteString): Integer; overload;
    tu passes un UnicodeString et RawByteString
    du coup il doit avoir des difficultés pour choisir entre la variante 2 UnicodeString ou 2 RawByteString

    essaye ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var 
      XLMTextIN: RawByteString;
    const
      XML_ENCODE:RawByteString = 'utf-8'; // force le typage et donc le choix de la variante
    begin
      index := Pos(XML_ENCODE, XLMTextIN);
      if index > 0 then
        ...
     
    end;
    ReceiveText d'un Socket retourne une AnsiString, c'est normalement théorique le plus proche du binaire avec un mode chaine

    As-tu essayé un ReceiveBuf dans TByteDynArray temporaire recopié ensuite dans un TMemoryStream pour finalement effectué un TXMLDocument LoadFromStream ?

    Pense aussi que tu ne recevra jamais les 20000 caractères d'un coup mais découpé en lot de 8Ko, il te faudra donc accumuler le XML dans le TMemoryStream, une fois complet, tu pourras le lire
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    septembre 2008
    Messages
    3 584
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 3 584
    Points : 6 161
    Points
    6 161

    Par défaut

    Il faudrait déjà s'assurer qu'il n'y a pas de #0 dans la chaîne. Ceci permettrait de le contrôler :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ShowMessage(PAnsiChar(XLMTextIN) +#13 +IntToStr(Length(XLMTextIN)));
    Si la longueur du texte affiché ne correspond pas à la taille renvoyée, il y a un #0

  6. #6
    Membre du Club

    Inscrit en
    août 2003
    Messages
    207
    Détails du profil
    Informations forums :
    Inscription : août 2003
    Messages : 207
    Points : 58
    Points
    58

    Par défaut

    Merci à tous pour vos réponses ... J'ai peut être une explication sur le problème que je rencontre.

    J'utilise un TServerSocket et lorque la socket reçoit environ 20Ko de données, effectivement elle les reçoit en plusieurs paquets.

    J'ai mis un point d'arrêt sur l'évènement OnRead de la socket.

    Lors du 1er arrêt, si je consulte la variable
    XLMTextIN = Socket.ReceiveText; elle affiche bien '<?xml version="1.0" encoding="utf-8"?>.. je vois donc son contenu

    la seconde variable est :
    x := ansipos('utf-8', XLMTextIN);

    A ce moment, x = 0 ( ce qui est perturbant car il devrait afficher 31 )

    Et ce n'est qu'au 4ème passage sur le point d'arrêt que x = 31.

    Comme le dit justement Shail, les données n'arrivent pas en une seule fois et il semblerait que la fonction pos et/ou ansipos ne renvoie pas la bonne valeur tant que l'intégralité des données aient été reçues. C'est étrange car lors de chaque passage au point d'arrêt, le contenu de la variable XLMTextIN, qui reçoit les données de la socket, est bien visible.

    Au final j'arrive à faire fonctionner ce programme mais le débogage n'est pas facilité en raison du comportement soit de Delphi soit de mon application.


    Merci encore une fois à tous ceux qui ont apporté leur contribution à ce post.

    Wilco

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    septembre 2008
    Messages
    3 584
    Détails du profil
    Informations forums :
    Inscription : septembre 2008
    Messages : 3 584
    Points : 6 161
    Points
    6 161

    Par défaut

    Je ne fais que lire l'aide :

    La déclaration de variables ou de champs de type RawByteString doit être rarement effectué car cela peut conduire à un comportement indéterminé et à des pertes de données potentielles.
    Peut-être serait-il temps d'essayer un autre type...

  8. #8
    Expert Confirmé Sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    novembre 2002
    Messages
    6 086
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : novembre 2002
    Messages : 6 086
    Points : 17 861
    Points
    17 861

    Par défaut

    RawByteString ne perd pas réellement de données, il perd sa page de code, du code le caractère #145 n'est pas forcément le caractère "æ", mais #65 sera toujours un "A"

    pour identifier clairement le problème en mettant de côté le debugueur j'utilise souvent une méthode très efficace:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      {$IFDEF BUG}
       AllocConsole; // ouvre une console si elle n'existe pas déjà
       WriteLn('XLMTextIN = ', XLMTextIN, ' (', Length(XLMTextIN),')');
       WriteLn('Pos(utf-8)=', Pos('utf-8', XLMTextIN));
      {$ENDIF}
    en plaçant ce code juste avant ou après le Pos() qui pose problème on voit clairement ce qu'il se passe.

    ensuite on peut aller plus loin
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
      {$IFDEF BUG}
       AllocConsole; // ouvre une console si elle n'existe pas déjà
       if Length(XMLTextIn) >= 31 then
       begin
         WriteLn('XLMTextIN[31+] = ', Copy(XLMTextIN,31, MaxInt));
       end;
      {$ENDIF}
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Produits : UPnP, RemoteOffice, FlashPascal

Discussions similaires

  1. Export sur Excel - Longueur de champ
    Par eddyG dans le forum VBA Access
    Réponses: 1
    Dernier message: 07/11/2007, 21h01
  2. Chaînes de longueur supérieure à 255
    Par svince dans le forum Langage
    Réponses: 13
    Dernier message: 14/07/2007, 11h47
  3. Réponses: 7
    Dernier message: 20/04/2007, 18h59
  4. Problème sur la longueur de chiffres
    Par iamor dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 28/07/2006, 17h11
  5. Requete : Condition sur la longueur du champ
    Par uskiki85 dans le forum Access
    Réponses: 1
    Dernier message: 23/01/2006, 16h00

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