Pergunta

Eu tenho um arquivo binário que eu carregado usando um objeto NSData. Existe uma maneira para localizar uma sequência de caracteres, 'abcd', por exemplo, dentro de que os dados binários e retornar o deslocamento sem converter o arquivo inteiro para uma string? Parece que deve haver uma resposta simples, mas eu não tenho certeza de como fazê-lo. Alguma idéia?

Estou fazendo isso no iOS 3 para que eu não tenho -rangeOfData:options:range: disponível.

Eu estou indo para o prêmio deste um para Sixteen Otto para sugerir strstr. Fui e o código-fonte para a função strstr C e reescrevi de trabalho em uma matriz de comprimento fixo de bytes - que, aliás, é diferente de uma matriz de carvão animal, uma vez que não é nulo terminada. Aqui está o código que acabou com:

- (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;
}

A retorna um ponteiro para a primeira ocorrência de bytes, a coisa que estou procurando, em tampão, a matriz de bytes que deve conter bytes.

Eu chamo-lhe assim:

// data is the NSData object
const Byte *bytes = [data bytes];
Byte* index = [self offsetOfBytes:tag inBuffer:bytes ofLength:[data length]];
Foi útil?

Solução

Converter seu substring a um objeto NSData, e procurar os bytes na NSData maior usando rangeOfData:options:range: . Certifique-se de que as codificações corda combinar!

iPhone On, onde que não está disponível, você pode ter que fazer isso sozinho. A função C strstr() lhe dará um ponteiro para a primeira ocorrência de um padrão dentro da memória tampão (contanto que não contêm nulos!), Mas não o índice. Aqui está uma função que deve fazer o trabalho (mas sem promessas, já que eu não tentei realmente executá-lo ...):

- (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;
}

isto corre em algo como S (nm), em que n é o comprimento do buffer, e m é o tamanho da subcadeia. É escrito para trabalhar com NSData por duas razões: 1.) Isso é o que parece ter na mão, e 2) os objetos já encapsular ambos os bytes reais, e o comprimento do buffer

Outras dicas

Se você estiver usando o Snow Leopard, uma maneira conveniente é o novo -rangeOfData: opções: intervalo: método em NSData que retorna o intervalo da primeira ocorrência de um pedaço de dados . Caso contrário, você pode acessar o conteúdo do NSData-se usando seu -bytes método para realizar sua própria pesquisa.

Eu tive o mesmo problema. Eu resolvi fazer o contrário, em comparação com as sugestões.

Em primeiro lugar, eu reformatar os dados (assumir o seu NSData é armazenado em var RawFile) com:

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

Agora, você pode facilmente fazer pesquisas de cadeia como 'abcd' ou o que quiser usando a classe NSScanner e passar a seqüência de caracteres ASCII para o scanner. Talvez isso não é realmente eficiente, mas funciona até que o método -rangeOfData estará disponível para iPhone também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top