2011-12-21 5 views
1

NSString을 NSString으로 다중 바이트 인코딩으로 변환하는 프로그램을 작성하고 있습니다. 변환 자체는 쉽지만 문제는 NSData가 개별적으로 도착한다는 것입니다 (데이터가 순서대로 도착했습니다). 데이터는 8 비트 문자는 확인하지만 멀티 바이트 문자열 데이터를 분석하고있어이 포함 된 경우 그것은별도로 도착하는 NSData에서 NSString 가져 오기

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

좋아한다. 그래서 NSData를 머리글에서 NSString으로 변환하고 다음에 dataArrived를 호출하여 유효하지 않은 바이트를 보관합니다 (마지막 1 바이트는 SJIS 문자가 1 또는 2 바이트이므로 NSShiftJISStringEncoding의 유효하지 않은 바이트로 남을 수 있음).

이 작업을 수행하는 데 유용한 방법이나 기능이 있는지 궁금합니다. 이상적인 메서드는 NSData 및 인코딩을 취하여 NSData에서 잘못된 바이트 시퀀스가있는 위치를 반환 할 수 있습니다.

+0

내 답변이 귀하의 질문에 대답하지 않습니까? ;-) –

답변

1

JIS 1 또는 2 바이트에 인코딩 시프트, 당신은 그 가정 할 수 있기 때문에 :

  • 중 모든 처리되지 않은 데이터가 유효한 시프트 JIS 문자열
  • 또는 최초로 길이를 1 바이트가됩니다를 유효 시프트 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 
} 
+0

SJIS 인코딩에는 이상이 없습니다. 나는 모든 인코딩을위한 일반적인 솔루션을 원했지만, 현재 내가 작업하고있는 SJIS를 위해 이것을 사용한다. –

+0

나는 우아한 일반적인 해결책이 두렵다. 대부분의 인코딩은 문자를 인코딩하는 데 1 ~ 4 바이트를 사용하기 때문에 유효한 문자열이나 길이가 0이 될 때까지 반복 할 수 있습니다. –

1

모든 데이터를 수집 한 다음 한꺼번에 모두 데이터를 수집했다고 생각하십니까? 많은 양의 데이터를 다룰 필요가 없다면 제안 된 방법보다 훨씬 간단 할 것입니다.

+0

예. 나는 이미 모든 데이터가 오기를 기다리는 또 다른 대답에 대해 언급했기 때문에 오랜 시간이 걸리고 나는 그것을 피하고 싶다. –

0

수신 된 모든 데이터를 저장 한 다음 업데이트 된 데이터에서 문자열을 다시 생성하는 것은 어떻습니까?

@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]를 호출 할 수 있습니다.

+0

당신이 제안한 것을 이미 구현했습니다. 사용자 경험으로 나는 가능한 한 빨리 데이터에서 얻은 문자열을 보여주고 싶다. (모든 데이터를 기다리는 데 오랜 시간이 걸릴 것이다.) –

+0

그래서'-pocessData :'를 호출 할 때마다'-string'을 호출 할 수있다. 이렇게하면 매번 업데이트 ** 후에 ** 어떤 것을 사용자에게 보여줄 수 있습니다 **. – v1Axvw

+0

오, 나는 당신이 제안한 것을 오해 할 수도 있습니다. 이것은 "문자열"메서드를 호출 할 때마다 나는 지금까지받은 문자열을 얻을 수 있다는 것을 의미합니다. –