dillo  3.0.5
About: dillo is a small, fast, extensible Web browser particularly suitable for older or smaller computers and embedded systems (but only limited or no support for frames, CSS, JavaScript, Java).
  Fossies Dox: dillo-3.0.5.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

misc.hh
Go to the documentation of this file.
1 #ifndef __LOUT_MISC_HH__
2 #define __LOUT_MISC_HH__
3 
4 #include <stdio.h>
5 #include <stdarg.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <assert.h>
9 
10 namespace lout {
11 
17 namespace misc {
18 
19 template <class T> inline T min (T a, T b) { return a < b ? a : b; }
20 template <class T> inline T max (T a, T b) { return a > b ? a : b; }
21 
22 template <class T> inline T min (T a, T b, T c)
23 {
24  return (min (a, min (b, c)));
25 }
26 template <class T> inline T max (T a, T b, T c)
27 {
28  return (max (a, max (b, c)));
29 }
30 
31 extern const char *prgName;
32 
33 void init (int argc, char *argv[]);
34 
35 inline void assertNotReached ()
36 {
37  fprintf (stderr, "*** [%s] This should not happen! ***\n", prgName);
38  abort ();
39 }
40 
41 inline int roundInt(double d)
42 {
43  return (int) ((d > 0) ? (d + 0.5) : (d - 0.5));
44 }
45 
46 inline int AsciiTolower(char c)
47 {
48  return ((c >= 'A' && c <= 'Z') ? c + 0x20 : c);
49 }
50 
51 inline int AsciiToupper(char c)
52 {
53  return ((c >= 'a' && c <= 'z') ? c - 0x20 : c);
54 }
55 
56 inline int AsciiStrcasecmp(const char *s1, const char *s2)
57 {
58  int ret = 0;
59 
60  while ((*s1 || *s2) && !(ret = AsciiTolower(*s1) - AsciiTolower(*s2))) {
61  s1++;
62  s2++;
63  }
64  return ret;
65 }
66 
71 template <class T> class SimpleVector
72 {
73 private:
74  T *array;
75  int num, numAlloc;
76 
77  inline void resize ()
78  {
79  /* This algorithm was tuned for memory&speed with this huge page:
80  * http://downloads.mysql.com/docs/refman-6.0-en.html.tar.gz
81  */
82  if (array == NULL) {
83  this->numAlloc = 1;
84  this->array = (T*) malloc (sizeof (T));
85  }
86  if (this->numAlloc < this->num) {
87  this->numAlloc = (this->num < 100) ?
88  this->num : this->num + this->num/10;
89  this->array =
90  (T*) realloc(this->array, (this->numAlloc * sizeof (T)));
91  }
92  }
93 
94 public:
95  inline SimpleVector (int initAlloc = 1)
96  {
97  this->num = 0;
98  this->numAlloc = initAlloc;
99  this->array = NULL;
100  }
101 
102  inline SimpleVector (const SimpleVector &o) {
103  this->array = NULL;
104  this->num = o.num;
105  this->numAlloc = o.numAlloc;
106  resize ();
107  memcpy (this->array, o.array, sizeof (T) * num);
108  }
109 
110  inline ~SimpleVector ()
111  {
112  if (this->array)
113  free (this->array);
114  }
115 
119  inline int size() const { return this->num; }
120 
121  inline T* getArray() const { return array; }
122 
123  inline T* detachArray() {
124  T* arr = array;
125  array = NULL;
126  numAlloc = 0;
127  num = 0;
128  return arr;
129  }
130 
136  inline void increase() { setSize(this->num + 1); }
137 
143  inline void setSize(int newSize) {
144  assert (newSize >= 0);
145  this->num = newSize;
146  this->resize ();
147  }
148 
154  inline void setSize (int newSize, T t) {
155  int oldSize = this->num;
156  setSize (newSize);
157  for (int i = oldSize; i < newSize; i++)
158  set (i, t);
159  }
160 
166  inline T* getRef (int i) const {
167  assert (i >= 0 && this->num - i > 0);
168  return array + i;
169  }
170 
177  inline T get (int i) const {
178  assert (i >= 0 && this->num - i > 0);
179  return this->array[i];
180  }
181 
185  inline T* getFirstRef () const {
186  assert (this->num > 0);
187  return this->array;
188  }
189 
193  inline T getFirst () const {
194  assert (this->num > 0);
195  return this->array[0];
196  }
197 
201  inline T* getLastRef () const {
202  assert (this->num > 0);
203  return this->array + this->num - 1;
204  }
205 
209  inline T getLast () const {
210  assert (this->num > 0);
211  return this->array[this->num - 1];
212  }
213 
222  inline void set (int i, T t) {
223  assert (i >= 0 && this->num - i > 0);
224  this->array[i] = t;
225  }
226 };
227 
262 template <class T> class NotSoSimpleVector
263 {
264 private:
267 
268  inline void resizeMain ()
269  {
270  /* This algorithm was tuned for memory&speed with this huge page:
271  * http://downloads.mysql.com/docs/refman-6.0-en.html.tar.gz
272  */
273  if (arrayMain == NULL) {
274  this->numAllocMain = 1;
275  this->arrayMain = (T*) malloc (sizeof (T));
276  }
277  if (this->numAllocMain < this->numMain) {
278  this->numAllocMain = (this->numMain < 100) ?
279  this->numMain : this->numMain + this->numMain/10;
280  this->arrayMain =
281  (T*) realloc(this->arrayMain, (this->numAllocMain * sizeof (T)));
282  }
283  }
284 
285  inline void resizeExtra ()
286  {
287  /* This algorithm was tuned for memory&speed with this huge page:
288  * http://downloads.mysql.com/docs/refman-6.0-en.html.tar.gz
289  */
290  if (arrayExtra1 == NULL) {
291  this->numAllocExtra = 1;
292  this->arrayExtra1 = (T*) malloc (sizeof (T));
293  this->arrayExtra2 = (T*) malloc (sizeof (T));
294  }
295  if (this->numAllocExtra < this->numExtra) {
296  this->numAllocExtra = (this->numExtra < 100) ?
297  this->numExtra : this->numExtra + this->numExtra/10;
298  this->arrayExtra1 =
299  (T*) realloc(this->arrayExtra1, (this->numAllocExtra * sizeof (T)));
300  this->arrayExtra2 =
301  (T*) realloc(this->arrayExtra2, (this->numAllocExtra * sizeof (T)));
302  }
303  }
304 
305  void consolidate ()
306  {
307  if (startExtra != -1) {
308  numMain += numExtra;
309  resizeMain ();
311  (numMain - (startExtra + numExtra)) * sizeof (T));
312  memmove (arrayMain + startExtra, arrayExtra1, numExtra * sizeof (T));
313  startExtra = -1;
314  numExtra = 0;
315  }
316  }
317 
318 public:
319  inline NotSoSimpleVector (int initAlloc)
320  {
321  this->numMain = this->numExtra = 0;
322  this->numAllocMain = initAlloc;
323  this->numAllocExtra = initAlloc;
324  this->arrayMain = this->arrayExtra1 = this->arrayExtra2 = NULL;
325  this->startExtra = -1;
326  }
327 
329  {
330  this->arrayMain = NULL;
331  this->numMain = o.numMain;
332  this->numAllocMain = o.numAllocMain;
333  resizeMain ();
334  memcpy (this->arrayMain, o.arrayMain, sizeof (T) * numMain);
335 
336  this->arrayExtra = NULL;
337  this->numExtra = o.numExtra;
338  this->numAllocExtra = o.numAllocExtra;
339  resizeExtra ();
340  memcpy (this->arrayExtra, o.arrayExtra, sizeof (T) * numExtra);
341 
342  this->startExtra = o.startExtra;
343  }
344 
346  {
347  if (this->arrayMain)
348  free (this->arrayMain);
349  if (this->arrayExtra1)
350  free (this->arrayExtra1);
351  if (this->arrayExtra2)
352  free (this->arrayExtra2);
353  }
354 
355  inline int size() const { return this->numMain + this->numExtra; }
356 
357  inline void increase() { setSize(size() + 1); }
358 
359  inline void setSize(int newSize)
360  {
361  assert (newSize >= 0);
362  this->numMain = newSize - numExtra;
363  this->resizeMain ();
364  }
365 
366  void insert (int index, int numInsert)
367  {
368  assert (numInsert >= 0);
369 
370  // The following lines are a simple (but inefficient) replacement.
371  //setSize (numMain + numInsert);
372  //memmove (arrayMain + index + numInsert, arrayMain + index,
373  // (numMain - index - numInsert) * sizeof (T));
374  //return;
375 
376  if (this->startExtra == -1) {
377  // simple case
378  this->numExtra = numInsert;
379  this->startExtra = index;
380  resizeExtra ();
381  } else {
382  if (index < startExtra) {
383  consolidate ();
384  insert (index, numInsert);
385  } else if (index < startExtra + numExtra) {
386  int oldNumExtra = numExtra;
387  numExtra += numInsert;
388  resizeExtra ();
389 
390  int toMove = startExtra + oldNumExtra - index;
391  memmove (arrayExtra1 + numExtra - toMove,
392  arrayExtra1 + index - startExtra,
393  toMove * sizeof (T));
394  } else {
395  int oldNumExtra = numExtra;
396  numExtra += numInsert;
397  resizeExtra ();
398 
399  // Note: index refers to the *logical* adress, not to the
400  // *physical* one.
401  int diff = index - this->startExtra - oldNumExtra;
402  T *arrayMainI = arrayMain + this->startExtra;
403  for (int i = diff + oldNumExtra - 1; i >= 0; i--) {
404  T *src = i < oldNumExtra ?
405  this->arrayExtra1 + i : arrayMainI + (i - oldNumExtra);
406  T *dest = i < diff ?
407  arrayMainI + i : arrayExtra2 + (i - diff);
408  *dest = *src;
409  }
410 
411  memcpy (arrayExtra1, arrayExtra2, sizeof (T) * oldNumExtra);
412  startExtra = index - oldNumExtra;
413  }
414  }
415  }
416 
422  inline T* getRef (int i) const
423  {
424  if (this->startExtra == -1)
425  return this->arrayMain + i;
426  else {
427  if (i < this->startExtra)
428  return this->arrayMain + i;
429  else if (i >= this->startExtra + this->numExtra)
430  return this->arrayMain + i - this->numExtra;
431  else
432  return this->arrayExtra1 + i - this->startExtra;
433  }
434  }
435 
442  inline T get (int i) const
443  {
444  return *(this->getRef(i));
445  }
446 
450  inline T* getFirstRef () const {
451  assert (size () > 0);
452  return this->getRef(0);
453  }
454 
458  inline T getFirst () const {
459  return *(this->getFirstRef());
460  }
461 
465  inline T* getLastRef () const {
466  assert (size () > 0);
467  return this->getRef(size () - 1);
468  }
469 
473  inline T getLast () const {
474  return *(this->getLastRef());
475  }
476 
485  inline void set (int i, T t) {
486  *(this->getRef(i)) = t;
487  }
488 };
489 
494 {
495 private:
496  struct Node
497  {
498  char *data;
500  };
501 
503  int numChars;
504  char *str;
505  bool strValid;
506 
507 public:
508  StringBuffer();
509  ~StringBuffer();
510 
517  inline void append(const char *str) { appendNoCopy(strdup(str)); }
518  void appendNoCopy(char *str);
519  const char *getChars();
520  void clear ();
521 };
522 
523 
527 class BitSet
528 {
529 private:
530  unsigned char *bits;
531  int numBytes;
532 
533  inline int bytesForBits(int bits) { return bits == 0 ? 1 : (bits + 7) / 8; }
534 
535 public:
536  BitSet(int initBits);
537  ~BitSet();
539  bool get(int i) const;
540  void set(int i, bool val);
541  void clear();
542 };
543 
550 {
551 private:
555 
556 public:
558  this->poolSize = poolSize;
559  this->poolLimit = poolSize / 4;
560  this->freeIdx = poolSize;
561  this->pools = new SimpleVector <char*> (1);
562  this->bulk = new SimpleVector <char*> (1);
563  };
564 
566  zoneFree ();
567  delete pools;
568  delete bulk;
569  }
570 
571  inline void * zoneAlloc (size_t t) {
572  void *ret;
573 
574  if (t > poolLimit) {
575  bulk->increase ();
576  bulk->set (bulk->size () - 1, (char*) malloc (t));
577  return bulk->get (bulk->size () - 1);
578  }
579 
580  if (t > poolSize - freeIdx) {
581  pools->increase ();
582  pools->set (pools->size () - 1, (char*) malloc (poolSize));
583  freeIdx = 0;
584  }
585 
586  ret = pools->get (pools->size () - 1) + freeIdx;
587  freeIdx += t;
588  return ret;
589  }
590 
591  inline void zoneFree () {
592  for (int i = 0; i < pools->size (); i++)
593  free (pools->get (i));
594  pools->setSize (0);
595  for (int i = 0; i < bulk->size (); i++)
596  free (bulk->get (i));
597  bulk->setSize (0);
598  freeIdx = poolSize;
599  }
600 
601  inline const char *strndup (const char *str, size_t t) {
602  char *new_str = (char *) zoneAlloc (t + 1);
603  memcpy (new_str, str, t);
604  new_str[t] = '\0';
605  return new_str;
606  }
607 
608  inline const char *strdup (const char *str) {
609  return strndup (str, strlen (str));
610  }
611 };
612 
613 } // namespace misc
614 
615 } // namespace lout
616 
617 #endif // __LOUT_MISC_HH__
lout::misc::ZoneAllocator::zoneAlloc
void * zoneAlloc(size_t t)
Definition: misc.hh:571
lout::misc::SimpleVector::getFirst
T getFirst() const
Return the first element, explicitly.
Definition: misc.hh:193
lout::misc::NotSoSimpleVector::numAllocMain
int numAllocMain
Definition: misc.hh:266
lout::misc::NotSoSimpleVector::getLastRef
T * getLastRef() const
Return the reference of the last element (convenience method).
Definition: misc.hh:465
lout::misc::NotSoSimpleVector::numMain
int numMain
Definition: misc.hh:266
lout::misc::SimpleVector::get
T get(int i) const
Return the one element, explicitly.
Definition: misc.hh:177
lout::misc::SimpleVector::numAlloc
int numAlloc
Definition: misc.hh:75
lout::misc::SimpleVector::getRef
T * getRef(int i) const
Return the reference of one element.
Definition: misc.hh:166
lout::misc::SimpleVector::setSize
void setSize(int newSize)
Set the size explicitly.
Definition: misc.hh:143
lout::misc::StringBuffer::Node
Definition: misc.hh:496
lout::misc::SimpleVector::increase
void increase()
Increase the vector size by one.
Definition: misc.hh:136
lout::misc::ZoneAllocator
A simple allocator optimized to handle many small chunks of memory. The chunks can not be free'd indi...
Definition: misc.hh:549
lout::misc::StringBuffer::firstNode
Node * firstNode
Definition: misc.hh:502
lout::misc::SimpleVector::num
int num
Definition: misc.hh:75
lout::misc::NotSoSimpleVector::setSize
void setSize(int newSize)
Definition: misc.hh:359
lout::misc::BitSet::clear
void clear()
Definition: misc.cc:180
lout::misc::assertNotReached
void assertNotReached()
Definition: misc.hh:35
lout::misc::NotSoSimpleVector::getFirst
T getFirst() const
Return the first element, explicitly.
Definition: misc.hh:458
lout::misc::SimpleVector::resize
void resize()
Definition: misc.hh:77
lout::misc::BitSet
A bit set, which automatically reallocates when needed.
Definition: misc.hh:527
lout::misc::ZoneAllocator::ZoneAllocator
ZoneAllocator(size_t poolSize)
Definition: misc.hh:557
lout::misc::SimpleVector::getArray
T * getArray() const
Definition: misc.hh:121
lout::misc::SimpleVector::detachArray
T * detachArray()
Definition: misc.hh:123
lout::misc::NotSoSimpleVector::arrayExtra2
T * arrayExtra2
Definition: misc.hh:265
lout::misc::NotSoSimpleVector::NotSoSimpleVector
NotSoSimpleVector(int initAlloc)
Definition: misc.hh:319
lout::misc::StringBuffer::strValid
bool strValid
Definition: misc.hh:505
lout::misc::SimpleVector::getLastRef
T * getLastRef() const
Return the reference of the last element (convenience method).
Definition: misc.hh:201
lout::misc::SimpleVector::size
int size() const
Return the number of elements put into this vector.
Definition: misc.hh:119
lout::misc::StringBuffer::numChars
int numChars
Definition: misc.hh:503
lout::misc::max
T max(T a, T b)
Definition: misc.hh:20
lout::misc::ZoneAllocator::pools
SimpleVector< char * > * pools
Definition: misc.hh:553
lout::misc::min
T min(T a, T b)
Definition: misc.hh:19
lout::misc::BitSet::bits
unsigned char * bits
Definition: misc.hh:530
lout::misc::StringBuffer::~StringBuffer
~StringBuffer()
Definition: misc.cc:54
lout::misc::NotSoSimpleVector::consolidate
void consolidate()
Definition: misc.hh:305
lout::misc::BitSet::~BitSet
~BitSet()
Definition: misc.cc:141
lout::misc::ZoneAllocator::bulk
SimpleVector< char * > * bulk
Definition: misc.hh:554
lout::misc::StringBuffer::Node::data
char * data
Definition: misc.hh:498
lout::misc::SimpleVector::set
void set(int i, T t)
Store an object in the vector.
Definition: misc.hh:222
lout::misc::SimpleVector::~SimpleVector
~SimpleVector()
Definition: misc.hh:110
lout::misc::ZoneAllocator::strdup
const char * strdup(const char *str)
Definition: misc.hh:608
lout::misc::prgName
const char * prgName
Definition: misc.cc:33
lout::misc::StringBuffer
A class for fast concatenation of a large number of strings.
Definition: misc.hh:493
lout::misc::NotSoSimpleVector::arrayExtra1
T * arrayExtra1
Definition: misc.hh:265
lout::misc::StringBuffer::StringBuffer
StringBuffer()
Definition: misc.cc:46
lout::misc::NotSoSimpleVector::resizeExtra
void resizeExtra()
Definition: misc.hh:285
lout::misc::AsciiStrcasecmp
int AsciiStrcasecmp(const char *s1, const char *s2)
Definition: misc.hh:56
lout::misc::NotSoSimpleVector::getLast
T getLast() const
Return the last element, explicitly.
Definition: misc.hh:473
lout::misc::ZoneAllocator::poolSize
size_t poolSize
Definition: misc.hh:552
lout::misc::ZoneAllocator::~ZoneAllocator
~ZoneAllocator()
Definition: misc.hh:565
lout::misc::NotSoSimpleVector::set
void set(int i, T t)
Store an object in the vector.
Definition: misc.hh:485
lout::misc::BitSet::get
bool get(int i) const
Definition: misc.cc:154
lout::misc::NotSoSimpleVector::size
int size() const
Definition: misc.hh:355
lout
Definition: container.cc:26
lout::misc::SimpleVector::setSize
void setSize(int newSize, T t)
Set the size explicitly and initialize new values.
Definition: misc.hh:154
lout::misc::StringBuffer::append
void append(const char *str)
Append a NUL-terminated string to the buffer, with copying.
Definition: misc.hh:517
lout::misc::AsciiToupper
int AsciiToupper(char c)
Definition: misc.hh:51
lout::misc::BitSet::set
void set(int i, bool val)
Definition: misc.cc:162
lout::misc::NotSoSimpleVector::NotSoSimpleVector
NotSoSimpleVector(const NotSoSimpleVector &o)
Definition: misc.hh:328
lout::misc::SimpleVector::SimpleVector
SimpleVector(int initAlloc=1)
Definition: misc.hh:95
lout::misc::ZoneAllocator::strndup
const char * strndup(const char *str, size_t t)
Definition: misc.hh:601
lout::misc::NotSoSimpleVector::numAllocExtra
int numAllocExtra
Definition: misc.hh:266
lout::misc::SimpleVector::SimpleVector
SimpleVector(const SimpleVector &o)
Definition: misc.hh:102
lout::misc::ZoneAllocator::zoneFree
void zoneFree()
Definition: misc.hh:591
lout::misc::BitSet::intoStringBuffer
void intoStringBuffer(misc::StringBuffer *sb)
Definition: misc.cc:146
lout::misc::init
void init(int argc, char *argv[])
Definition: misc.cc:35
lout::misc::NotSoSimpleVector::startExtra
int startExtra
Definition: misc.hh:266
lout::misc::ZoneAllocator::poolLimit
size_t poolLimit
Definition: misc.hh:552
lout::misc::NotSoSimpleVector
Container similar to lout::misc::SimpleVector, but some cases of insertion optimized (used for hyphen...
Definition: misc.hh:262
lout::misc::NotSoSimpleVector::~NotSoSimpleVector
~NotSoSimpleVector()
Definition: misc.hh:345
lout::misc::NotSoSimpleVector::getFirstRef
T * getFirstRef() const
Return the reference of the first element (convenience method).
Definition: misc.hh:450
lout::misc::NotSoSimpleVector::arrayMain
T * arrayMain
Definition: misc.hh:265
lout::misc::NotSoSimpleVector::increase
void increase()
Definition: misc.hh:357
lout::misc::BitSet::numBytes
int numBytes
Definition: misc.hh:531
lout::misc::BitSet::bytesForBits
int bytesForBits(int bits)
Definition: misc.hh:533
lout::misc::StringBuffer::appendNoCopy
void appendNoCopy(char *str)
Append a NUL-terminated string to the buffer, without copying.
Definition: misc.cc:68
lout::misc::StringBuffer::Node::next
Node * next
Definition: misc.hh:499
lout::misc::NotSoSimpleVector::insert
void insert(int index, int numInsert)
Definition: misc.hh:366
lout::misc::SimpleVector::getLast
T getLast() const
Return the last element, explicitly.
Definition: misc.hh:209
lout::misc::roundInt
int roundInt(double d)
Definition: misc.hh:41
lout::misc::StringBuffer::getChars
const char * getChars()
Return a NUL-terminated strings containing all appended strings.
Definition: misc.cc:92
lout::misc::NotSoSimpleVector::getRef
T * getRef(int i) const
Return the reference of one element.
Definition: misc.hh:422
lout::misc::StringBuffer::lastNode
Node * lastNode
Definition: misc.hh:502
lout::misc::SimpleVector::getFirstRef
T * getFirstRef() const
Return the reference of the first element (convenience method).
Definition: misc.hh:185
lout::misc::NotSoSimpleVector::resizeMain
void resizeMain()
Definition: misc.hh:268
lout::misc::SimpleVector
Simple (simpler than container::untyped::Vector and container::typed::Vector) template based vector.
Definition: misc.hh:71
lout::misc::StringBuffer::clear
void clear()
Remove all strings appended to the string buffer.
Definition: misc.cc:116
lout::misc::SimpleVector::array
T * array
Definition: misc.hh:74
lout::misc::AsciiTolower
int AsciiTolower(char c)
Definition: misc.hh:46
lout::misc::ZoneAllocator::freeIdx
size_t freeIdx
Definition: misc.hh:552
lout::misc::NotSoSimpleVector::get
T get(int i) const
Return the one element, explicitly.
Definition: misc.hh:442
lout::misc::StringBuffer::str
char * str
Definition: misc.hh:504
lout::misc::NotSoSimpleVector::numExtra
int numExtra
Definition: misc.hh:266
lout::misc::BitSet::BitSet
BitSet(int initBits)
Definition: misc.cc:134