/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010-2012 University of Bonn. All rights reserved. * * * This file is part of MoleCuilder. * * MoleCuilder is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * MoleCuilder is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MoleCuilder. If not, see . */ /* * ConfigFileBuffer.cpp * * Created on: 12.06.2010 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include #include #include "ConfigFileBuffer.hpp" #include "CodePatterns/Verbose.hpp" #include "CodePatterns/Log.hpp" #include "Helpers/defs.hpp" #include "Helpers/helpers.hpp" #include "World.hpp" /******************************** Functions for class ConfigFileBuffer **********************/ /** Structure containing compare function for Ion_Type sorting. */ struct IonTypeCompare { bool operator()(std::string s1, std::string s2) const { ConvertTo toInt; boost::char_separator sep("_"); tokenizer tokens1(s1,sep); tokenizer tokens2(s2,sep); tokenizer::iterator tok_iter1 = tokens1.begin(); tokenizer::iterator tok_iter2 = tokens2.begin(); ++tok_iter1; ++tok_iter2; std::string element1(*tok_iter1++); std::string element2(*tok_iter2++); int elementno1 = toInt(element1.substr(4,string::npos)); int elementno2 = toInt(element2.substr(4,string::npos)); if (elementno1 != elementno2) return elementno1 < elementno2; else { std::string atom1(*tok_iter1); std::string atom2(*tok_iter2); int atomno1 = toInt(atom1); int atomno2 = toInt(atom2); return atomno1 < atomno2; } // char number1[8]; // char number2[8]; // const char *dummy1 = s1.c_str(); // const char *dummy2 = s2.c_str(); // //LOG(0, s1 << " " << s2); // dummy1 = strchr(s1, '_')+sizeof(char)*5; // go just after "Ion_Type" // dummy2 = strchr(dummy1, '_'); // strncpy(number1, dummy1, dummy2-dummy1); // copy the number // number1[dummy2-dummy1]='\0'; // dummy1 = strchr(s2, '_')+sizeof(char)*5; // go just after "Ion_Type" // dummy2 = strchr(dummy1, '_'); // strncpy(number2, dummy1, dummy2-dummy1); // copy the number // number2[dummy2-dummy1]='\0'; // if (atoi(number1) != atoi(number2)) // return (atoi(number1) < atoi(number2)); // else { // dummy1 = strchr(s1, '_')+sizeof(char); // dummy1 = strchr(dummy1, '_')+sizeof(char); // dummy2 = strchr(dummy1, ' ') < strchr(dummy1, '\t') ? strchr(dummy1, ' ') : strchr(dummy1, '\t'); // strncpy(number1, dummy1, dummy2-dummy1); // copy the number // number1[dummy2-dummy1]='\0'; // dummy1 = strchr(s2, '_')+sizeof(char); // dummy1 = strchr(dummy1, '_')+sizeof(char); // dummy2 = strchr(dummy1, ' ') < strchr(dummy1, '\t') ? strchr(dummy1, ' ') : strchr(dummy1, '\t'); // strncpy(number2, dummy1, dummy2-dummy1); // copy the number // number2[dummy2-dummy1]='\0'; // return (atoi(number1) < atoi(number2)); // } } typedef boost::tokenizer > tokenizer; }; /** Constructor for ConfigFileBuffer class. */ ConfigFileBuffer::ConfigFileBuffer() : buffer(NULL), LineMapping(NULL), CurrentLine(0), NoLines(0) { }; /** Constructor for ConfigFileBuffer class with filename to be parsed. * \param *filename file name */ ConfigFileBuffer::ConfigFileBuffer(const char * const filename) : buffer(NULL), LineMapping(NULL), CurrentLine(0), NoLines(0) { InitFileBuffer(filename); } void ConfigFileBuffer::InitFileBuffer(const char * const filename) { ifstream *file= new ifstream(filename); InitFileBuffer(file); } void ConfigFileBuffer::InitFileBuffer(istream *file) { char line[MAXSTRINGSIZE]; RemoveMapping(); // prescan number of lines if (file->fail()) { ELOG(1, "config file missing!"); return; } NoLines = 0; // we're overcounting by one long file_position = file->tellg(); // mark current position while (file->good()) { file->getline(line, MAXSTRINGSIZE-1); NoLines++; } file->clear(); file->seekg(file_position, ios::beg); LOG(1, NoLines-1 << " lines were recognized."); // allocate buffer's 1st dimension if (buffer != NULL) { ELOG(1, "FileBuffer->buffer is not NULL!"); return; } else buffer = new char *[NoLines]; // scan each line and put into buffer int lines=0; int i; do { buffer[lines] = new char[MAXSTRINGSIZE]; file->getline(buffer[lines], MAXSTRINGSIZE-1); i = strlen(buffer[lines]); buffer[lines][i] = '\n'; buffer[lines][i+1] = '\0'; lines++; } while((!file->eof()) && (lines < NoLines)); LOG(1, lines-1 << " lines were read into the buffer."); file->clear(); file->seekg(file_position, ios::beg); InitMapping(); } /** Destructor for ConfigFileBuffer class. */ ConfigFileBuffer::~ConfigFileBuffer() { RemoveBuffer(); RemoveMapping(); } /** Create trivial mapping. */ void ConfigFileBuffer::InitMapping() { LineMapping = new int[NoLines]; for (int i=0;i IonTypeLineMap; if (!MappingAllocated) { InitMapping(); } typedef boost::tokenizer > tokenizer; boost::char_separator sep("\t "); // put all into hashed map for (int i=CurrentLine; i (token, i)); } } } // fill map (aka IonType1_1, IonType1_1, IonType1_1, IonType1_2, IonType1_2, IonType1_2, ... // ..., IonType2_1, IonType2_1, IonType2_1, ...) int nr=0; for (map::iterator runner = IonTypeLineMap.begin(); runner != IonTypeLineMap.end(); ++runner) { if (CurrentLine+nr < NoLines) LineMapping[CurrentLine+(nr++)] = runner->second; else { ELOG(0, "config::MapIonTypesInBuffer - NoLines is wrong: We are past the end of the file!"); performCriticalExit(); } } }