xstream和iPhone SDK之间的Base64编解码器/解码器
问题描述:
我使用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]);
}
任何想法可能会出错?
答
我发现这是我在互联网上找到的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