Question

J'ai un fichier binaire que j'ai chargé à l'aide d'un objet NSData. Est-il possible de localiser une séquence de caractères, « abcd », par exemple, dans ce que les données binaires et retourner le décalage sans convertir le fichier entier à une chaîne? On dirait que ce devrait être une réponse simple, mais je ne sais pas comment le faire. Toutes les idées?

Je fais cela sur iOS 3, donc je n'ai pas -rangeOfData:options:range: disponible.

Je vais d'attribuer celui-ci à seize Otto pour suggérer strstr. Je suis et trouvé que le code source de la fonction C strstr et réécrit pour travailler sur une longueur fixe tableau d'octets - qui est d'ailleurs différente d'un tableau de caractères comme elle est nulle terminée pas. Voici le code que je fini avec:

- (Byte*)offsetOfBytes:(Byte*)bytes inBuffer:(const Byte*)buffer ofLength:(int)len;
{
    Byte *cp = bytes;
    Byte *s1, *s2;

    if ( !*buffer )
        return bytes;

    int i = 0;
    for (i=0; i < len; ++i)
    {
        s1 = cp;
        s2 = (Byte*)buffer;

        while ( *s1 && *s2 && !(*s1-*s2) )
            s1++, s2++;

        if (!*s2)
            return cp;

        cp++;
    }

    return NULL;
}

renvoie un pointeur sur la première occurrence d'octets, la chose que je cherche, dans un tampon, le tableau d'octets qui doit contenir octets.

Je l'appelle comme ceci:

// data is the NSData object
const Byte *bytes = [data bytes];
Byte* index = [self offsetOfBytes:tag inBuffer:bytes ofLength:[data length]];
Était-ce utile?

La solution

Convertir votre sous-chaîne à un objet NSData et rechercher ces octets dans le NSData plus en utilisant rangeOfData:options:range: . Assurez-vous que la chaîne encodages match!

Sur l'iPhone, où ce n'est pas disponible, vous pouvez avoir à faire vous-même. La fonction C strstr() vous donnera un pointeur sur la première occurrence d'un modèle dans le tampon (aussi longtemps que ne contient nulls!), Mais pas l'indice. Voici une fonction qui devrait faire le travail (mais pas de promesses, puisque je ne l'ai pas essayé réellement en cours d'exécution ...):

- (NSUInteger)indexOfData:(NSData*)needle inData:(NSData*)haystack
{
    const void* needleBytes = [needle bytes];
    const void* haystackBytes = [haystack bytes];

    // walk the length of the buffer, looking for a byte that matches the start
    // of the pattern; we can skip (|needle|-1) bytes at the end, since we can't
    // have a match that's shorter than needle itself
    for (NSUInteger i=0; i < [haystack length]-[needle length]+1; i++)
    {
        // walk needle's bytes while they still match the bytes of haystack
        // starting at i; if we walk off the end of needle, we found a match
        NSUInteger j=0;
        while (j < [needle length] && needleBytes[j] == haystackBytes[i+j])
        {
            j++;
        }
        if (j == [needle length])
        {
            return i;
        }
    }
    return NSNotFound;
}

Cela va à quelque chose comme O (nm), où n est la longueur du tampon, et m est la taille de la sous-chaîne. Il est écrit à travailler avec NSData pour deux raisons:. 1) est ce que vous semblez avoir en main, et 2) les objets encapsulent déjà deux octets réels, et la longueur du tampon

Autres conseils

Si vous utilisez Snow Leopard, un moyen pratique est la nouvelle -rangeOfData: Options: Gamme: méthode NSData qui renvoie la plage de la première occurrence d'un élément de données . Dans le cas contraire, vous pouvez accéder au contenu de la NSData vous en utilisant sa méthode -bytes pour effectuer votre recherche.

J'ai eu le même problème. Je l'ai résolu de faire l'inverse, par rapport aux suggestions.

Tout d'abord, les données que je reformater (en supposant que votre NSData est stocké dans var rawFile) avec:

NSString *ascii = [[NSString alloc] initWithData:rawFile encoding:NSAsciiStringEncoding];

Maintenant, vous pouvez facilement faire des recherches de chaîne comme « ABCD » ou tout ce que vous voulez utiliser la classe NSScanner et passer la chaîne ascii au scanner. Peut-être que ce n'est pas vraiment efficace, mais cela fonctionne jusqu'à ce que la méthode -rangeOfData sera disponible pour iPhone aussi.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top