Получить NSString из NSData, поступающей отдельно - PullRequest
1 голос
/ 21 декабря 2011

Я пишу программу, которая преобразует NSData в NSString с многобайтовой кодировкой. Само преобразование легко, но проблема в том, что NSData поступает отдельно (данные поступают в порядке). Это как

- (void) dataArrived:(NSData*) data{
    NSString* mystr = [[[NSString alloc] initWithData:data encoding:NSShiftJISStringEncoding] autorelease];
    // I want to parse string here and show some view as it arrives.
}

Если данные содержат только 8-битные буквы, это нормально, но я анализирую многобайтовые строковые данные. Поэтому я хочу преобразовать NSData в NSString из заголовка и сохранить недопустимые байты для следующего вызова dataArrived (последний 1 байт может быть оставлен как недопустимый байт для NSShiftJISStringEncoding, поскольку буква SJIS составляет 1 или 2 байта).

Интересно, есть ли у них какой-либо полезный метод или функция для этого? Идеальный метод может принимать NSData и Encoding и возвращать позицию, в которой он находит недопустимую последовательность байтов в NSData.

Ответы [ 3 ]

1 голос
/ 21 декабря 2011

Поскольку Shift JIS кодируется в 1 или 2 байта, можно предположить, что:

  • либо все необработанные данные являются допустимой строкой Shift JIS
  • или первой длины-1 байт - допустимая строка Shift JIS

Итак, мы можем использовать буфер NSMutableData и обрабатывать данные следующим образом:

- (void)dataArrived:(NSData*)data
{
    [_mutableData appendData:data];
    NSUInteger length = [_mutableData length];
    NSString *string = [[[NSString alloc] initWithData:_mutableData
                                              encoding:NSShiftJISStringEncoding] autorelease];

    if ( ! string && length )
    {
        // try without the last byte
        --length;
        string = [[[NSString alloc] initWithBytes:data.bytes
                                           length:length
                                         encoding:NSShiftJISStringEncoding] autorelease];
    }

    if ( ! string && length )
    {
        // we have a problem: the data are invalid
        return;
    }

    // remove processed bytes
    [_mutableData replaceBytesInRange:NSMakeRange(0, length) withBytes:NULL length:0];

    // now, we can append string
}
1 голос
/ 21 декабря 2011

Рассматривали ли вы сбор всех данных и их последующее декодирование сразу?Это было бы намного проще, чем предложенный вами подход, если вам не нужно иметь дело с большими объемами данных.

0 голосов
/ 21 декабря 2011

Как насчет сохранения всех полученных данных, а затем воссоздания строки из обновленных данных?

@interface StringReceiver {
    NSMutableData *_allData;
}
@property (retain, readonly) NSString *string;
- (void)processData:(NSData *)d;
@end

@implementation StringReceiver
- (id)init {
    self = [super init];
    if(self != nil) {
        _allData = [NSMutableData new];
    }
    return self;
}

- (void)dealloc {
    [_allData release];
    [super dealloc];
}

- (NSString *)string {
    NSString *s;
    s = [[NSString alloc] initWithData:_allData encoding:NSShiftJISStringEncoding];
    return [s autorelease];
}

- (void)processData:(NSData *)myData {
    [_allData appendData:myData];
}
@end

Теперь каждый раз, когда вы звоните -[StringReceiver processData:], вы можете позвонить -[StringReceiver string], чтобы получить обновленную строку.

...