in core/indigo-core/molecule/src/molfile_loader.cpp [3444:3797]
void MolfileLoader::_readSGroup3000(const char* str)
{
BufferScanner scanner(str);
QS_DEF(Array<char>, type);
QS_DEF(Array<char>, entity);
entity.clear();
type.clear();
MoleculeSGroups* sgroups = &_bmol->sgroups;
scanner.skipSpace();
int sgroup_idx = scanner.readInt();
scanner.skipSpace();
scanner.readWord(type, 0);
type.push(0);
scanner.skipSpace();
scanner.readInt();
scanner.skipSpace();
int idx = sgroups->addSGroup(type.ptr());
SGroup* sgroup = &sgroups->getSGroup(idx);
sgroup->original_group = sgroup_idx;
DataSGroup* dsg = 0;
Superatom* sup = 0;
RepeatingUnit* sru = 0;
if (sgroup->sgroup_type == SGroup::SG_TYPE_DAT)
dsg = (DataSGroup*)sgroup;
else if (sgroup->sgroup_type == SGroup::SG_TYPE_SUP)
sup = (Superatom*)sgroup;
else if (sgroup->sgroup_type == SGroup::SG_TYPE_SRU)
sru = (RepeatingUnit*)sgroup;
int n;
while (!scanner.isEOF())
{
scanner.readWord(entity, "=");
if (scanner.isEOF())
return; // should not actually happen
scanner.skip(1); // =
entity.push(0);
if (strcmp(entity.ptr(), "ATOMS") == 0)
{
scanner.skip(1); // (
n = scanner.readInt1();
while (n-- > 0)
{
sgroup->atoms.push(scanner.readInt() - 1);
scanner.skipSpace();
}
scanner.skip(1); // )
}
else if ((strcmp(entity.ptr(), "XBONDS") == 0) || (strcmp(entity.ptr(), "CBONDS") == 0))
{
scanner.skip(1); // (
n = scanner.readInt1();
while (n-- > 0)
{
sgroup->bonds.push(scanner.readInt() - 1);
scanner.skipSpace();
}
scanner.skip(1); // )
}
else if (strcmp(entity.ptr(), "PATOMS") == 0)
{
scanner.skip(1); // (
n = scanner.readInt1();
while (n-- > 0)
{
idx = scanner.readInt() - 1;
if (sgroup->sgroup_type == SGroup::SG_TYPE_MUL)
((MultipleGroup*)sgroup)->parent_atoms.push(idx);
scanner.skipSpace();
}
scanner.skip(1); // )
}
else if (strcmp(entity.ptr(), "SUBTYPE") == 0)
{
QS_DEF(Array<char>, subtype);
subtype.clear();
scanner.readWord(subtype, 0);
if (strcmp(subtype.ptr(), "ALT") == 0)
sgroup->sgroup_subtype = SGroup::SG_SUBTYPE_ALT;
else if (strcmp(subtype.ptr(), "RAN") == 0)
sgroup->sgroup_subtype = SGroup::SG_SUBTYPE_RAN;
else if (strcmp(subtype.ptr(), "BLO") == 0)
sgroup->sgroup_subtype = SGroup::SG_SUBTYPE_BLO;
}
else if (strcmp(entity.ptr(), "MULT") == 0)
{
int mult = scanner.readInt();
if (sgroup->sgroup_type == SGroup::SG_TYPE_MUL)
((MultipleGroup*)sgroup)->multiplier = mult;
}
else if (strcmp(entity.ptr(), "PARENT") == 0)
{
int parent = scanner.readInt();
sgroup->parent_group = parent;
}
else if (strcmp(entity.ptr(), "BRKTYP") == 0)
{
QS_DEF(Array<char>, style);
style.clear();
scanner.readWord(style, 0);
if (strcmp(style.ptr(), "BRACKET") == 0)
sgroup->brk_style = _BRKTYP_SQUARE;
if (strcmp(style.ptr(), "PAREN") == 0)
sgroup->brk_style = _BRKTYP_ROUND;
}
else if (strcmp(entity.ptr(), "BRKXYZ") == 0)
{
scanner.skip(1); // (
n = scanner.readInt1();
if (n != 9)
throw Error("BRKXYZ number is %d (must be 9)", n);
scanner.skipSpace();
float x1 = scanner.readFloat();
scanner.skipSpace();
float y1 = scanner.readFloat();
scanner.skipSpace();
scanner.readFloat();
scanner.skipSpace(); // skip z
float x2 = scanner.readFloat();
scanner.skipSpace();
float y2 = scanner.readFloat();
scanner.skipSpace();
scanner.readFloat();
scanner.skipSpace(); // skip z
// skip 3-rd point
scanner.readFloat();
scanner.skipSpace();
scanner.readFloat();
scanner.skipSpace();
scanner.readFloat();
scanner.skipSpace();
Vec2f* brackets = sgroup->brackets.push();
brackets[0].set(x1, y1);
brackets[1].set(x2, y2);
scanner.skip(1); // )
}
else if (strcmp(entity.ptr(), "CONNECT") == 0)
{
char c1 = scanner.readChar();
char c2 = scanner.readChar();
if (sgroup->sgroup_type == SGroup::SG_TYPE_SRU)
{
if (c1 == 'H' && c2 == 'T')
((RepeatingUnit*)sgroup)->connectivity = SGroup::HEAD_TO_TAIL;
else if (c1 == 'H' && c2 == 'H')
((RepeatingUnit*)sgroup)->connectivity = SGroup::HEAD_TO_HEAD;
}
}
else if (strcmp(entity.ptr(), "FIELDNAME") == 0)
{
_readStringInQuotes(scanner, dsg ? &dsg->name : NULL);
}
else if (strcmp(entity.ptr(), "FIELDINFO") == 0)
{
_readStringInQuotes(scanner, dsg ? &dsg->description : NULL);
}
else if (strcmp(entity.ptr(), "FIELDDISP") == 0)
{
QS_DEF(Array<char>, substr);
substr.clear();
_readStringInQuotes(scanner, &substr);
if (substr.size() > 0)
substr.pop(); // remove trailing 0
if (dsg != 0)
{
BufferScanner subscan(substr);
_readSGroupDisplay(subscan, *dsg);
}
}
else if (strcmp(entity.ptr(), "FIELDDATA") == 0)
{
_readStringInQuotes(scanner, &dsg->data);
}
else if (strcmp(entity.ptr(), "QUERYTYPE") == 0)
{
_readStringInQuotes(scanner, dsg ? &dsg->querycode : NULL);
}
else if (strcmp(entity.ptr(), "QUERYOP") == 0)
{
_readStringInQuotes(scanner, dsg ? &dsg->queryoper : NULL);
}
else if (strcmp(entity.ptr(), "LABEL") == 0)
{
bool has_quote = false;
while (!scanner.isEOF())
{
char c = scanner.readChar();
if (c == '"')
{
if (has_quote)
break;
else
has_quote = true;
continue;
}
if (c == ' ' && !has_quote)
break;
if (sup != 0)
sup->subscript.push(c);
if (sru != 0)
sru->subscript.push(c);
}
if (sup != 0)
sup->subscript.push(0);
if (sru != 0)
sru->subscript.push(0);
}
else if (strcmp(entity.ptr(), "CLASS") == 0)
{
while (!scanner.isEOF())
{
char c = scanner.readChar();
if (c == ' ')
break;
if (sup != 0)
sup->sa_class.push(c);
}
if (sup != 0)
sup->sa_class.push(0);
}
else if (strcmp(entity.ptr(), "SEQID") == 0)
{
int seqid = scanner.readInt();
if ((sup != 0) && seqid > 0)
sup->seqid = seqid;
}
else if (strcmp(entity.ptr(), "NATREPLACE") == 0)
{
while (!scanner.isEOF())
{
char c = scanner.readChar();
if (c == ' ')
break;
if (sup != 0)
sup->sa_natreplace.push(c);
if (dsg != 0)
dsg->sa_natreplace.push(c);
}
if (sup != 0)
sup->sa_natreplace.push(0);
if (dsg != 0)
dsg->sa_natreplace.push(0);
}
else if (strcmp(entity.ptr(), "ESTATE") == 0)
{
while (!scanner.isEOF())
{
char c = scanner.readChar();
if (c == ' ')
break;
if (c == 'E')
{
if (sup != 0)
sup->contracted = DisplayOption::Expanded;
}
else
{
if (sup != 0)
sup->contracted = DisplayOption::Undefined;
}
}
}
else if (strcmp(entity.ptr(), "CSTATE") == 0)
{
if (sup != 0)
{
scanner.skip(1); // (
n = scanner.readInt1();
if (n != 4)
throw Error("CSTATE number is %d (must be 4)", n);
scanner.skipSpace();
Superatom::_BondConnection& bond = sup->bond_connections.push();
idx = scanner.readInt() - 1;
bond.bond_idx = idx;
scanner.skipSpace();
bond.bond_dir.x = scanner.readFloat();
scanner.skipSpace();
bond.bond_dir.y = scanner.readFloat();
scanner.skipSpace();
scanner.skipUntil(")"); // Skip z coordinate
scanner.skip(1); // )
}
else // skip for all other sgroups
{
scanner.skipUntil(")");
scanner.skip(1);
}
}
else if (strcmp(entity.ptr(), "SAP") == 0)
{
if (sup != 0)
{
scanner.skip(1); // (
n = scanner.readInt1();
if (n != 3)
throw Error("SAP number is %d (must be 3)", n);
scanner.skipSpace();
idx = scanner.readInt() - 1;
int idap = sup->attachment_points.add();
Superatom::_AttachmentPoint& ap = sup->attachment_points.at(idap);
ap.aidx = idx;
scanner.skipSpace();
ap.lvidx = scanner.readInt() - 1;
scanner.skip(1);
ap.apid.clear();
while (!scanner.isEOF())
{
char c = scanner.readChar();
if (c == ')')
break;
ap.apid.push(c);
}
ap.apid.push(0);
}
else // skip for all other sgroups
{
scanner.skipUntil(")");
scanner.skip(1);
}
}
else
{
if (scanner.lookNext() == '(')
{
scanner.skip(1);
n = scanner.readInt1();
while (n-- > 0)
{
scanner.readFloat();
scanner.skipSpace();
}
scanner.skip(1); // )
}
else
{
// Unknown property that can have value in quotes: PROP=" "
_readStringInQuotes(scanner, NULL);
}
}
scanner.skipSpace();
}
}