void MolfileLoader::_readSGroup3000()

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();
    }
}