source: trunk/token.cpp @ 4

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

willem

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