hessian2/basic_codec/def_ref_codec.cc (78 lines of code) (raw):
#include "hessian2/basic_codec/def_ref_codec.hpp"
namespace Hessian2 {
// class-def ::= 'C' string int string*
// object ::= 'O' int value*
// ::= [x60-x6f] value*
template <>
std::unique_ptr<Object::Definition> Decoder::decode() {
auto ret = reader_->read<uint8_t>();
if (!ret.first) {
return nullptr;
}
Object::RawDefinitionSharedPtr def =
std::make_shared<Object::RawDefinition>();
auto code = ret.second;
if (code == 'C') {
auto type_name = decode<std::string>();
if (!type_name) {
return nullptr;
}
auto field_len = decode<int32_t>();
if (!field_len) {
return nullptr;
}
def->type_ = *type_name;
def->field_names_.reserve(*field_len);
for (int i = 0; i < *field_len; i++) {
auto field_name = decode<std::string>();
if (!field_name) {
return nullptr;
}
def->field_names_.push_back(*field_name);
}
def_ref_.push_back(def);
} else if (code == 'O') {
auto ref_number = decode<int32_t>();
if (!ref_number) {
return nullptr;
}
if (static_cast<uint32_t>(*ref_number) >= def_ref_.size()) {
return nullptr;
}
def = def_ref_[*ref_number];
} else if (code >= 0x60 && code <= 0x6f) {
uint32_t ref_num = code - 0x60;
if (ref_num >= def_ref_.size()) {
return nullptr;
}
def = def_ref_[ref_num];
} else {
return nullptr;
}
return std::make_unique<Object::Definition>(def);
}
// TODO(tianqian.zyf:) Avoid copying definitions
template <>
bool Encoder::encode(const Object::RawDefinition &value) {
auto r = getDefRef(value);
if (r == -1) {
writer_->writeByte('C');
def_ref_.push_back(std::make_shared<Object::RawDefinition>(value));
encode<std::string>(value.type_);
encode<int32_t>(value.field_names_.size());
for (const auto &field_name : value.field_names_) {
encode<std::string>(field_name);
}
encode<Object::RawDefinition>(value);
} else {
if (r <= 15) {
uint8_t code = 0x60 + r;
writer_->writeByte(code);
} else {
writer_->writeByte('O');
encode<int32_t>(r);
}
}
return true;
}
// TODO(tianqian.zyf):
template <>
bool Encoder::encode(const Object::Definition &value) {
return encode<Object::RawDefinition>(*value.data_);
}
} // namespace Hessian2