in core/indigo-core/molecule/src/cmf_loader.cpp [89:284]
bool CmfLoader::_readAtom(int& code, _AtomDesc& atom, int atom_idx)
{
if (code > 0 && code < ELEM_MAX)
atom.label = code;
else if (code == CMF_PSEUDOATOM)
{
int len;
if (!_getNextCode(len))
throw Error("pseudo-atom identifier must be followed by length");
if (len < 1)
throw Error("empty pseudo-atom");
atom.pseudo_atom_idx = _pseudo_labels.add(len + 1);
char* label = _pseudo_labels.at(atom.pseudo_atom_idx);
for (int i = 0; i < len; i++)
{
int c;
if (!_getNextCode(c))
throw Error("pseudo-atom label is incomplete");
label[i] = static_cast<char>(c);
}
label[len] = 0;
}
else if (code == CMF_RSITE)
{
atom.label = ELEM_RSITE;
_getNextCode(atom.rsite_bits);
}
else if (code == CMF_RSITE_EXT)
{
atom.label = ELEM_RSITE;
atom.rsite_bits = (int)_scanner->readPackedUInt();
}
else
throw Error("bad atom number: %d", code);
if (!_getNextCode(code))
return false;
if (code >= CMF_CHARGES && code < CMF_CHARGES + CMF_NUM_OF_CHARGES && code != CMF_SEPARATOR)
{
int charge = code - CMF_CHARGES;
charge += CMF_MIN_CHARGE;
atom.charge = charge;
if (!_getNextCode(code))
return false;
}
if (code == CMF_CHARGE_EXT)
{
int charge;
_getNextCode(charge);
charge -= 128;
atom.charge = charge;
if (!_getNextCode(code))
return false;
}
if (code >= CMF_ISOTOPE_ZERO && code <= CMF_ISOTOPE_OTHER)
{
int deviation;
if (code == CMF_ISOTOPE_ZERO)
deviation = 0;
else if (code == CMF_ISOTOPE_PLUS1)
deviation = 1;
else if (code == CMF_ISOTOPE_PLUS2)
deviation = 2;
else if (code == CMF_ISOTOPE_MINUS1)
deviation = -1;
else if (code == CMF_ISOTOPE_MINUS2)
deviation = -2;
else // CMF_ISOTOPE_OTHER
{
if (!_getNextCode(code))
throw Error("expecting mass difference");
deviation = code - 100;
}
atom.isotope = Element::getDefaultIsotope(atom.label) + deviation;
if (!_getNextCode(code))
return false;
}
if (code >= CMF_RADICAL_SINGLET && code <= CMF_RADICAL_TRIPLET)
{
if (code == CMF_RADICAL_SINGLET)
atom.radical = RADICAL_SINGLET;
else if (code == CMF_RADICAL_DOUBLET)
atom.radical = RADICAL_DOUBLET;
else // code == CMF_RADICAL_TRIPLET
atom.radical = RADICAL_TRIPLET;
if (!_getNextCode(code))
return false;
}
if (code >= CMF_STEREO_ANY && code <= CMF_STEREO_ABS_1)
{
if (code >= CMF_STEREO_AND_1)
{
/* CMF_STEREO_*_1 -> CMF_STEREO_*_0 */
code -= CMF_MAX_STEREOGROUPS * 2 + 1;
atom.stereo_invert_pyramid = true;
}
if (code == CMF_STEREO_ANY)
atom.stereo_type = MoleculeStereocenters::ATOM_ANY;
else if (code == CMF_STEREO_ABS_0)
atom.stereo_type = MoleculeStereocenters::ATOM_ABS;
else if (code < CMF_STEREO_OR_0)
{
atom.stereo_type = MoleculeStereocenters::ATOM_AND;
atom.stereo_group = code - CMF_STEREO_AND_0 + 1;
}
else
{
atom.stereo_type = MoleculeStereocenters::ATOM_OR;
atom.stereo_group = code - CMF_STEREO_OR_0 + 1;
}
if (!_getNextCode(code))
return false;
}
if (code == CMF_STEREO_ALLENE_0 || code == CMF_STEREO_ALLENE_1)
{
if (code == CMF_STEREO_ALLENE_0)
atom.allene_stereo_parity = 1;
else
atom.allene_stereo_parity = 2;
if (!_getNextCode(code))
return false;
}
if (code >= CMF_IMPLICIT_H && code <= CMF_IMPLICIT_H + CMF_MAX_IMPLICIT_H)
{
atom.hydrogens = code - CMF_IMPLICIT_H;
if (!_getNextCode(code))
return false;
}
if (code >= CMF_VALENCE && code <= CMF_VALENCE + CMF_MAX_VALENCE)
{
atom.valence = code - CMF_VALENCE;
if (!_getNextCode(code))
return false;
}
if (code == CMF_VALENCE_EXT)
{
atom.valence = (int)_scanner->readPackedUInt();
if (!_getNextCode(code))
return false;
}
while (code == CMF_ATTACHPT)
{
int aidx;
if (!_getNextCode(aidx))
throw Error("expected attachment index");
_AttachmentDesc& att = _attachments.push();
att.atom = atom_idx;
att.index = aidx;
if (!_getNextCode(code))
return false;
}
while (code >= CMF_ATOM_FLAGS && code < CMF_ATOM_FLAGS + CMF_NUM_OF_ATOM_FLAGS)
{
atom.flags |= (1 << (code - CMF_ATOM_FLAGS));
if (!_getNextCode(code))
return false;
}
if (code == CMF_HIGHLIGHTED)
{
atom.highlighted = true;
if (!_getNextCode(code))
return false;
}
return true;
}