source: src/Parser/ConfigFileBuffer.cpp@ a844d8

Candidate_v1.6.1
Last change on this file since a844d8 was 9eb71b3, checked in by Frederik Heber <frederik.heber@…>, 8 years ago

Commented out MemDebug include and Memory::ignore.

  • MemDebug clashes with various allocation operators that use a specific placement in memory. It is so far not possible to wrap new/delete fully. Hence, we stop this effort which so far has forced us to put ever more includes (with clashes) into MemDebug and thereby bloat compilation time.
  • MemDebug does not add that much usefulness which is not also provided by valgrind.
  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * ConfigFileBuffer.cpp
25 *
26 * Created on: 12.06.2010
27 * Author: heber
28 */
29
30// include config.h
31#ifdef HAVE_CONFIG_H
32#include <config.h>
33#endif
34
35//#include "CodePatterns/MemDebug.hpp"
36
37#include <iostream>
38#include <boost/tokenizer.hpp>
39#include <string>
40
41#include "ConfigFileBuffer.hpp"
42#include "CodePatterns/Verbose.hpp"
43#include "CodePatterns/Log.hpp"
44#include "Helpers/defs.hpp"
45#include "Helpers/helpers.hpp"
46#include "World.hpp"
47
48/******************************** Functions for class ConfigFileBuffer **********************/
49
50/** Structure containing compare function for Ion_Type sorting.
51 */
52struct IonTypeCompare {
53 bool operator()(std::string s1, std::string s2) const {
54 ConvertTo<int> toInt;
55 boost::char_separator<char> sep("_");
56 tokenizer tokens1(s1,sep);
57 tokenizer tokens2(s2,sep);
58 tokenizer::iterator tok_iter1 = tokens1.begin();
59 tokenizer::iterator tok_iter2 = tokens2.begin();
60 ++tok_iter1;
61 ++tok_iter2;
62
63 std::string element1(*tok_iter1++);
64 std::string element2(*tok_iter2++);
65 int elementno1 = toInt(element1.substr(4,string::npos));
66 int elementno2 = toInt(element2.substr(4,string::npos));
67 if (elementno1 != elementno2)
68 return elementno1 < elementno2;
69 else {
70 std::string atom1(*tok_iter1);
71 std::string atom2(*tok_iter2);
72 int atomno1 = toInt(atom1);
73 int atomno2 = toInt(atom2);
74 return atomno1 < atomno2;
75 }
76
77// char number1[8];
78// char number2[8];
79// const char *dummy1 = s1.c_str();
80// const char *dummy2 = s2.c_str();
81// //LOG(0, s1 << " " << s2);
82// dummy1 = strchr(s1, '_')+sizeof(char)*5; // go just after "Ion_Type"
83// dummy2 = strchr(dummy1, '_');
84// strncpy(number1, dummy1, dummy2-dummy1); // copy the number
85// number1[dummy2-dummy1]='\0';
86// dummy1 = strchr(s2, '_')+sizeof(char)*5; // go just after "Ion_Type"
87// dummy2 = strchr(dummy1, '_');
88// strncpy(number2, dummy1, dummy2-dummy1); // copy the number
89// number2[dummy2-dummy1]='\0';
90// if (atoi(number1) != atoi(number2))
91// return (atoi(number1) < atoi(number2));
92// else {
93// dummy1 = strchr(s1, '_')+sizeof(char);
94// dummy1 = strchr(dummy1, '_')+sizeof(char);
95// dummy2 = strchr(dummy1, ' ') < strchr(dummy1, '\t') ? strchr(dummy1, ' ') : strchr(dummy1, '\t');
96// strncpy(number1, dummy1, dummy2-dummy1); // copy the number
97// number1[dummy2-dummy1]='\0';
98// dummy1 = strchr(s2, '_')+sizeof(char);
99// dummy1 = strchr(dummy1, '_')+sizeof(char);
100// dummy2 = strchr(dummy1, ' ') < strchr(dummy1, '\t') ? strchr(dummy1, ' ') : strchr(dummy1, '\t');
101// strncpy(number2, dummy1, dummy2-dummy1); // copy the number
102// number2[dummy2-dummy1]='\0';
103// return (atoi(number1) < atoi(number2));
104// }
105 }
106
107 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
108};
109
110
111/** Constructor for ConfigFileBuffer class.
112 */
113ConfigFileBuffer::ConfigFileBuffer() :
114 buffer(NULL),
115 LineMapping(NULL),
116 CurrentLine(0),
117 NoLines(0)
118{
119};
120
121/** Constructor for ConfigFileBuffer class with filename to be parsed.
122 * \param *filename file name
123 */
124ConfigFileBuffer::ConfigFileBuffer(const char * const filename) :
125 buffer(NULL),
126 LineMapping(NULL),
127 CurrentLine(0),
128 NoLines(0)
129{
130 InitFileBuffer(filename);
131}
132
133void ConfigFileBuffer::InitFileBuffer(const char * const filename)
134{
135 ifstream *file= new ifstream(filename);
136 InitFileBuffer(file);
137}
138
139void ConfigFileBuffer::InitFileBuffer(istream *file)
140{
141 char line[MAXSTRINGSIZE];
142
143 RemoveMapping();
144
145 // prescan number of lines
146 if (file->fail()) {
147 ELOG(1, "config file missing!");
148 return;
149 }
150 NoLines = 0; // we're overcounting by one
151 long file_position = file->tellg(); // mark current position
152 while (file->good()) {
153 file->getline(line, MAXSTRINGSIZE-1);
154 NoLines++;
155 }
156 file->clear();
157 file->seekg(file_position, ios::beg);
158 LOG(1, NoLines-1 << " lines were recognized.");
159
160 // allocate buffer's 1st dimension
161 if (buffer != NULL) {
162 ELOG(1, "FileBuffer->buffer is not NULL!");
163 return;
164 } else
165 buffer = new char *[NoLines];
166
167 // scan each line and put into buffer
168 int lines=0;
169 int i;
170 do {
171 buffer[lines] = new char[MAXSTRINGSIZE];
172 file->getline(buffer[lines], MAXSTRINGSIZE-1);
173 i = strlen(buffer[lines]);
174 buffer[lines][i] = '\n';
175 buffer[lines][i+1] = '\0';
176 lines++;
177 } while((!file->eof()) && (lines < NoLines));
178 LOG(1, lines-1 << " lines were read into the buffer.");
179 file->clear();
180 file->seekg(file_position, ios::beg);
181
182 InitMapping();
183}
184
185/** Destructor for ConfigFileBuffer class.
186 */
187ConfigFileBuffer::~ConfigFileBuffer()
188{
189 RemoveBuffer();
190 RemoveMapping();
191}
192
193
194/** Create trivial mapping.
195 */
196void ConfigFileBuffer::InitMapping()
197{
198 LineMapping = new int[NoLines];
199 for (int i=0;i<NoLines;i++)
200 LineMapping[i] = i;
201 MappingAllocated = true;
202}
203
204/** Remove allocated mapping.
205 */
206void ConfigFileBuffer::RemoveMapping()
207{
208 delete[](LineMapping);
209 MappingAllocated = false;
210}
211
212/** Remove allocated mapping.
213 */
214void ConfigFileBuffer::RemoveBuffer()
215{
216 for(int i=0;i<NoLines;++i)
217 delete[](buffer[i]);
218 delete[](buffer);
219}
220
221
222/** Creates a mapping for the \a *FileBuffer's lines containing the Ion_Type keyword such that they are sorted.
223 * \a *map on return contains a list of NoAtom entries such that going through the list, yields indices to the
224 * lines in \a *FileBuffer in a sorted manner of the Ion_Type?_? keywords. We assume that ConfigFileBuffer::CurrentLine
225 * points to first Ion_Type entry.
226 * \param *FileBuffer pointer to buffer structure
227 * \param NoAtoms of subsequent lines to look at
228 */
229void ConfigFileBuffer::MapIonTypesInBuffer(const int NoAtoms)
230{
231 std::multimap<std::string, int, IonTypeCompare> IonTypeLineMap;
232 if (!MappingAllocated) {
233 InitMapping();
234 }
235
236 typedef boost::tokenizer<boost::char_separator<char> >
237 tokenizer;
238 boost::char_separator<char> sep("\t ");
239
240 // put all into hashed map
241 for (int i=CurrentLine; i<NoLines; ++i) {
242 std::string line(buffer[i]);
243 tokenizer tokens(line, sep);
244 if (tokens.begin() != tokens.end()) {
245 const std::string token = *tokens.begin();
246 if (token.find("Ion_Type") != string::npos) {
247 IonTypeLineMap.insert(pair<std::string, int> (token, i));
248 }
249 }
250 }
251
252 // fill map (aka IonType1_1, IonType1_1, IonType1_1, IonType1_2, IonType1_2, IonType1_2, ...
253 // ..., IonType2_1, IonType2_1, IonType2_1, ...)
254 int nr=0;
255 for (map<std::string, int, IonTypeCompare>::iterator runner = IonTypeLineMap.begin(); runner != IonTypeLineMap.end(); ++runner) {
256 if (CurrentLine+nr < NoLines)
257 LineMapping[CurrentLine+(nr++)] = runner->second;
258 else {
259 ELOG(0, "config::MapIonTypesInBuffer - NoLines is wrong: We are past the end of the file!");
260 performCriticalExit();
261 }
262 }
263}
Note: See TracBrowser for help on using the repository browser.