void DS::Stream::writeSafeString(const ST::string& value, DS::StringType format) { if (format == e_StringUTF16) { ST::utf16_buffer buffer = value.to_utf16(); uint16_t length = value.size() & 0x0FFF; ST::utf16_buffer work; char16_t* data = work.create_writable_buffer(length); memcpy(data, buffer.data(), length * sizeof(char16_t)); for (uint16_t i=0; i<length; ++i) data[i] = ~data[i]; write<uint16_t>(length | 0xF000); writeBytes(data, length * sizeof(char16_t)); write<char16_t>(0); } else { ST::char_buffer buffer = (format == e_StringUTF8) ? value.to_utf8() : value.to_latin_1(ST::substitute_invalid); uint16_t length = value.size() & 0x0FFF; ST::char_buffer work; char* data = work.create_writable_buffer(length); memcpy(data, buffer.data(), length * sizeof(char)); for (uint16_t i=0; i<length; ++i) data[i] = ~data[i]; write<uint16_t>(length | 0xF000); writeBytes(data, length * sizeof(char)); } }
ST::string DS::Stream::readSafeString(DS::StringType format) { uint16_t length = read<uint16_t>(); if (!(length & 0xF000)) read<uint16_t>(); // Discarded length &= 0x0FFF; if (format == e_StringUTF16) { ST::utf16_buffer result; char16_t* buffer = result.create_writable_buffer(length); ssize_t bytes = readBytes(buffer, length * sizeof(char16_t)); read<char16_t>(); // redundant u'\0' DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(char16_t))); if (length && (buffer[0] & 0x8000)) { for (uint16_t i=0; i<length; ++i) buffer[i] = ~buffer[i]; } buffer[length] = 0; return ST::string::from_utf16(result, ST::substitute_invalid); } else { ST::char_buffer result; char* buffer = result.create_writable_buffer(length); ssize_t bytes = readBytes(buffer, length * sizeof(char)); DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(char))); if (length && (buffer[0] & 0x80)) { for (uint16_t i=0; i<length; ++i) buffer[i] = ~buffer[i]; } buffer[length] = 0; return (format == e_StringUTF8) ? ST::string::from_utf8(result, ST::substitute_invalid) : ST::string::from_latin_1(result); } }
ST::string pnSocket::recvString(size_t maxlen) { uint16_t size; if (recv(&size, sizeof(uint16_t)) <= 0) size = 0; if (size >= maxlen) size = maxlen-1; if (size > 0) { ST::utf16_buffer str; char16_t* buf = str.create_writable_buffer(size); recv(buf, size * sizeof(char16_t)); return ST::string::from_utf16(str); } else { return ST::string(); } }
ST::string DS::Stream::readString(size_t length, DS::StringType format) { if (format == e_StringUTF16) { ST::utf16_buffer result; char16_t* buffer = result.create_writable_buffer(length); ssize_t bytes = readBytes(buffer, length * sizeof(char16_t)); DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(char16_t))); buffer[length] = 0; return ST::string::from_utf16(result, ST::substitute_invalid); } else { ST::char_buffer result; char* buffer = result.create_writable_buffer(length); ssize_t bytes = readBytes(buffer, length * sizeof(char)); DS_DASSERT(bytes == static_cast<ssize_t>(length * sizeof(char))); buffer[length] = 0; return (format == e_StringUTF8) ? ST::string::from_utf8(result, ST::substitute_invalid) : ST::string::from_latin_1(result); } }