2010-05-04 101 views
0

我使用XML將java服務器中的字節數組傳遞給iPad客戶端。服務器正在使用xstream將字節數組轉換爲帶有EncodedByteArrayConverter的XML,後者應該將數組轉換爲Base 64.使用xstream,我可以將xml解碼回java客戶端中正確的字節數組,但在iPad客戶端中,我收到了無效的長度錯誤。爲了解碼,我使用this頁面底部的代碼。字符串的長度確實是而不是是4的倍數,所以我的字符串肯定有些奇怪 - 儘管由於xstream可以對它進行解碼,所以我猜測我只需要在iPad端對讓它解碼。我已經嘗試在字符串的末尾切斷填充以將其縮小到合適的大小,並且確實允許解碼器正常工作,但是我最終得到的JPG的頭部無效,並且不可顯示。xstream和iPhone SDK之間的Base64編解碼器/解碼器

在服務器端,我用下面的代碼:

Object rtrn = getByteArray(); 
XStream xstream = new XStream(); 
String xml = xstream.toXML(rtrn); 

在客戶端,我打電話從XML解析回調上面的解碼器是這樣的:

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{ 
    NSLog(@"Converting data; string length: %d", [string length]); 
    //NSLog(@"%@", string); 
    NSData *data = [Base64 decode:string]; 
    NSLog(@"converted data length: %d", [data length]); 
} 

任何想法可能會出錯?

回答

0

我發現這是我在互聯網上找到的Base64解碼器和XStream使用的編碼器之間的區別。我重新編譯瞭解碼器以匹配XStream實現中的解碼器,而這個解碼器似乎效果很好。我寫得很快,所以可能會有錯誤/效率低下。這直接基於XStream源代碼中提供的XStream Base64實現。

@implementation XStreamBase64 

#define ArrayLength(x) (sizeof(x)/sizeof(*(x))) 

static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 
static char decodingTable[123]; 
static int decIdx = 0; 

+ (void) initialize { 
    if (self == [XStreamBase64 class]) { 
     memset(decodingTable, 0, ArrayLength(decodingTable)); 
     for (NSInteger i = 0; i < ArrayLength(encodingTable); i++) { 
      decodingTable[encodingTable[i]] = i+1; 
     } 
    } 
} 

+(NSData*) decode:(NSString*)string 
{ 
    NSInteger outputLength = string.length * 3/4; 
    NSMutableData *data = [NSMutableData dataWithLength:outputLength]; 
    uint8_t *output = data.mutableBytes; 

    decIdx = 0; 
    int oIdx = 0; 

    for(int i = 0;i < string.length;i+=4) 
    { 
     int a[4]; 
     a[0] = [self mapCharToInt:string]; 
     a[1] = [self mapCharToInt:string]; 
     a[2] = [self mapCharToInt:string]; 
     a[3] = [self mapCharToInt:string]; 

     int oneBigNumber = (a[0] & 0x3f) << 18 | (a[1] & 0x3f) << 12 | (a[2] & 0x3f) << 6 | (a[3] & 0x3f); 
     for(int j = 0;j < 3;j++) 
     { 
      if(a[j + 1] >= 0) 
      { 
       output[oIdx] = 0xff & oneBigNumber >> 8 * (2 - j); 
       oIdx++; 
      } 
     }   
    } 

    return data; 
} 

+(int) mapCharToInt:(NSString*)string 
{ 
    while(decIdx < string.length) 
    { 
     int c = [string characterAtIndex:decIdx]; 
     int result = decodingTable[c]; 
     decIdx++; 
     if(result != 0) return result - 1; 
     if(c == '=') return -1; 
    } 

    return -1; 
} 
@end