#include "RibFileStack.h" RibFileStack::RibFileStack(QString dir) { ribProc = ribParser::initHash(); //hash of rib procedure stack = new QStack< QPair* >(); templateDir = dir; subDir.append("."); //to search in the same dir }; RibFileStack::~RibFileStack() { delete ribProc; while(!stack->isEmpty()) popFile(); //close all file delete stack; //it's enough? }; //open file and push the text stream to stack bool RibFileStack::pushFile(QString path) { if(QFile::exists(path)) { QFile* file = new QFile(path); return pushFile(file); } else { return false; } }; bool RibFileStack::pushFile(QFile* file) { //add file to stack and open it if(!(*file).open(QIODevice::ReadOnly)) { return false; } QTextStream* stream = new QTextStream(file); QPair* p = new QPair(file, stream); stack->push(p); if(stack->count() == 1) { //if it's the first prepare next line bool end; nextLine = topNextLine(&end); nextLineType = isRibProcedure(nextLine); } return true; }; //close file and pop from stack bool RibFileStack::popFile() { if(stack->isEmpty()) return false; QPair* p = stack->pop(); (*(p->first)).close(); return true; }; //return the next line from file at top of stack //if it's the end of this file, pop it and take the line of next QString RibFileStack::topNextLine(bool* end) { if(stack->isEmpty()) { *end = true; return ""; } //take the top element from stack QPair* p = stack->top(); //the stream of file QTextStream* s = (p->second); if(!s->atEnd()) { *end = false; QString str = s->readLine(); if(str == "") return topNextLine(end); //ignore empty line else return str; } else { //close and remove from stack the file popFile(); //recursive call (the top is changed) return topNextLine(end); } }; //return the next statement of file stack (maybe on more line) QString RibFileStack::nextStatement(int* type, bool manageReadArchive) { if(nextLine == "") { bool end = false; nextLine = topNextLine(&end); if(end) { *type = ribParser::NOMORESTATEMENT; return nextLine; //no more line to be readable } else *type = isRibProcedure(nextLine); } QString str = nextLine; //nextline is a rib procedure *type = nextLineType; if(*type == ribParser::READARCHIVE) { //qDebug("is a ReadArchive"); QStringList token = ribParser::splitStatement(&str); //0: ReadArchive, //1: " , //2: , //3: " bool end; while(token.size() < 4 && !end) { QString line = topNextLine(&end); str += " " + line; token = ribParser::splitStatement(&str); } if(manageReadArchive) { if(readArchive(str)) { //add the new file to stack nextLine = topNextLine(&end); nextLineType = isRibProcedure(nextLine); //qDebug("Readed: %s Type: %d",qPrintable(str), *type); //qDebug("nextline: %s type: %d",qPrintable(nextLine),nextLineType); return nextStatement(type, manageReadArchive); //read the first line of new file, if found it } else { nextLine = ""; nextLineType = ribParser::NOMORESTATEMENT; return str; } } else { nextLine = ""; nextLineType = ribParser::NOMORESTATEMENT; return str; } } else { //it isn't a ReadArchive procedure bool end; nextLine = topNextLine(&end); //take next line if(!inString(str)) nextLineType = isRibProcedure(nextLine); else //maybe a string with a procedure name nextLineType = ribParser::NOTAPROCEDURE; while(nextLine != "" && nextLineType == ribParser::NOTAPROCEDURE ) { //qDebug("nextline: %s type: %d",qPrintable(nextLine),nextLineType); str += "\n" + nextLine; //if isn't a rib procedure append to str nextLine = topNextLine(&end); if(!inString(str)) nextLineType = isRibProcedure(nextLine); //if there's a string opened, don't test if it's a procedure } //qDebug("Readed: %s Type: %d",qPrintable(str), *type); //qDebug("nextline: %s type: %d",qPrintable(nextLine),nextLineType); return str; } } //parse the statement, search and add the new file to stack bool RibFileStack::readArchive(QString line) { QStringList token = ribParser::splitStatement(&line); //test if it's a statement to open a new file if(ribProc->value(token[0]) == ribParser::READARCHIVE) { //if it's a ReadArchive statement search the next file to parse QString filename = token[2]; //token[2] is the file name //search in subdir list return searchFile(filename); } return false; } //search file in subdir and add to stack bool RibFileStack::searchFile(QString filename) { //search in subdir list for(int i=0; ivalue(token); } bool RibFileStack::hasNext() const { return !stack->isEmpty(); }; //append a directory list to the list of stack bool RibFileStack::addSubDirs(QStringList dirs) { foreach(QString dir,dirs) subDir.append(dir); return true; };