in thrift/lib/cpp2/protocol/TableBasedSerializerImpl.h [146:403]
void read(
Protocol_* iprot,
const TypeInfo& typeInfo,
ProtocolReaderStructReadState<Protocol_>& readState,
void* object) {
using WireTypeInfo = ProtocolReaderWireTypeInfo<Protocol_>;
using WireType = typename WireTypeInfo::WireType;
switch (typeInfo.type) {
case protocol::TType::T_STRUCT:
readState.beforeSubobject(iprot);
read<Protocol_>(
iprot,
*static_cast<const StructInfo*>(typeInfo.typeExt),
typeInfo.set ? invokeStructSet(typeInfo, object) : object);
readState.afterSubobject(iprot);
break;
case protocol::TType::T_I64: {
std::int64_t temp;
iprot->readI64(temp);
reinterpret_cast<void (*)(void*, std::int64_t)>(typeInfo.set)(
object, temp);
break;
}
case protocol::TType::T_I32: {
std::int32_t temp;
iprot->readI32(temp);
reinterpret_cast<void (*)(void*, std::int32_t)>(typeInfo.set)(
object, temp);
break;
}
case protocol::TType::T_I16: {
std::int16_t temp;
iprot->readI16(temp);
reinterpret_cast<void (*)(void*, std::int16_t)>(typeInfo.set)(
object, temp);
break;
}
case protocol::TType::T_BYTE: {
std::int8_t temp;
iprot->readByte(temp);
reinterpret_cast<void (*)(void*, std::int8_t)>(typeInfo.set)(
object, temp);
break;
}
case protocol::TType::T_BOOL: {
bool temp;
iprot->readBool(temp);
reinterpret_cast<void (*)(void*, bool)>(typeInfo.set)(object, temp);
break;
}
case protocol::TType::T_DOUBLE: {
double temp;
iprot->readDouble(temp);
reinterpret_cast<void (*)(void*, double)>(typeInfo.set)(object, temp);
break;
}
case protocol::TType::T_FLOAT: {
float temp;
iprot->readFloat(temp);
reinterpret_cast<void (*)(void*, float)>(typeInfo.set)(object, temp);
break;
}
case protocol::TType::T_STRING: {
switch (*static_cast<const StringFieldType*>(typeInfo.typeExt)) {
case StringFieldType::String:
iprot->readString(*static_cast<std::string*>(object));
break;
case StringFieldType::StringView: {
std::string temp;
iprot->readBinary(temp);
reinterpret_cast<void (*)(void*, const std::string&)>(typeInfo.set)(
object, temp);
break;
}
case StringFieldType::Binary:
iprot->readBinary(*static_cast<std::string*>(object));
break;
case StringFieldType::IOBufObj: {
const OptionalThriftValue value = getValue(typeInfo, object);
if (value.hasValue()) {
iprot->readBinary(*value.value().iobuf);
} else {
folly::IOBuf temp;
iprot->readBinary(temp);
reinterpret_cast<void (*)(void*, const folly::IOBuf&)>(
typeInfo.set)(object, temp);
}
break;
}
case StringFieldType::IOBuf:
iprot->readBinary(*static_cast<folly::IOBuf*>(object));
break;
case StringFieldType::IOBufPtr:
iprot->readBinary(
*static_cast<std::unique_ptr<folly::IOBuf>*>(object));
break;
}
break;
}
case protocol::TType::T_MAP: {
readState.beforeSubobject(iprot);
// Initialize the container to clear out current values.
auto* actualObject = invokeSet(typeInfo.set, object);
const MapFieldExt& ext =
*static_cast<const MapFieldExt*>(typeInfo.typeExt);
std::uint32_t size = ~0;
WireType reportedKeyType = WireTypeInfo::defaultValue();
WireType reportedMappedType = WireTypeInfo::defaultValue();
iprot->readMapBegin(reportedKeyType, reportedMappedType, size);
struct Context {
const TypeInfo* keyInfo;
const TypeInfo* valInfo;
Protocol_* iprot;
ProtocolReaderStructReadState<Protocol_>& readState;
};
const Context context = {
ext.keyInfo,
ext.valInfo,
iprot,
readState,
};
auto const keyReader = [](const void* context, void* key) {
const auto& typedContext = *static_cast<const Context*>(context);
read(
typedContext.iprot,
*typedContext.keyInfo,
typedContext.readState,
key);
};
auto const valueReader = [](const void* context, void* val) {
const auto& typedContext = *static_cast<const Context*>(context);
read(
typedContext.iprot,
*typedContext.valInfo,
typedContext.readState,
val);
};
if (iprot->kOmitsContainerSizes()) {
while (iprot->peekMap()) {
ext.consumeElem(&context, actualObject, keyReader, valueReader);
}
} else {
if (size > 0 &&
(ext.keyInfo->type != reportedKeyType ||
ext.valInfo->type != reportedMappedType)) {
skip_n(*iprot, size, {reportedKeyType, reportedMappedType});
} else {
if (!canReadNElements(
*iprot, size, {reportedKeyType, reportedMappedType})) {
protocol::TProtocolException::throwTruncatedData();
}
ext.readMap(&context, actualObject, size, keyReader, valueReader);
}
}
iprot->readMapEnd();
readState.afterSubobject(iprot);
break;
}
case protocol::TType::T_SET: {
readState.beforeSubobject(iprot);
// Initialize the container to clear out current values.
auto* actualObject = invokeSet(typeInfo.set, object);
const SetFieldExt& ext =
*static_cast<const SetFieldExt*>(typeInfo.typeExt);
std::uint32_t size = ~0;
WireType reportedType = WireTypeInfo::defaultValue();
iprot->readSetBegin(reportedType, size);
struct Context {
const TypeInfo* valInfo;
Protocol_* iprot;
ProtocolReaderStructReadState<Protocol_>& readState;
};
const Context context = {
ext.valInfo,
iprot,
readState,
};
auto const reader = [](const void* context, void* value) {
const auto& typedContext = *static_cast<const Context*>(context);
read(
typedContext.iprot,
*typedContext.valInfo,
typedContext.readState,
value);
};
if (iprot->kOmitsContainerSizes()) {
while (iprot->peekSet()) {
ext.consumeElem(&context, actualObject, reader);
}
} else {
if (reportedType != ext.valInfo->type) {
skip_n(*iprot, size, {reportedType});
} else {
if (!canReadNElements(*iprot, size, {reportedType})) {
protocol::TProtocolException::throwTruncatedData();
}
ext.readSet(&context, actualObject, size, reader);
}
}
iprot->readSetEnd();
readState.afterSubobject(iprot);
break;
}
case protocol::TType::T_LIST: {
readState.beforeSubobject(iprot);
// Initialize the container to clear out current values.
auto* actualObject = invokeSet(typeInfo.set, object);
const ListFieldExt& ext =
*static_cast<const ListFieldExt*>(typeInfo.typeExt);
std::uint32_t size = ~0;
WireType reportedType = WireTypeInfo::defaultValue();
iprot->readListBegin(reportedType, size);
struct Context {
const TypeInfo* valInfo;
Protocol_* iprot;
ProtocolReaderStructReadState<Protocol_>& readState;
};
const Context context = {
ext.valInfo,
iprot,
readState,
};
auto const reader = [](const void* context, void* value) {
const auto& typedContext = *static_cast<const Context*>(context);
read(
typedContext.iprot,
*typedContext.valInfo,
typedContext.readState,
value);
};
if (iprot->kOmitsContainerSizes()) {
while (iprot->peekList()) {
ext.consumeElem(&context, actualObject, reader);
}
} else {
if (reportedType != ext.valInfo->type) {
skip_n(*iprot, size, {reportedType});
} else {
if (!canReadNElements(*iprot, size, {reportedType})) {
protocol::TProtocolException::throwTruncatedData();
}
ext.readList(&context, actualObject, size, reader);
}
}
iprot->readListEnd();
readState.afterSubobject(iprot);
break;
}
case protocol::TType::T_STOP:
case protocol::TType::T_VOID:
case protocol::TType::T_UTF8:
case protocol::TType::T_U64:
case protocol::TType::T_UTF16:
case protocol::TType::T_STREAM:
skip(iprot, readState);
}
}