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