/src/openbabel/src/formats/cccformat.cpp
Line | Count | Source |
1 | | /********************************************************************** |
2 | | Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc. |
3 | | Some portions Copyright (C) 2001-2006 by Geoffrey R. Hutchison |
4 | | Some portions Copyright (C) 2004 by Chris Morley |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation version 2 of the License. |
9 | | |
10 | | This program is distributed in the hope that it will be useful, |
11 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | GNU General Public License for more details. |
14 | | ***********************************************************************/ |
15 | | #include <openbabel/babelconfig.h> |
16 | | |
17 | | #include <openbabel/obmolecformat.h> |
18 | | #include <openbabel/mol.h> |
19 | | #include <openbabel/atom.h> |
20 | | #include <openbabel/elements.h> |
21 | | #include <cstdlib> |
22 | | |
23 | | |
24 | | using namespace std; |
25 | | namespace OpenBabel |
26 | | { |
27 | | |
28 | | class CCCFormat : public OBMoleculeFormat |
29 | | { |
30 | | public: |
31 | | //Register this format type ID |
32 | | CCCFormat() |
33 | 12 | { |
34 | 12 | OBConversion::RegisterFormat("ccc",this); |
35 | 12 | } |
36 | | |
37 | | const char* Description() override // required |
38 | 0 | { |
39 | 0 | return |
40 | 0 | "CCC format\n" |
41 | 0 | "No comments yet\n"; |
42 | 0 | } |
43 | | |
44 | | const char* SpecificationURL() override |
45 | 0 | { return ""; } // optional |
46 | | |
47 | | //Flags() can return be any the following combined by | or be omitted if none apply |
48 | | // NOTREADABLE READONEONLY NOTWRITABLE WRITEONEONLY |
49 | | unsigned int Flags() override |
50 | 13 | { |
51 | 13 | return NOTWRITABLE; |
52 | 13 | } |
53 | | |
54 | | //////////////////////////////////////////////////// |
55 | | /// The "API" interface functions |
56 | | bool ReadMolecule(OBBase* pOb, OBConversion* pConv) override; |
57 | | |
58 | | }; |
59 | | |
60 | | //Make an instance of the format class |
61 | | CCCFormat theCCCFormat; |
62 | | |
63 | | ///////////////////////////////////////////////////////////////// |
64 | | bool CCCFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) |
65 | 0 | { |
66 | |
|
67 | 0 | OBMol* pmol = pOb->CastAndClear<OBMol>(); |
68 | 0 | if (pmol == nullptr) |
69 | 0 | return false; |
70 | | |
71 | | //Define some references so we can use the old parameter names |
72 | 0 | istream &ifs = *pConv->GetInStream(); |
73 | 0 | OBMol &mol = *pmol; |
74 | 0 | mol.SetTitle( pConv->GetTitle()); //default title is the filename |
75 | |
|
76 | 0 | char buffer[BUFF_SIZE]; |
77 | 0 | ifs.getline(buffer,BUFF_SIZE); |
78 | |
|
79 | 0 | if (strlen(buffer) > 5) |
80 | 0 | mol.SetTitle(&buffer[5]); |
81 | 0 | mol.SetEnergy(0.0); |
82 | |
|
83 | 0 | int natoms = 0; |
84 | 0 | ifs.getline(buffer,BUFF_SIZE); |
85 | 0 | sscanf(buffer,"%*s%d",&natoms); |
86 | 0 | if (natoms < 1 || natoms >= 100000000) |
87 | 0 | return(false); |
88 | 0 | mol.ReserveAtoms(natoms); |
89 | 0 | mol.BeginModify(); |
90 | |
|
91 | 0 | int end,order; |
92 | 0 | double x,y,z; |
93 | 0 | OBAtom atom; |
94 | 0 | vector3 v; |
95 | 0 | vector<string> vs; |
96 | 0 | char element[3]; |
97 | 0 | element[2] = '\0'; |
98 | |
|
99 | 0 | for (int i = 1;i <= natoms;i++) |
100 | 0 | { |
101 | 0 | if (!ifs.getline(buffer,BUFF_SIZE)) |
102 | 0 | return(false); |
103 | | // This is a fixed-column format: the element symbol is in columns |
104 | | // 0-1, the coordinates start at column 15, and the bond list starts |
105 | | // at column 60. Bounds-check the line length before indexing so we |
106 | | // never parse past the end of the (terminated) line into stale memory. |
107 | 0 | size_t linelen = strlen(buffer); |
108 | 0 | if (linelen < 15) |
109 | 0 | { |
110 | 0 | obErrorLog.ThrowError(__FUNCTION__, |
111 | 0 | "Problems reading a CCC file: truncated atom " |
112 | 0 | "record (missing coordinates).", obError); |
113 | 0 | return(false); |
114 | 0 | } |
115 | 0 | atom.Clear(); |
116 | 0 | element[0] = buffer[0]; |
117 | 0 | element[1] = (buffer[1] != ' ') ? buffer[1]:'\0'; |
118 | 0 | atom.SetAtomicNum(OBElements::GetAtomicNum(element)); |
119 | 0 | x = y = z = 0.0; |
120 | 0 | if (sscanf(&buffer[15],"%lf%lf%lf",&x,&y,&z) != 3) |
121 | 0 | { |
122 | 0 | obErrorLog.ThrowError(__FUNCTION__, |
123 | 0 | "Problems reading a CCC file: could not parse " |
124 | 0 | "atom coordinates.", obError); |
125 | 0 | return(false); |
126 | 0 | } |
127 | 0 | v.Set(x,y,z); |
128 | 0 | atom.SetVector(v); |
129 | |
|
130 | 0 | if (!mol.AddAtom(atom)) |
131 | 0 | return(false); |
132 | | // The bond list is optional; only parse it when the line is long |
133 | | // enough, and clear vs otherwise so bonds do not leak across atoms. |
134 | 0 | vs.clear(); |
135 | 0 | if (linelen > 60) |
136 | 0 | tokenize(vs,&buffer[60]); |
137 | 0 | vector<string>::iterator j; |
138 | |
|
139 | 0 | for (j = vs.begin();j != vs.end();++j) |
140 | 0 | if (!j->empty()) |
141 | 0 | { |
142 | | //get the bond order |
143 | 0 | switch((char)(*j)[j->size()-1]) |
144 | 0 | { |
145 | 0 | case 'S': |
146 | 0 | order = 1; |
147 | 0 | break; |
148 | 0 | case 'D': |
149 | 0 | order = 2; |
150 | 0 | break; |
151 | 0 | case 'T': |
152 | 0 | order = 3; |
153 | 0 | break; |
154 | 0 | default: |
155 | 0 | order = 1; |
156 | 0 | } |
157 | 0 | (*j)[j->size()-1] = ' '; |
158 | 0 | end = atoi(j->c_str()); |
159 | 0 | if (i>end) |
160 | 0 | mol.AddBond(i,end,order); |
161 | 0 | } |
162 | 0 | } |
163 | | |
164 | 0 | mol.EndModify(); |
165 | 0 | return(true); |
166 | 0 | } |
167 | | |
168 | | } //namespace OpenBabel |