forest-net
an overlay networks for large-scale virtual worlds
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
NetBuffer.cpp
Go to the documentation of this file.
1 
9 #include "NetBuffer.h"
10 
11 namespace forest {
12 
18 NetBuffer::NetBuffer(int socket, int size1) : sock(socket), size(size1) {
19  buf = new char[size];
20  rp = wp = buf;
21  noRefill = false;
22 }
23 
24 NetBuffer::NetBuffer(string& s) : size(s.length()) {
25  buf = new char[size+1];
26  s.copy(buf,size);
27  rp = buf; wp = rp + size;
28  noRefill = true;
29 }
30 
31 NetBuffer::NetBuffer(char *p, int size1) : size(size1) {
32  buf = new char[size+1];
33  memcpy(buf,p,size);
34  rp = buf; wp = rp + size;
35  noRefill = true;
36 }
37 
38 NetBuffer::~NetBuffer() { delete buf; }
39 
42 void NetBuffer::reset(string& s) {
43  if (s.length() > size) {
44  delete [] buf;
45  size = s.length();
46  buf = new char[size+1];
47  }
48  s.copy(buf,size);
49  rp = buf; wp = rp + s.length();
50  noRefill = true;
51 }
52 
53 void NetBuffer::reset(char *p, int nuSize) {
54  if (nuSize > size) {
55  delete [] buf;
56  size = nuSize;
57  buf = new char[size+1];
58  }
59  memcpy(buf,p,nuSize);
60  rp = buf; wp = rp + nuSize;
61  noRefill = true;
62 }
63 
69  if (noRefill || full()) return false;
70  int n, len;
71  if (wp < rp) {
72  len = (rp-1) - wp;
73  } else {
74  len = buf+size - wp;
75  if (rp == buf) len--;
76  }
77  n = recv(sock,wp,len,0);
78  if (n <= 0) return false;
79  advance(wp,n);
80  return true;
81 }
82 
87 void NetBuffer::extract(int len, string& s) {
88  if (rp+len <= buf+size) {
89  s.assign(rp,len);
90  } else {
91  int len1 = buf+size-rp;
92  s.assign(rp,len1);
93  s.append(buf,len-len1);
94  }
95  advance(rp,len);
96 }
97 
104  char* p = rp;
105  while (true) {
106  if (p == wp && !refill()) return false;
107  if (!isspace(*p)) break;
108  advance(p);
109  }
110  rp = p; return true;
111 }
112 
119  char* p = rp;
120  while (true) {
121  if (p == wp && !refill()) return false;
122  if (!isspace(*p) || *p == '\n') break;
123  advance(p);
124  }
125  rp = p; return true;
126 }
127 
139 bool NetBuffer::readLine(string& line) {
140  char* p = rp; int len = 0;
141  while (true) {
142  if (p == wp && !refill()) return false;
143  if (*p == '\n') {
144  extract(len,line);
145  rp++; if (rp >= buf+size) rp = buf;
146  return true;
147  }
148  len++; advance(p);
149  }
150 }
151 
160 bool NetBuffer::readWord(string& s) {
161  if (!skipSpace()) return false;
162  char* p = rp;
163  if (!isWordChar(*p)) return false;
164  int len = 0;
165  while (true) {
166  if (p == wp && !refill()) return false;
167  if (!isWordChar(*p)) {
168  if (len == 0) return false;
169  extract(len,s); return true;
170  }
171  advance(p); len++;
172  }
173 }
174 
179 bool NetBuffer::readAlphas(string& s) {
180  if (!skipSpace()) return false;
181  char* p = rp;
182  if (!isalpha(*p)) return false;
183  int len = 0;
184  while (true) {
185  if (p == wp && !refill()) {
186  return false;
187  }
188  if (!isalpha(*p)) {
189  if (len == 0) return false;
190  extract(len,s);
191  return true;
192  }
193  advance(p); len++;
194  }
195 }
196 
205 bool NetBuffer::readName(string& s) {
206  if (!skipSpace()) return false;
207  char* p = rp;
208  if (!isalpha(*p)) return false;
209  int len = 0;
210  while (true) {
211  if (p == wp && !refill()) return false;
212  if (!isalpha(*p) && !isdigit(*p) && *p != '_') {
213  if (len == 0) return false;
214  extract(len,s); return true;
215  }
216  advance(p); len++;
217  }
218 }
219 
226 bool NetBuffer::readString(string& s) {
227  if (!skipSpace()) return false;
228  char* p = rp;
229  if (*p != '\"') return false;
230  advance(p); rp = p; int len = 0;
231  while (true) {
232  if (p == wp && !refill()) return false;
233  if (*p == '\"') {
234  extract(len,s); advance(rp); return true;
235  }
236  len++; advance(p);
237  }
238 }
239 
245 bool NetBuffer::readBit(bool& b) {
246  if (!skipSpace()) return false;
247  if (*rp == '0') { advance(rp); b = false; return true; }
248  if (*rp == '1') { advance(rp); b = true; return true; }
249  return false;
250 }
251 
258 bool NetBuffer::readInt(int& i) {
259  if (!skipSpace()) return false;
260  char* p = rp;
261  if (!isdigit(*p) && *p != '-') return false;
262  advance(p); int len = 1;
263  while (true) {
264  if (p == wp && !refill()) return false;
265  if (!isdigit(*p)) {
266  if (len == 0) return false;
267  string s; extract(len,s);
268  istringstream ss(s); ss >> i;
269  return true;
270  }
271  len++; advance(p);
272  }
273 }
274 
275 bool NetBuffer::readInt(uint64_t& i) {
276  if (!skipSpace()) return false;
277  char* p = rp;
278  if (!isdigit(*p) && *p != '-') return false;
279  advance(p); int len = 1;
280  while (true) {
281  if (p == wp && !refill()) return false;
282  if (!isdigit(*p)) {
283  if (len == 0) return false;
284  string s; extract(len,s);
285  istringstream ss(s); ss >> i;
286  return true;
287  }
288  len++; advance(p);
289  }
290 }
291 
299  if (!skipSpace()) return false;
300  char* p = rp;
301  if (!isdigit(*p)) return false;
302  int len = 0; int dotCount = 0;
303  while (true) {
304  if (p == wp && !refill()) return false;
305  if (*p == '.' && dotCount < 1) {
306  dotCount++;
307  } else if (!isdigit(*p) && *p != '.') {
308  if (len == 0) return false;
309  extract(len,s);
310  return true;
311  }
312  len++; advance(p);
313  }
314 }
315 
316 bool NetBuffer::readPktType(Forest::ptyp_t& type) {
317  string s;
318  if (!readWord(s)) return false;
319  return Packet::string2pktTyp(s,type);
320 }
321 
322 bool NetBuffer::readCpType(CtlPkt::CpType& cpTyp) {
323  string s;
324  if (!readWord(s)) return false;
325  return CtlPkt::string2cpType(s,cpTyp);
326 }
327 
334 bool NetBuffer::readIpAddress(string& s) {
335  if (!skipSpace()) return false;
336  char* p = rp;
337  if (!isdigit(*p)) return false;
338  int len = 0; int dotCount = 0;
339  while (true) {
340  if (p == wp && !refill()) return false;
341  if (*p == '.' && dotCount < 3) {
342  dotCount++;
343  } else if (!isdigit(*p) && *p != '.') {
344  if (len == 0) return false;
345  extract(len,s);
346  return true;
347  }
348  len++; advance(p);
349  }
350 }
351 
352 
359 int NetBuffer::readBlock(char *xbuf, int siz) {
360  char* p = rp; int i = 0;
361  while (i < siz) {
362  if (p == wp && !refill()) break;
363  xbuf[i++] = *p; advance(p);
364  }
365  xbuf[i] = '\0'; rp = p;
366  return i;
367 }
368 
369 bool NetBuffer::readRspec(RateSpec& rates) {
370  int bru, brd, pru, prd;
371  if (verify('(') &&
372  readInt(bru) && verify(',') && readInt(brd) && verify(',') &&
373  readInt(pru) && verify(',') && readInt(prd) && verify(')')) {
374  rates.set(bru,brd,pru,prd); return true;
375  }
376  return false;
377 }
378 
384 bool NetBuffer::verify(char c) {
385  if (!skipSpaceInLine()) return false;
386  if (*rp != c) return false;
387  advance(rp); return true;
388 }
389 
394  char* p = rp;
395  while (true) {
396  if (p == wp && !refill()) return false;
397  if (*p == '\n') break;
398  advance(p);
399  }
400  rp = p; advance(rp); return true;
401 }
402 
407 void NetBuffer::flushBuf(string& leftOver) {
408  int len = (rp <= wp ? wp-rp : size - (rp-wp));
409  extract(len,leftOver);
410  rp = wp = 0;
411 }
412 
415 void NetBuffer::clear() { rp = wp = 0; }
416 
417 string& NetBuffer::toString(string& s) {
418  stringstream ss;
419  ss << "rp=" << (rp-buf) << " wp=" << (wp-buf) << endl;
420  s = ss.str();
421  if (rp <= wp) {
422  s.append(rp,wp-rp);
423  } else {
424  int len1 = buf+size-rp;
425  s.append(rp,len1);
426  s.append(buf,wp-buf);
427  }
428  s += "\n";
429  return s;
430 }
431 
432 } // ends namespace
433