Base64 en / декодирование между xstream и iPhone SDK - PullRequest
0 голосов
/ 05 мая 2010

Я передаю байтовый массив с java-сервера клиенту iPad в XML. Сервер использует xstream для преобразования байтового массива в XML с помощью EncodedByteArrayConverter, который должен преобразовать массив в Base 64. Используя xstream, я могу декодировать xml обратно в соответствующий байтовый массив в клиенте Java, но в клиенте 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]);
}

Есть идеи, что может пойти не так?

1 Ответ

0 голосов
/ 05 мая 2010

Я обнаружил, что это была разница между декодером 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
...