in core/indigo-core/molecule/src/molecule_cdxml_saver.cpp [135:351]
void MoleculeCdxmlSaver::writeBinaryValue(const XMLAttribute* pAttr, int16_t tag, ECDXType cdx_type)
{
_output.writeBinaryUInt16(tag);
switch (cdx_type)
{
case ECDXType::CDXString: {
std::string val = pAttr->Value();
uint16_t styles = 0;
_output.writeBinaryUInt16(static_cast<uint16_t>(val.size() + sizeof(styles)));
_output.writeBinaryUInt16(styles);
_output.write(val.data(), static_cast<int>(val.size()));
}
break;
case ECDXType::CDXUINT8:
case ECDXType::CDXINT8: {
int8_t val;
switch (tag)
{
case kCDXProp_CaptionJustification:
case kCDXProp_Justification:
case kCDXProp_LabelJustification:
val = kTextJustificationStrToInt.at(pAttr->Value());
break;
case kCDXProp_LabelAlignment:
case kCDXProp_Node_LabelDisplay:
val = kLabelAlignmentStrToInt.at(pAttr->Value());
break;
case kCDXProp_Atom_Radical:
val = static_cast<int8_t>(kRadicalStrToId.at(pAttr->Value()));
break;
case kCDXProp_Bond_CIPStereochemistry:
val = kCIPBondStereochemistryIndexToChar.at(pAttr->Value()[0]);
break;
case kCDXProp_Atom_CIPStereochemistry:
val = kCIPStereochemistryCharToIndex.at(pAttr->Value()[0]);
break;
case kCDXProp_Arrow_Type:
val = static_cast<int8_t>(kCDXProp_Arrow_TypeStrToID.at(pAttr->Value()));
break;
case kCDXProp_Atom_Geometry:
val = static_cast<int8_t>(KGeometryTypeNameToInt.at(pAttr->Value()));
break;
case kCDXProp_Atom_EnhancedStereoType:
val = static_cast<int8_t>(kCDXEnhancedStereoStrToID.at(pAttr->Value()));
break;
default:
val = static_cast<int8_t>(pAttr->IntValue());
break;
}
_output.writeBinaryUInt16(sizeof(val));
_output.writeByte(val);
}
break;
case ECDXType::CDXINT16:
case ECDXType::CDXUINT16: {
int16_t val = static_cast<int16_t>(pAttr->IntValue());
switch (tag)
{
case kCDXProp_Node_Type:
val = static_cast<int16_t>(KNodeTypeNameToInt.at(pAttr->Value()));
break;
case kCDXProp_Graphic_Type:
val = static_cast<int16_t>(kCDXPropGraphicTypeStrToID.at(pAttr->Value()));
break;
case kCDXProp_Rectangle_Type: {
auto vecs = split(pAttr->Value(), ' ');
for (auto str_val : vecs)
val |= kRectangleTypeStrToInt.at(str_val);
}
break;
case kCDXProp_BondSpacing:
val *= kBondSpacingMultiplier;
break;
case kCDXProp_Line_Type:
val = static_cast<int16_t>(kLineTypeStrToInt.at(pAttr->Value()));
break;
case kCDXProp_Arrow_Type:
val = static_cast<int16_t>(kCDXProp_Arrow_TypeStrToID.at(pAttr->Value()));
break;
case kCDXProp_Arrow_ArrowHead_Head:
case kCDXProp_Arrow_ArrowHead_Tail:
val = kCDXProp_Arrow_ArrowHeadStrToInt.at(pAttr->Value());
break;
case kCDXProp_Arrowhead_Type: {
auto it = kCDXProp_Arrow_ArrowHeadTypeStrToInt.find(pAttr->Value());
if (it != kCDXProp_Arrow_ArrowHeadTypeStrToInt.end())
val = it->second;
break;
}
case kCDXProp_Symbol_Type: {
auto it = kCDXPropSymbolTypeStrToID.find(pAttr->Value());
if (it != kCDXPropSymbolTypeStrToID.end())
val = it->second;
break;
}
case kCDXProp_Bond_Display:
case kCDXProp_Bond_Display2:
val = static_cast<int16_t>(kCDXProp_Bond_DisplayStrToID.at(pAttr->Value()));
break;
case kCDXProp_Bond_Order: {
auto vals = split(pAttr->Value(), ' ');
val = 0;
for (auto& value : vals)
{
val |= static_cast<int16_t>(kBondOrderStrToId.at(value));
}
if (val == 0)
val = -1;
}
break;
}
_output.writeBinaryUInt16(sizeof(val));
_output.writeBinaryUInt16(val);
}
break;
case ECDXType::CDXINT32:
case ECDXType::CDXUINT32: {
int32_t val = pAttr->IntValue();
if (tag == kCDXProp_ChainAngle)
val <<= 16;
_output.writeBinaryUInt16(sizeof(val));
_output.writeBinaryInt(val);
}
break;
case ECDXType::CDXPoint3D:
case ECDXType::CDXPoint2D:
case ECDXType::CDXRectangle: {
std::string values = pAttr->Value();
auto vec_strs = split(values, ' ');
if (vec_strs.size() % 2 == 0)
{
for (size_t i = 0; i < vec_strs.size(); i += 2)
std::swap(vec_strs[i], vec_strs[i + 1]);
}
_output.writeBinaryUInt16(static_cast<uint16_t>(sizeof(int32_t) * vec_strs.size()));
for (const auto& v : vec_strs)
{
int32_t coord = static_cast<int32_t>(std::stof(v) * (1 << 16));
_output.writeBinaryInt(coord);
}
}
break;
case ECDXType::CDXCoordinate: {
int32_t coord = static_cast<int32_t>(pAttr->FloatValue() * (1 << 16));
_output.writeBinaryUInt16(sizeof(coord));
_output.writeBinaryInt(coord);
}
break;
case ECDXType::CDXBooleanImplied:
case ECDXType::CDXBoolean: {
uint8_t val = std::string(pAttr->Value()) == "yes" ? 1 : 0;
_output.writeBinaryUInt16(sizeof(val));
_output.writeByte(val);
}
break;
case ECDXType::CDXObjectID: {
uint32_t val = pAttr->IntValue();
_output.writeBinaryUInt16(sizeof(val));
_output.writeBinaryInt(val);
}
break;
case ECDXType::CDXUnformatted: {
std::string values = pAttr->Value();
std::vector<uint8_t> bytes_vector;
for (size_t i = 0; i < values.size(); i += 2)
{
uint32_t val;
std::string hex_str = values.substr(i, 2);
std::stringstream converter;
converter << std::hex << hex_str;
converter >> val;
bytes_vector.push_back(static_cast<uint8_t>(val));
}
_output.writeBinaryUInt16(static_cast<uint16_t>(bytes_vector.size()));
_output.write(bytes_vector.data(), static_cast<int>(bytes_vector.size()));
}
break;
case ECDXType::CDXObjectIDArray: {
std::string values = pAttr->Value();
auto vals = split(values, ' ');
_output.writeBinaryUInt16(static_cast<uint16_t>(vals.size() * sizeof(int32_t)));
for (const auto& val : vals)
_output.writeBinaryInt(std::stoi(val));
}
break;
case ECDXType::CDXDate:
case ECDXType::CDXRepresentsProperty:
case ECDXType::CDXFontTable:
case ECDXType::CDXColorTable:
case ECDXType::CDXElementList:
case ECDXType::CDXFormula:
case ECDXType::CDXObjectIDArrayWithCounts:
case ECDXType::CDXGenericList:
case ECDXType::CDXFLOAT64:
case ECDXType::CDXINT16ListWithCounts:
case ECDXType::CDXCurvePoints:
case ECDXType::CDXCurvePoints3D:
case ECDXType::CDXvaries:
case ECDXType::CDXFontStyle:
throw Error("Unsupported type: %d", cdx_type);
break;
default:
break;
}
}