#include #include "token.h" #include "tofromstring.h" // // a token is a record in the pool file. // Format: // nmmmsssssssssssssssssssssssssssssssssssssssssssssssssssssssss // || | // || string // |number of times this string has been geven out // 0: not ready. 1: ready // // constructor: token::token() { this->setvalue(""); // value (string) this->setlinenr(0); // line number this->clearstatus(); // status: ready or not this->setcommitted(0); // counter this->pmarker = "pp"; // this marks the start of the pointer record this->pmarkerlen = this->pmarker.length(); } void token::clearstatus() { this->status = '0'; } char token::getstatus(void) { return this->status; } void token::ready() { this->status = '1'; } bool token::getready(void) { return this->status == '1'; } void token::setvalue(std::string v) { this->value = v; } void token::setlinenr(unsigned int l) { this->linenr = l; } unsigned int token::getlinenr(void) { return this->linenr; } std::string token::getvalue(void) { return this->value; } void token::setcommitted(unsigned int n) { this->committed = n; } unsigned int token::getcommitted(void) { return this->committed; } std::string token::gettotal(void) { return this->status + to_string(this->committed,comlen) + to_string(this->linenr,linenrlen)+ this->value; } // // puts everything that we know in repective variables // int token::puttotal(std::string t) { if (t.length() < this->valuestart) return 1; // check that all chars before the value are [0-9]: for (unsigned int i=0; i '9') return 1; } switch (t[this->statstart]) { case '0': break; case '1': break; default: return 1; break; } this->committed = from_string(t.substr(comstart,comlen)); this->status = t[0]; this->linenr = from_string(t.substr(linenrstart,linenrlen)); if (t.length() == valuestart) this->value=""; else this->value=t.substr(valuestart); return 0; } // // the file with the tokens // void token::setfile(std::fstream& file) { this->file = &file; } // // read token from file, from position pos, possibly // wrap around // on return: posused is used position // posnext is position of next token // int token::readnext(std::streampos pos, std::streampos& posused, std::streampos& posnext) { // // note: file is member of class token // posused = pos; file->seekg(posused); std::string line; getline(*file,line); if (file->eof() || file->fail() || file->bad()) return -1; if (line.substr(0,this->pmarkerlen) == this->pmarker) { posused = 0; file->seekg(posused); getline(*file,line); if (line.substr(0,this->pmarkerlen) == this->pmarker) return -1; } if (file->eof() || file->fail() || file->bad()) return -1; posnext = file->tellg(); return puttotal(line); } // // rewrite token on position p // on return, p contains the postion of the next token // int token::writetoken(std::streampos& p) { this->file->seekp(p); *file << this->gettotal() << std::endl; p = this->file->tellp(); this->file->flush(); return 0; } // // rewrites the location pointer // int token::writelocpointer(std::streampos locpointer) { // // note: in this function, file is member of class token // std::streampos g = file->tellg(); std::streampos p = file->tellp(); // // check if last line already contains locpointer // file->seekg(0,std::ios::end); long long filelength = file->tellg(); long long l = this->pointerlen +this->pmarkerlen+2; if ( l > filelength) { // // this file has no locpointer // file->seekp(0,std::ios::end); } else { file->seekg(-l,std::ios::end); char c = file->get(); std::string line; getline(*file,line); if (line.length() == this->pointerlen + this->pmarkerlen && line.substr(0,pmarkerlen) == pmarker && c == '\n') { // // this is a record with a locpointer value // file->seekp(-(std::streampos)((this->pointerlen)+this->pmarkerlen+1),std::ios::end); } else { file->seekp(0,std::ios::end); } } *file << pmarker << std::setfill('0') << std::setw(this->pointerlen) << locpointer << std::endl; file->flush(); file->seekg(g); file->seekp(p); return 0; } // // reads the location pinter // returns the value of the location pointer, // -1 if error // std::streampos token::readlocpointer() { std::streampos g = file->tellg(); long long l = this->pointerlen + this->pmarkerlen +2; file->seekg(0,std::ios::end); char c; if (file->tellg() < l) { file->seekg(0); c = '\n'; } else { file->seekg(-l,std::ios::end); c = file->get(); } std::string line; getline(*file,line); if (line.length() == this->pointerlen + this->pmarkerlen && line.substr(0,pmarkerlen) == pmarker && c == '\n') return from_string(line.substr(2)); else return -1; file->seekg(g); return 0; }