source: tags/1.1/token.cpp @ 5

Last change on this file since 5 was 5, checked in by willem, 11 years ago

willem

File size: 5.0 KB
Line 
1#include <fstream>
2#include "token.h"
3#include "tofromstring.h"
4
5//
6// a token is a record in the pool file.
7// Format:
8// nmmmsssssssssssssssssssssssssssssssssssssssssssssssssssssssss
9// ||  |
10// ||  string
11// |number of times this string has been geven out   
12// 0: not ready. 1: ready
13//
14// constructor:
15token::token()
16{
17  this->setvalue("");    // value (string)
18  this->setlinenr(0);    // line number
19  this->clearstatus();   // status: ready or not
20  this->setcommitted(0); // counter
21  this->pmarker = "pp";  // this marks the start of the pointer record
22  this->pmarkerlen = this->pmarker.length();
23}
24void token::clearstatus()
25{
26  this->status = '0';
27}
28char token::getstatus(void)
29{
30  return this->status;
31}
32void token::ready()
33{
34  this->status = '1';
35}
36bool token::getready(void)
37{
38  return this->status == '1';
39}
40void token::setvalue(std::string v)
41{
42  this->value = v;
43}
44void token::setlinenr(unsigned int l)
45{
46  this->linenr = l;
47}
48unsigned int token::getlinenr(void)
49{
50  return this->linenr;
51}
52std::string token::getvalue(void)
53{
54  return this->value;
55}
56void token::setcommitted(unsigned int n)
57{
58  this->committed = n;
59}
60unsigned int token::getcommitted(void)
61{
62  return this->committed;
63}
64std::string token::gettotal(void)
65{
66  return this->status + to_string(this->committed,comlen) + 
67            to_string(this->linenr,linenrlen)+ this->value;
68}
69//
70// puts everything that we know in repective variables
71//
72int token::puttotal(std::string t)
73{
74  if (t.length() < this->valuestart)
75    return 1;
76  // check that all chars before the value are [0-9]:
77  for (unsigned int i=0; i<valuestart; i++)
78  {
79    if (t[i] < '0' || t[i] > '9')
80      return 1;
81  }
82
83  switch (t[this->statstart])
84  {
85    case '0': break;
86    case '1': break;
87    default: return 1;
88             break;
89  }
90
91  this->committed = from_string<long>(t.substr(comstart,comlen));
92  this->status = t[0];
93  this->linenr = from_string<unsigned int>(t.substr(linenrstart,linenrlen));
94  if (t.length() == valuestart)
95    this->value="";
96  else
97    this->value=t.substr(valuestart);
98  return 0;
99}
100//
101// the file with the tokens
102//
103void token::setfile(std::fstream& file)
104{
105  this->file = &file;
106}
107
108//
109// read token from file, from position pos, possibly
110// wrap around
111// on return: posused is used position
112//            posnext is position of next token
113//
114int token::readnext(std::streampos pos, std::streampos& posused, std::streampos& posnext)
115{
116  //
117  // note: file is member of class token
118  //
119  posused = pos;
120  file->seekg(posused);
121  std::string line;
122  getline(*file,line);
123  if (file->eof() || file->fail() || file->bad())
124    return -1;
125  if (line.substr(0,this->pmarkerlen) == this->pmarker)
126  {
127    posused = 0;
128    file->seekg(posused);
129    getline(*file,line);
130    if (line.substr(0,this->pmarkerlen) == this->pmarker)
131      return -1;
132  }
133  if (file->eof() || file->fail() || file->bad())
134    return -1;
135  posnext = file->tellg();
136  return puttotal(line);
137}
138
139//
140// rewrite token on position p
141// on return, p contains the postion of the next token
142//
143int token::writetoken(std::streampos& p)
144{
145  this->file->seekp(p);
146  *file << this->gettotal() << std::endl;
147  p = this->file->tellp();
148  this->file->flush();
149
150  return 0;
151}
152
153//
154// rewrites the location pointer
155//
156int token::writelocpointer(std::streampos locpointer)
157{
158  //
159  // note: in this function, file is member of class token
160  //
161  std::streampos g = file->tellg();
162  std::streampos p = file->tellp();
163  //
164  // check if last line already contains locpointer
165  //
166  file->seekg(0,std::ios::end);
167  long long filelength = file->tellg();
168  long long l = this->pointerlen +this->pmarkerlen+2;
169  if ( l > filelength)
170  {
171    //
172    // this file has no locpointer
173    //
174    file->seekp(0,std::ios::end);
175  }
176  else
177  {
178    file->seekg(-l,std::ios::end);
179    char c  = file->get();
180    std::string line;
181    getline(*file,line);
182    if (line.length() == this->pointerlen + this->pmarkerlen
183        && line.substr(0,pmarkerlen) == pmarker
184        && c == '\n')
185    {
186      //
187      // this is a record with a locpointer value
188      //
189      file->seekp(-(std::streampos)((this->pointerlen)+this->pmarkerlen+1),std::ios::end);
190    }
191    else
192    {
193      file->seekp(0,std::ios::end);
194    }
195  }
196  *file << pmarker << std::setfill('0') << std::setw(this->pointerlen) <<
197    locpointer << std::endl;
198  file->flush();
199  file->seekg(g);
200  file->seekp(p);
201  return 0;
202}
203
204//
205// reads the location pinter
206// returns the value of the location pointer,
207//   -1 if error
208//
209std::streampos token::readlocpointer()
210{
211  std::streampos g = file->tellg();
212
213  long long l = this->pointerlen + this->pmarkerlen +2;
214  file->seekg(0,std::ios::end);
215  char c;
216  if (file->tellg() < l)
217  {
218    file->seekg(0);
219    c = '\n';
220  }
221  else
222  {
223    file->seekg(-l,std::ios::end);
224    c  = file->get();
225  }
226  std::string line;
227  getline(*file,line);
228  if (line.length() == this->pointerlen + this->pmarkerlen
229      && line.substr(0,pmarkerlen) == pmarker
230      && c == '\n')
231    return from_string<long>(line.substr(2));
232  else
233    return -1;
234  file->seekg(g);
235  return 0;
236}
Note: See TracBrowser for help on using the repository browser.