0

我正在将一个字节数组从 Java 服务器传递到 XML 中的 iPad 客户端。服务器正在使用 xstream 使用EncodedByteArrayConverter将字节数组转换为 XML,这应该将数组转换为 Base 64。使用 xstream,我可以在 java 客户端中将 xml 解码回正确的字节数组,但在 iPad 客户端中,我收到一个无效的长度错误。为了进行解码,我使用了本页底部的代码。字符串的长度确实不是4 的倍数,所以我的字符串一定有一些奇怪的地方——尽管由于 xstream 可以很好地解码它,我猜我需要在 iPad 端做一些事情来让它解码。我尝试在字符串末尾切断填充以将其缩小到正确的大小,这确实允许解码器工作,但我最终得到的 JPG 具有无效的标题,并且无法显示。

在服务器端,我使用以下代码:

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]);
}

有什么想法可能会出错吗?

4

1 回答 1

0

我发现这是我在互联网上找到的 Base64 解码器和 XStream 使用的编码器之间的区别。我重新设计了解码器以匹配 XStream 实现中的解码器,这个解码器似乎工作得很好。我写得很快,所以可能存在错误/效率低下。这是直接基于 XStream Base64 实现的,该实现在 XStream 源代码中可用。

@implementation XStreamBase64

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

static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
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
于 2010-05-05T17:26:12.800 回答