Вы должны будете сделать демаршаллинг самостоятельно; к счастью, это довольно просто. Класс Java DataOutputStream
записывает целые числа в формате с прямым порядком байтов (сетевым). Итак, чтобы демаршировать целое число, мы берем 4 байта и распаковываем их в 4-байтовое целое число.
Для строк UTF-8 DataOutputStream
сначала записывает 2-байтовое значение, указывающее число байтов, которые следуют. Мы читаем это в, а затем читаем последующие байты. Затем для декодирования строки мы можем использовать метод NSString
initWithBytes:length:encoding:
следующим образом:
NSData *data = ...; // this comes from the HTTP request
int length = [data length];
const uint8_t *bytes = (const uint8_t *)[data bytes];
if(length < 4)
; // oops, handle error
// demarshall the big-endian integer from 4 bytes
uint32_t myInt = (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | (bytes[3]);
// convert from (n)etwork endianness to (h)ost endianness (may be a no-op)
// ntohl is defined in <arpa/inet.h>
myInt = ntohl(myInt);
// advance to next datum
bytes += 4;
length -= 4;
// demarshall the string length
if(length < 2)
; // oops, handle error
uint16_t myStringLen = (bytes[0] << 8) | (bytes[1]);
// convert from network to host endianness
myStringLen = ntohs(myStringLen);
bytes += 2;
length -= 2;
// make sure we actually have as much data as we say we have
if(myStringLen > length)
myStringLen = (uint16_t)length;
// demarshall the string
NSString *myString = [[NSString alloc] initWithBytes:bytes length:myStringLen encoding:NSUTF8StringEncoding];
bytes += myStringLen;
length -= myStringLen;
Вы можете (и, вероятно, должны) написать функции для demarshall, чтобы вам не приходилось повторять этот код для каждого поля, которое вы хотите demarshall. Кроме того, будьте особенно осторожны относительно переполнения буфера . Вы обрабатываете данные, отправленные по сети, которые вы всегда должны не доверять. Всегда проверяет ваши данные, а всегда проверяет длину вашего буфера.