0

XML で Java サーバーから 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 ソース コードで利用可能な XStream Base64 実装に直接基づいています。

@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 に答える