in hessian2/basic_codec/string_codec.cc [427:506]
bool Encoder::encode(const absl::string_view &data) {
Uint64Vector per_chunk_bytes_offsets;
Uint64Vector four_bytes_char_offsets;
int64_t length = getUtf8StringLengthAndPerChunkOffsets(
data, per_chunk_bytes_offsets, four_bytes_char_offsets);
if (length == -1) {
return false;
}
absl::string_view data_view = data;
#ifdef COMPATIBLE_WITH_JAVA_HESSIAN_LITE
std::string rewrite_data;
if (!four_bytes_char_offsets.empty()) {
rewrite_data = escapeFourBytesUtf8Char(data, four_bytes_char_offsets);
if (rewrite_data.empty()) {
return false;
}
per_chunk_bytes_offsets.clear();
four_bytes_char_offsets.clear();
length = getUtf8StringLengthAndPerChunkOffsets(
rewrite_data, per_chunk_bytes_offsets, four_bytes_char_offsets);
data_view = rewrite_data;
}
// Check length again.
if (length == -1) {
return false;
}
#endif
// Java's 16-bit integers are signed, so the maximum value is 32768
uint32_t str_offset = 0;
const uint16_t step_length = STRING_CHUNK_SIZE;
int pos = 0;
while (static_cast<uint64_t>(length) > STRING_CHUNK_SIZE) {
writer_->writeByte(0x52);
writer_->writeBE<uint16_t>(step_length);
length -= step_length;
auto raw_offset = per_chunk_bytes_offsets[pos++];
writer_->rawWrite(data_view.substr(str_offset, raw_offset - str_offset));
str_offset = raw_offset;
}
if (length == 0) {
// x00 # "", empty string
writer_->writeByte(0x00);
return true;
}
const size_t data_view_size = data_view.size();
if (length <= 31) {
// [x00-x1f] <utf8-data>
// Compact: short strings
writer_->writeByte(length);
writer_->rawWrite(
data_view.substr(str_offset, data_view_size - str_offset));
return true;
}
// [x30-x34] <utf8-data>
if (length <= 1023) {
uint8_t code = length / 256;
uint8_t remain = length % 256;
writer_->writeByte(0x30 + code);
writer_->writeByte(remain);
writer_->rawWrite(
data_view.substr(str_offset, data_view_size - str_offset));
return true;
}
writer_->writeByte(0x53);
writer_->writeBE<uint16_t>(length);
writer_->rawWrite(data_view.substr(str_offset, data_view_size - str_offset));
return true;
}