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 :

(SearchBinaryInFile) : Copier un string dans un TByteDynArray


Sujet :

Langage Delphi

  1. #1
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut (SearchBinaryInFile) : Copier un string dans un TByteDynArray
    Bonjour à tous

    La fonction SearchBinaryInFile me pose un problème de syntaxe tout bête. La chaîne de caractère (string) à rechercher dans le fichier : comment la copier dans un TByteDynArray ?

    Rien ne passe : ni StrCopy(), ni := , ni quoi que ce soit. Comment faire cette copie d'un string ds un TByteDynArray (donc un tableau de bytes, si je comprends bien) ?

    Illustration :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    // Var passées en paramètres à SerchBinary -------
     
    Nom_F_SearchBinary : string;   // F où effectuer la recherche
    Tab_Chn_Rech : TByteDynArray;   // Tableau de Bytes à chercher dans le fichier
    Tab_Positions : TInt64DynArray;  // Tableau d'Int64 qui contiendra les positions des occurrences trouvés
    Rech_Ttes_Occurrences : boolean;  // Si True,  remplit le tableau Tab_Positions des différentes occurrences
    Max_Occurrences_Acceptees : integer; // Si le nombre d'occurrences trouvées atteint ce nombre, la recherche s'arrête
    Accepter_Chevauchement_Occurrences : boolean;   // (exemple : on cherche coco; si le fichier contient cocococo : True = 3, False = 2)
    Nb_Occurrences_Trouvees : integer;  // retourné par la fonction
    La fonction est explicitée ici , mais je bloque :/ : http://www.developpez.net/forums/d78...e/#post4542214

  2. #2
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    Voici ce que je fais, mais "Erreur d'étendue" à l'exécution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    Procedure Copier_String_Sur_DynArray;  // DEBUG
    Var   i : integer;
          Car_Pointe : char;
     
    begin
     
          For i := 1 to (Longueur_Chn -1) DO
              begin
                    Car_Pointe := Chn_Recherchee[1];
                    Tab_Chn_Rech[i] := Byte(Car_Pointe);
              end;
     
    end;

  3. #3
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 152
    Points
    10 152
    Par défaut
    Sous Delphi < 2009, ou avec des AnsiString :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function StringToByteArray(const S: AnsiString): TByteDynArray;
    var
      Len: Integer;
    begin
      Len := Length(S);
      SetLength(Result, Len);
      Move(S[1], Result[0], Len);
    end;
    Sous Delphi >= 2009, les chaînes sont Unicode. Donc il faut savoir dans quel encodage tu veux transformer ta chaîne avant de rechercher la chaîne de bytes dans le fichier. Puis tu as la méthode GetBytes de TEncoding.

    Donc si tu veux travailler en UTF-8 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bytes := TEncoding.UTF8.GetBytes(S);
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  4. #4
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par sjrd Voir le message
    Sous Delphi < 2009, ou avec des AnsiString :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function StringToByteArray(const S: AnsiString): TByteDynArray;
    var
      Len: Integer;
    begin
      Len := Length(S);
      SetLength(Result, Len);
      Move(S[1], Result[0], Len);
    end;
    Sous Delphi >= 2009, les chaînes sont Unicode. Donc il faut savoir dans quel encodage tu veux transformer ta chaîne avant de rechercher la chaîne de bytes dans le fichier. Puis tu as la méthode GetBytes de TEncoding.

    Donc si tu veux travailler en UTF-8 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bytes := TEncoding.UTF8.GetBytes(S);
    Ca, c'est une piste ! Merci Je vais tester ça tout de suite.

  5. #5
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par sjrd Voir le message
    Sous Delphi < 2009, ou avec des AnsiString :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function StringToByteArray(const S: AnsiString): TByteDynArray;
    var
      Len: Integer;
    begin
      Len := Length(S);
      SetLength(Result, Len);
      Move(S[1], Result[0], Len);
    end;
    Sous Delphi >= 2009, les chaînes sont Unicode. Donc il faut savoir dans quel encodage tu veux transformer ta chaîne avant de rechercher la chaîne de bytes dans le fichier. Puis tu as la méthode GetBytes de TEncoding.

    Donc si tu veux travailler en UTF-8 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Bytes := TEncoding.UTF8.GetBytes(S);
    OK. Ca marche (je suis en D7) :je peux appeler SearchBinaryToFile(), avec ta fonction

    En revanche, c'est SearchBinary elle-même qui semble foirer. Elle ne trouve systématiquement pas les chaînes de caractères que je lui passe. Aléatoirement oui, ou non . Tests effectués sur fichiers HTM et RTF . Pr les fichiers RTF, Delphi a ce qu'il faut : FindText(). Mais pour les HTM, HTML etc, là, FindText() s'égare...

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Sinon, il y a le code de SearchStringInFile juste en dessous de SearchBinaryInFile dans le lien que tu as cité comment chercher une valeur hex dans un fichier binaire "file of byte"

    de D4 à D2007, cela fonctione sans soucis
    Après D2009, il faudra passer à AnsiString et AnsiChar dans le Code

    Et donc, la fonctionne trouve pas le mot que tu recherches, cela m'intéresse, je pourrais peut-être t'aider

    Attention, c'est une recherche binaire pur !
    si tu cherche "toto" dans un HTML, cela ne trouve que "toto" mais pas "t<B>ot<\B>o"
    Je fais cette remarque parce FindText lui cherche du Texte dans un RTF en retirant les balises de mise en forme
    Evidemment FindText ne traitant que du RTF, cela ne peut pas traiter du HTML
    Et vouloir utiliser FindText sur du HTML c'est que tu n'as pas compris l'aide et
    que tu ne mesures par l'importance des balises de mise en forme et de la différence entre un fichier texte simple et un fichier plus évolué !

    Avec TWebBrowser.Naviagate2(FichierLocal), puis OleDoc->Body->InnerHTML puis une fonction Pos, tu peux bidouiller un extracteur de Text de fichier HTML
    c'est un peu moche !
    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

  7. #7
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon, il y a le code de SearchStringInFile juste en dessous de SearchBinaryInFile dans le lien que tu as cité comment chercher une valeur hex dans un fichier binaire "file of byte"

    de D4 à D2007, cela fonctione sans soucis
    Après D2009, il faudra passer à AnsiString et AnsiChar dans le Code

    Et donc, la fonctionne trouve pas le mot que tu recherches, cela m'intéresse, je pourrais peut-être t'aider

    Attention, c'est une recherche binaire pur !
    si tu cherche "toto" dans un HTML, cela ne trouve que "toto" mais pas "t<B>ot<\B>o"
    Je fais cette remarque parce FindText lui cherche du Texte dans un RTF en retirant les balises de mise en forme
    Evidemment FindText ne traitant que du RTF, cela ne peut pas traiter du HTML
    Et vouloir utiliser FindText sur du HTML c'est que tu n'as pas compris l'aide et
    que tu ne mesures par l'importance des balises de mise en forme et de la différence entre un fichier texte simple et un fichier plus évolué !

    Avec TWebBrowser.Naviagate2(FichierLocal), puis OleDoc->Body->InnerHTML puis une fonction Pos, tu peux bidouiller un extracteur de Text de fichier HTML
    c'est un peu moche !
    C'est toi l'auteur de cette fonction, non ? Elle est super... mais je dois lui passer de mauvais paramètres. Je te mets le code en ligne, attends

  8. #8
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon, il y a le code de SearchStringInFile juste en dessous de SearchBinaryInFile dans le lien que tu as cité comment chercher une valeur hex dans un fichier binaire "file of byte"

    de D4 à D2007, cela fonctione sans soucis
    Après D2009, il faudra passer à AnsiString et AnsiChar dans le Code

    Et donc, la fonctionne trouve pas le mot que tu recherches, cela m'intéresse, je pourrais peut-être t'aider

    Attention, c'est une recherche binaire pur !
    si tu cherche "toto" dans un HTML, cela ne trouve que "toto" mais pas "t<B>ot<\B>o"
    Je fais cette remarque parce FindText lui cherche du Texte dans un RTF en retirant les balises de mise en forme
    Evidemment FindText ne traitant que du RTF, cela ne peut pas traiter du HTML
    Et vouloir utiliser FindText sur du HTML c'est que tu n'as pas compris l'aide et
    que tu ne mesures par l'importance des balises de mise en forme et de la différence entre un fichier texte simple et un fichier plus évolué !

    Avec TWebBrowser.Naviagate2(FichierLocal), puis OleDoc->Body->InnerHTML puis une fonction Pos, tu peux bidouiller un extracteur de Text de fichier HTML
    c'est un peu moche !

    Ca maaaaaarche !!! Fantastique !!

    Dis-donc, ShaiLeTroll, on ne t'a jamais dit que tu avais du génie, toi ?

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Merci Merci !

    Quel était le problème ?
    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

  10. #10
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Merci Merci !

    Quel était le problème ?
    Je n'arrivais pas à copier un string sur TDynArray. Bon. Puios on m'a expliqué comment. Mais c'est carrément plus simple SearchBinaryInFile

    Le fin du fin, ce serait une fonction comme celle-ci, mais "scrutant" un buffer mémoire, sans forcément passer par l'ouverture d'un fichier.

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Pour la Mémoire, si c'est des chaines, Pos et PosEx !

    Sinon, c'est juste une boucle sur deux Pointeurs, voir la fonction CompareMem (celle codée en pascal, pas celle en ASM)
    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

  12. #12
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Pour la Mémoire, si c'est des chaines, Pos et PosEx !

    Sinon, c'est juste une boucle sur deux Pointeurs, voir la fonction CompareMem (celle codée en pascal, pas celle en ASM)
    Hélas non ! Extrait de l'aide de Delphi :
    Description

    CompareMem effectue une comparaison binaire de Length octets de mémoire référencés par P1 et P2.CompareMem renvoie true si la mémoire référencée par P1 est identique à celle de P2.


    Je ne compare pas, je voudrais TROUVER une occurrence de la châine X ds un bloc mémoire

    Or, mon bloc mémoire n'est pas un String : il est non typé. C'est juste un buffer de bytes. Pos() et PosEx() ne travaillent que sur des string. Le buffer où je vais chercher est une concaténation de fichiers RTF et HTML déjà chargée en mémoire.


    D'où mon intérêt pour SearchBinary ! Malheureusement, il me faut l'adapter à mon prog, évitant tout chargement de fichier. Le buffer où SearchBinary doit chercher, il est déjà en RAM, pointé par un pointeur "void" : Pointer

    Je cherche à extraire de SearchBinary toute référence à un fichier, pour la faire bosser sur un buffer : la tableau SearchBuf me va très bien.... Il me faudrait juste la routine de recherche sur le tableau de bytes. C'est elle que j'essaie d'isoler, pour ne passer aucun nom de fichier en paramètre, mais un pointeur sur un buffer.

    Pas évident... Avec tous ces if/else

  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
    et pourquoi ne places-tu pas ton HTML/RTF dans un string ?!
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  14. #14
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    et pourquoi ne places-tu pas ton HTML/RTF dans un string ?!
    , il n'a pas envie d'utiliser PosEx que veux-tu !

    qu'est qui empêche d'utiliser CompareMem dans une boucle, en incrémentant d'un le pointeur du bloc mémoire à chaque itération !

    SearchBinaryInFile étant dédié au fichier utilise un buffer de lecture ce qui complique le code évidemment mais devient totalement inutile pour le recherche dans un binaire !

    D'ailleurs, la version du forum n'est pas la bonne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if iCountFound = Threshold then
    doit être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if Result = Threshold then
    Mais bon, c'est pas grave !

    Le code version buffer, en conservant toutes les fonctions devraient être ça

    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
    {* -----------------------------------------------------------------------------
    la Fonction SearchBinaryInBuffer Permet de Chercher un Tableau de Byte dans un Buffer
    @param Buffer Pointeur sur une Zone Mémoire de 4Go maximum
    @param BufferLen Longueur de la Zone Mémoire
    @param SearchBinary Tableau de Byte à chercher dans la Zone Mémoire
    @param OffSets Tableau d'Entier qui contiendra les positions de occurences trouvés
    @param KeepOffSet Boolean True rempli OffSets, False, ne rempli pas OffSets
    @param Threshold Si le nombre de Tableau de Byte trouvé atteind ce nombre, la Recherche s'arrête
    @param AcceptOverlap Boolean True si le mot à chercher est une répétition cela compte les occurences qui se chevauche, False chaque octet d'une occurence ne peut être comptabilisé qu'une seule fois (exemple on chercher coco, le fichier contient cocococo, True = 3, False = 2)
    @return Nombre d'occurence Trouvé
    ------------------------------------------------------------------------------ }
    function SearchBinaryInBinary(const Buffer: Pointer; BufferLen: Cardinal; const SearchBinary: TByteDynArray; out OffSets: TCardinalDynArray; KeepOffSet: Boolean = False; Threshold: Integer = MaxInt; AcceptOverlap: Boolean = False): Integer;
    var
       iReaded: Cardinal;
       SearchLen: Cardinal;
       BufferCurPos: PByte;
       WantedCurPos: PByte;
    begin
       Result := 0;
     
       SearchLen := Length(SearchBinary);
       if SearchLen <= 0 then
          Exit;
     
       BufferCurPos := Buffer;
       WantedCurPos := @SearchBinary[0];
       iReaded := 0;
     
       while iReaded < BufferLen do
       begin
          if CompareMem(BufferCurPos, WantedCurPos, SearchLen) then
          begin
             Inc(Result);
     
             if KeepOffSet then
             begin
                SetLength(OffSets, Length(OffSets) + 1);
                OffSets[High(OffSets)] := Cardinal(BufferCurPos) - Cardinal(Buffer); // Si un jour 64Bits, Cardinal -> Int64 ?
             end;
     
             if Result = Threshold then
               Exit;
            if AcceptOverlap then
            begin
               Inc(BufferCurPos, 1);
               Inc(iReaded, 1);
            end
            else
            begin
               Inc(BufferCurPos, SearchLen);
               Inc(iReaded, SearchLen);
            end;
          end
          else
          begin
             Inc(BufferCurPos, 1);
             Inc(iReaded, 1);
          end;
       end;
    end;
    cela s'utilise avec un
    - @array[0], si tu as stocké ton RTF dans array of byte
    - Stream.Memory si tu as stocké ton RTF TMemoryStream
    - Avec tout pointeur
    - avec @AnsiString[1], si tu as stocké ton RTF dans une chaine, voir le commentaire de Paul Toth
    ...
    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

  15. #15
    Membre régulier

    Profil pro
    Inscrit en
    Avril 2004
    Messages
    536
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 536
    Points : 121
    Points
    121
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    , il n'a pas envie d'utiliser PosEx que veux-tu !

    qu'est qui empêche d'utiliser CompareMem dans une boucle, en incrémentant d'un le pointeur du bloc mémoire à chaque itération !

    SearchBinaryInFile étant dédié au fichier utilise un buffer de lecture ce qui complique le code évidemment mais devient totalement inutile pour le recherche dans un binaire !

    D'ailleurs, la version du forum n'est pas la bonne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if iCountFound = Threshold then
    doit être
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if Result = Threshold then
    Mais bon, c'est pas grave !

    Le code version buffer, en conservant toutes les fonctions devraient être ça

    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
    {* -----------------------------------------------------------------------------
    la Fonction SearchBinaryInBuffer Permet de Chercher un Tableau de Byte dans un Buffer
    @param Buffer Pointeur sur une Zone Mémoire de 4Go maximum
    @param BufferLen Longueur de la Zone Mémoire
    @param SearchBinary Tableau de Byte à chercher dans la Zone Mémoire
    @param OffSets Tableau d'Entier qui contiendra les positions de occurences trouvés
    @param KeepOffSet Boolean True rempli OffSets, False, ne rempli pas OffSets
    @param Threshold Si le nombre de Tableau de Byte trouvé atteind ce nombre, la Recherche s'arrête
    @param AcceptOverlap Boolean True si le mot à chercher est une répétition cela compte les occurences qui se chevauche, False chaque octet d'une occurence ne peut être comptabilisé qu'une seule fois (exemple on chercher coco, le fichier contient cocococo, True = 3, False = 2)
    @return Nombre d'occurence Trouvé
    ------------------------------------------------------------------------------ }
    function SearchBinaryInBinary(const Buffer: Pointer; BufferLen: Cardinal; const SearchBinary: TByteDynArray; out OffSets: TCardinalDynArray; KeepOffSet: Boolean = False; Threshold: Integer = MaxInt; AcceptOverlap: Boolean = False): Integer;
    var
       iReaded: Cardinal;
       SearchLen: Cardinal;
       BufferCurPos: PByte;
       WantedCurPos: PByte;
    begin
       Result := 0;
     
       SearchLen := Length(SearchBinary);
       if SearchLen <= 0 then
          Exit;
     
       BufferCurPos := Buffer;
       WantedCurPos := @SearchBinary[0];
       iReaded := 0;
     
       while iReaded < BufferLen do
       begin
          if CompareMem(BufferCurPos, WantedCurPos, SearchLen) then
          begin
             Inc(Result);
     
             if KeepOffSet then
             begin
                SetLength(OffSets, Length(OffSets) + 1);
                OffSets[High(OffSets)] := Cardinal(BufferCurPos) - Cardinal(Buffer); // Si un jour 64Bits, Cardinal -> Int64 ?
             end;
     
             if Result = Threshold then
               Exit;
            if AcceptOverlap then
            begin
               Inc(BufferCurPos, 1);
               Inc(iReaded, 1);
            end
            else
            begin
               Inc(BufferCurPos, SearchLen);
               Inc(iReaded, SearchLen);
            end;
          end
          else
          begin
             Inc(BufferCurPos, 1);
             Inc(iReaded, 1);
          end;
       end;
    end;
    cela s'utilise avec un
    - @array[0], si tu as stocké ton RTF dans array of byte
    - Stream.Memory si tu as stocké ton RTF TMemoryStream
    - Avec tout pointeur
    - avec @AnsiString[1], si tu as stocké ton RTF dans une chaine, voir le commentaire de Paul Toth
    ...
    Ben voilà C'est exactement ce que je cherchais.
    Mais :
    1/ La fn me retourne 0 même en pointant un buffer contenant effectivement la chaîne . Je dois mal la paramétrer (cf. code ci-dessous)
    2/ Elle respecte la casse ou non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Retour_SearchBinary := // SearchBinaryInBinary(Ptr_Mob_Buffer_Base_Concatenee, // Pointer
                                 Surface_Fiche_Ds_Base,
     	                     Tab_SearchBinary,
    			     Tab_Cardinaux ,
        			     False, // KeepOffset
    			     1,  // Une seule occurrence suffit
    			     False);  // AcceptOverlap
    Je faute quelque part, mais où ?

  16. #16
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 421
    Points : 24 776
    Points
    24 776
    Par défaut
    Ben voilà C'est exactement ce que je cherchais.

    J'ai un peu l'impression que tu attends patiemment que l'on fasse TON Travail !
    Tu n'oublieras pas à nous verser ton salaire sur nos comptes !

    Elle respecte la casse
    C'est une blaque ?
    Comparaison binaire, il n'y a plus de notion de lettre, de casse, c'est des octets brut !
    Donc oui cela respecte la casse !
    Tu ne sais même pas faire la différence entre une manipulation binaire et une manipulation de texte !
    Sais-tu ce que tu fais ?

    On est pas devin !
    même si je lis très bien dans la cerboise, le paté de lapin en croute et dans le sanglier laqué !
    Surface_Fiche_Ds_Base c'est quoi ?
    Est-ce la longueur de Ptr_Mob_Buffer_Base_Concatenee ?

    Commence par une recherche simple, voici ma fonction de débogage de SearchBinaryInBinary

    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
    procedure Toto(AStrings: TStrings);
    const
      Zone: array[1..32] of Byte = (1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4);
      Search4: array[1..4] of Byte = (1, 2, 3, 4);
      Search8: array[1..8] of Byte = (1, 2, 3, 4, 5, 6, 7, 8);
      SearchO: array[1..8] of Byte = (1, 2, 3, 4, 1, 2, 3, 4);
    var
      Search: TByteDynArray; // mon C++ Builder refuse que je passe Search4, Search8 et SearchO directement à SearchBinaryInBinary, je ne sais pas si il y a une différence entre Delphi et le convertisseur Pascal\C++
      OffSets: TCardinalDynArray;
      I: Integer;
    begin
      SetLength(Search, Length(Search4));
      for I := Low(Search) to High(Search) do
        Search[I] := Search4[I + 1];
     
      AStrings.Add('--- 4 normal');
     
      SearchBinaryInBinary(@Zone[1], 32, Search, OffSets, True);
      for I := Low(OffSets) to High(OffSets) do
        AStrings.Add(IntToStr(OffSets[I]));
     
      AStrings.Add('--- 4 over');
     
      SearchBinaryInBinary(@Zone[1], 32, Search, OffSets, True, MaxInt, True);
      for I := Low(OffSets) to High(OffSets) do
        AStrings.Add(IntToStr(OffSets[I]));
     
      SetLength(Search, Length(Search8));
      for I := Low(Search) to High(Search) do
        Search[I] := Search8[I + 1];
     
      AStrings.Add('--- 8 normal');
     
      SearchBinaryInBinary(@Zone[1], 32, Search, OffSets, True);
      for I := Low(OffSets) to High(OffSets) do
        AStrings.Add(IntToStr(OffSets[I]));
     
      AStrings.Add('--- 8 over');
     
      SearchBinaryInBinary(@Zone[1], 32, Search, OffSets, True, MaxInt, True);
      for I := Low(OffSets) to High(OffSets) do
        AStrings.Add(IntToStr(OffSets[I]));
     
      SetLength(Search, Length(SearchO));
      for I := Low(Search) to High(Search) do
        Search[I] := SearchO[I + 1];
     
      AStrings.Add('--- O normal');
     
      SearchBinaryInBinary(@Zone[1], 32, Search, OffSets, True);
      for I := Low(OffSets) to High(OffSets) do
        AStrings.Add(IntToStr(OffSets[I]));
     
      AStrings.Add('--- O over');
     
      SearchBinaryInBinary(@Zone[1], 32, Search, OffSets, True, MaxInt, True);
      for I := Low(OffSets) to High(OffSets) do
        AStrings.Add(IntToStr(OffSets[I]));
    end;
    Lorsque l'on utilise une fonction pour la 1ere fois, il faut passer par une phase d'essai avec des éléments parfaitement maîtrisé !

    Bon Courage !
    Adieu !
    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

Discussions similaires

  1. copier un tableau string dans une arraylist
    Par ouadie99 dans le forum C#
    Réponses: 2
    Dernier message: 18/03/2008, 13h50
  2. Copier un String dans un variant
    Par foued_scorpion dans le forum Visual C++
    Réponses: 2
    Dernier message: 04/11/2006, 00h35
  3. [TP] Copier une variable string dans le presse-papier
    Par astyan dans le forum Turbo Pascal
    Réponses: 7
    Dernier message: 04/08/2006, 23h47
  4. Réponses: 6
    Dernier message: 24/07/2003, 13h39

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