/* # --------------------------------------------------------------------- # # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image # pour la SantÈ) # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton # Previous Authors : Laurent Guigues, Jean-Pierre Roux # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil # # This software is governed by the CeCILL-B license under French law and # abiding by the rules of distribution of free software. You can use, # modify and/ or redistribute the software under the terms of the CeCILL-B # license as circulated by CEA, CNRS and INRIA at the following URL # http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html # or in the file LICENSE.txt. # # As a counterpart to the access to the source code and rights to copy, # modify and redistribute granted by the license, users are provided only # with a limited warranty and the software's author, the holder of the # economic rights, and the successive licensors have only limited # liability. # # The fact that you are presently reading this means that you have had # knowledge of the CeCILL-B license and that you accept its terms. # ------------------------------------------------------------------------ */ // SYSTEM INCLUDES // PROJECT INCLUDES // LOCAL INCLUDES // FORWARD REFERENCES //NAMESPACE #include //====== LIFECYCLE ======== template ReaderEnvironment::ReaderEnvironment(std::string nameConfigurationFile,std::map* things) { this->nameConfigurationFile=nameConfigurationFile; this->things=things; this->instantHandler=NULL; this->nameOtherConceptsFile = nameOtherConceptsFile; this->environment= new SomeEnvironment(); //constants NUMCONCEPTS="numConcepts"; CONCEPT="concept"; OBJECT="object"; NUMOBJECTS="numObjects"; NAME="name"; SIZE="size"; PATH="path"; INSTANT="instant"; NUMINSTANTS="numInstants"; RANGE="r"; COMMENT="#"; EQUAL="="; POINT="."; ALL="all"; nameOtherConceptsFile = ""; numberOfConcepts = 0; //build the environment buildEnvironment(); } template ReaderEnvironment::ReaderEnvironment(std::string nameConceptFile,std::string nameObjectFile,std::map* things) { this->nameConceptFile=nameConceptFile; this->nameObjectFile=nameObjectFile; this->things=things; this->nameOtherConceptsFile = nameOtherConceptsFile; this->environment= new SomeEnvironment(); //constants NUMCONCEPTS="numConcepts"; CONCEPT="concept"; OBJECT="object"; NUMOBJECTS="numObjects"; NAME="name"; SIZE="size"; PATH="path"; INSTANT="instant"; NUMINSTANTS="numInstants"; RANGE="r"; COMMENT="#"; EQUAL="="; POINT="."; ALL="all"; nameOtherConceptsFile = ""; numberOfConcepts = 0; //build the environment buildEnvironment(); } template ReaderEnvironment :: ReaderEnvironment(std::string nameOtherConceptsFile, std::string nameConceptFile,std::string nameObjectFile, std::map* things) { this->nameConceptFile=nameConceptFile; this->nameObjectFile=nameObjectFile; this->nameOtherConceptsFile = nameOtherConceptsFile; this->things=things; this->environment= new SomeEnvironment(); //constants NUMCONCEPTS="numConcepts"; CONCEPT="concept"; OBJECT="object"; NUMOBJECTS="numObjects"; NAME="name"; SIZE="size"; PATH="path"; INSTANT="instant"; NUMINSTANTS="numInstants"; RANGE="r"; COMMENT="#"; EQUAL="="; POINT="."; ALL="all"; numberOfConcepts = 0; //build the environment buildEnvironment(); } template ReaderEnvironment::~ReaderEnvironment() { //deletes the things things->clear(); if(things) delete this->things; nameConceptFile.clear(); nameConfigurationFile.clear(); nameObjectFile.clear(); dataInFile.clear(); nameOtherConceptsFile.clear(); if(instantHandler) delete instantHandler; } //====== OPERATIONS ======= /* * @return environment builded */ template SomeEnvironment* ReaderEnvironment::getEnvironment() { return this->environment; } /* * build the environment */ template void ReaderEnvironment::buildEnvironment() { //read the file if(!nameConfigurationFile.empty()) readFile(nameConfigurationFile); else { readFile(nameConceptFile); readFile(nameObjectFile); if(!nameOtherConceptsFile.empty()) { readFile(nameOtherConceptsFile); } } //adding the data of the concepts to the environment addConcepts(); //setting the instant handler this->instantHandler=new InstantHandler(environment); //adding the things to the environment addThings(); } //======== PRIVATE METHODS ============== /* * build the instant from the string readed in the file * @param instant, string with the description of the instant * @param nameObject, name of the object for wich we can add an instant or several instants * @return * TODO: when is an r(i j) and when the user doesnt write all the information * of the instants it is considered like an all * for example, there is 3 concepts, the data complete for an instant is of size 3 * but the user can write only an index of the first concept, the others is assumed * to be all, is like instant= i, then it is assumed like instant= i all all */ template bool ReaderEnvironment::addInstants(std::string nameObject,std::string instant) { int indexAll,numConcept,sizeConcept=-1,i,k=0; //copying the string of the instant std::string instantCopy=instant; //finding alls indexAll=instantCopy.find(ALL); std::string concept; char* indexConcept=(char*)malloc(sizeof(char)); Instant* instantThing; //if have an all if(indexAll!=-1) { std::string nameConcept; //setting the first instant of the handler, using all the all's defined in the string while(indexAll!=-1) { //itoa(0,indexConcept,10); // itoa not ANSI sprintf(indexConcept, "%d", 0); instantCopy.replace(indexAll,ALL.size(),indexConcept); numConcept=getNumConcept(instantCopy,indexAll); getConceptName( nameConcept,numConcept); //setting the instanHandler instantHandler->addConceptToHandled(nameConcept,2,k); k++; nameConcept.clear(); indexAll=instantCopy.find(ALL); } //starting instant instantThing=getInstant(instantCopy); //adding to the environment if(instantThing) { if(environment->getNumberOfConcepts()== instantThing->getSize()) { environment->addInstantToThing(nameObject,instantThing); //starting the actual instant instantHandler->setActualInstant(instantThing); } //else THROW EXCEPTION } //else THROW AN EXCEPTION //deleting memory delete instantThing; //calculatig the number of instants int numInstants=instantHandler->getNumOfInstants(); //calculating all the instants for(i=1;inextInstant(); instantThing=instantHandler->getActualInstant(); //borrame int sizeI=instantThing->getSize(); for(int j=0;jgetIndexInConcept(j); // environment->addInstantToThing(nameObject,instantThing); } } //doesnt have an all else { instantThing=getInstant(instantCopy); if(instantThing) { environment->addInstantToThing(nameObject,instantThing); delete instantThing; } //else throw an exception } return true; } /* * Returns the name of the concept in the concepts defined given the number * of the concept in the instant * @param nameConcept, string where is going to be load the name of the concept * @param numConcept, number of the concept in the instant for which we are looking * for the name */ template void ReaderEnvironment::getConceptName(std::string& nameConcept,int numConcept) { int ncs,conceptIndexInEnvironment,i; //getting the names of the concept defined std::vector nameConcepts; environment->getConceptsNames(nameConcepts); //name of the concept i std::string nameConcepti; ncs=nameConcepts.size(); bool isConcept=false; for(i=0;i< ncs && !isConcept;i++) { nameConcepti=nameConcepts[i]; conceptIndexInEnvironment=environment->getIndexConcept(nameConcepti); if(conceptIndexInEnvironment==numConcept) isConcept=true; else nameConcepti.clear(); } if(isConcept) nameConcept=nameConcepti; nameConcepti.clear(); } /* * Returns the number of the concept in the instant string read * @param instant,instant where we are going to search the number of the * concept that is in the position given * @param position, position of the concept (string position) for which we want the number in the instant given * @return the number of concept in the instant */ template int ReaderEnvironment::getNumConcept(std::string& instant,int position ) { int splitIndex,counter=0; splitIndex=instant.rfind(" ",position); while(splitIndex>=0) { counter++; if(splitIndex>0) splitIndex=instant.rfind(" ",splitIndex-1); if(splitIndex==0) splitIndex=-1; } return counter; } /* * Returns the instant object of the instant string given * 1 1 1 1 and returns an instant object (1,1,1,1) * @param instant, instant for which we want to construct an Instant object * @return an Instant's object * TODO validation of indexes in instant */ template Instant* ReaderEnvironment:: getInstant(std::string instant) { int value,splitIndex; //getting the names of the concept defined std::vector nameConcepts; environment->getConceptsNames(nameConcepts); //instant vector std::vector* instantVector=new std::vector(); std::string concept; splitIndex=instant.find(" "); bool stop=false; int k=0; bool isValid= true; while(!stop && isValid) { if(splitIndex==-1) stop=true; concept=instant.substr(0,splitIndex); instant.erase(0,splitIndex+1); value=atoi(concept.c_str()); isValid=environment->isValidIndex(value,k); if(isValid) instantVector->push_back(value); splitIndex=instant.find(" "); k++; } Instant* instantThing; if(stop) { instantThing= new Instant(instantVector); delete instantVector; } else instantThing=NULL; return instantThing; } /* * add the instants defined in the file for the name of the * object given * @param nameObject, name of the object for which we want to search * its instant */ template bool ReaderEnvironment::addInstantToThing(std::string nameObject,std::string index) { int numInstants,i; std::map::iterator iteratorData; bool added=true; //getting the number of instants for the object given std::string s(OBJECT + index + POINT + NUMINSTANTS); iteratorData=dataInFile.find(s); if(iteratorData!=dataInFile.end()) { std::string numIns=iteratorData->second; numInstants=atoi(numIns.c_str()); numIns.clear(); } //else throw exception //getting the instants s.clear(); std::string instant; //finding the number of decimals places int num=getNumberOfDecimalPlaces(numInstants); char* indexi=(char*)malloc(sizeof(char)*(num+1)); //std::string indexiStr; for(i=1;i<=numInstants && added;i++) { //itoa(i,indexi,10); sprintf(indexi, "%d", i); //indexiStr=indexi; s=OBJECT+index+POINT+INSTANT+indexi; iteratorData=dataInFile.find(s); if(iteratorData!=dataInFile.end()) { instant=iteratorData->second; addInstants(nameObject,instant); } s.clear(); instant.clear(); } free(indexi); if(i==numInstants+1) return true; else return false; } /* * adds the things to the environment */ template bool ReaderEnvironment::addThings() { int numObjects=0,j=0; bool addedInstants=true; typename std::map::iterator iteratorData; typename std::map::iterator iteratorThings; //getting the number of objects iteratorData=dataInFile.find(NUMOBJECTS); if(iteratorData!=dataInFile.end()) { std::string numObj=iteratorData->second; numObjects=atoi(numObj.c_str()); numObj.clear(); } //finding the number of decimals places int num=getNumberOfDecimalPlaces(numObjects); //getting the objects if does come like objects if(things) { char* index= (char*)malloc(sizeof(char)*(num+1)); std::string objectData; std::string nameObjecti; for(j=1;j<=numObjects && addedInstants;j++) { //itoa(j,index,10); int num2=sprintf(index, "%d", j); objectData=OBJECT+index+POINT+NAME; iteratorData=dataInFile.find(objectData); if(iteratorData!=dataInFile.end()) { nameObjecti=iteratorData->second; iteratorThings=things->find(nameObjecti); if(iteratorThings!=things->end()) { environment->addThing(nameObjecti,iteratorThings->second); //indexS=index; addedInstants=addInstantToThing(nameObjecti,index); } //throwException //the names given en execution and of the file should be the same //else } objectData.clear(); } objectData.clear(); free(index); if(j==numObjects+1) return true; else return false; } //if we have to charge it from a file //if is like that we should ask for the objecti.path //else return false; } /* * adds the concepts of the file to the environment */ template bool ReaderEnvironment::addConcepts() { int numConcepts=0,i=0; std::map::iterator iteratorData; //getting the number of concepts defined iteratorData=dataInFile.find(NUMCONCEPTS); if(iteratorData!=dataInFile.end()) { std::string numberOfConcepts=iteratorData->second; numConcepts=atoi(numberOfConcepts.c_str()); } //finding the number of decimals places int num=getNumberOfDecimalPlaces(numConcepts); std::string conceptData; char* index=(char*)malloc(sizeof(char)*(num+1)); std::string nameConcepti; std::string sizeConcepti; for(i=1;i<=numConcepts;i++) { //itoa(i,index,10); sprintf(index, "%d", i); //finding the name conceptData=CONCEPT+index+POINT+NAME; iteratorData=dataInFile.find(conceptData); if(iteratorData!=dataInFile.end()) nameConcepti=iteratorData->second; //finding the size conceptData.clear(); conceptData=CONCEPT+index+POINT+SIZE; iteratorData=dataInFile.find(conceptData); if(iteratorData!=dataInFile.end()) sizeConcepti=iteratorData->second; //adding the concept environment->addConcept(nameConcepti,atoi(sizeConcepti.c_str())); conceptData.clear(); nameConcepti.clear(); sizeConcepti.clear(); } free(index); if(i==numConcepts+1) return true; else return false; } /* * read the configuration file */ template void ReaderEnvironment::readFile(std::string nameFile) { bool readingOtherConcepts = nameFile.compare(this->nameOtherConceptsFile) == 0; bool readingConcepts = nameFile.compare(this->nameConceptFile) == 0 || readingOtherConcepts; bool findedConceptOcurrence = false; int posPoint=0; int conceptValue=0; //std::string conceptKeyPart = ""; int pos; //reader of the file std::ifstream configFile; //each line of the file std::string line; //string of the data to save std::string data; //string with the key of the map std::string key; //line size int lineSize=0; //opening the file if(nameFile.compare("")!=0) { configFile.open(nameFile.c_str()); if(!configFile.is_open()) { //should throw an exception return ; } else { //THIS ONLY SAVES NUMBERS OF ONE DIGIT //FIXME char* index= (char*)malloc(sizeof(char)*5); char* dataString= (char*)malloc(sizeof(char)*10); while(!configFile.eof()) { //line.clear(); std::getline(configFile,line); cleanLine(line); pos=line.find(EQUAL); lineSize=line.size(); //if is not a comment int c=line.find(COMMENT); if (c !=std::string::npos ) findedConceptOcurrence = false; else//if(c<0 && pos>=0) { data=line.substr(pos+1,lineSize); key=line.substr(0,pos); if ( readingConcepts && (key.rfind( CONCEPT ))!=std::string::npos ) { if( (key.rfind( NAME ))!=std::string::npos ) { if ( !findedConceptOcurrence ) { numberOfConcepts++; findedConceptOcurrence = true; //itoa(numberOfConcepts,index,10); sprintf (index, "%d", numberOfConcepts); } if ( readingOtherConcepts ) key = CONCEPT + index + POINT + NAME; } else if ( (key.rfind( SIZE ))!=std::string::npos ) { if ( !findedConceptOcurrence) { numberOfConcepts++; findedConceptOcurrence = true; // itoa(numberOfConcepts,index,10); sprintf(index, "%d", numberOfConcepts); } if ( readingOtherConcepts ) key = CONCEPT + index + POINT + SIZE; } } int antes = dataInFile.size(); if(!key.empty()) { if( readingOtherConcepts && key.rfind(NUMCONCEPTS)!=std::string::npos ) { int otherConceptsValue = atoi(data.c_str()); //itoa(numberOfConcepts+otherConceptsValue,dataString,10); sprintf(dataString,"%d", numberOfConcepts+otherConceptsValue); data = dataString; std::map::iterator iter = dataInFile.find(key); dataInFile.erase(iter); } dataInFile.insert(std::pair(key,data)); } int despues = dataInFile.size(); //cleaning the data and the key variables data.clear(); key.clear(); } } free(index); free(dataString); configFile.close(); } } } /* * Returns the number of decimals places of the number given */ template int ReaderEnvironment::getNumberOfDecimalPlaces(int number) { int i=0; while(number>0) { number=number/10; i++; } if(i==0) i=1; return i; } /* * Clean the line readed from the file */ template void ReaderEnvironment::cleanLine(std::string & line) { int pos1,pos2,size; pos1=line.find_first_not_of(" "); line.erase(0,pos1); pos2=line.find_last_not_of(" "); size=line.length(); line.erase(pos2+1,size-1); }