Dillo v3.1.1-46-g8a360e32
Loading...
Searching...
No Matches
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#include "dlib/dlib.h"
10
11namespace lout {
12
18namespace misc {
19
20template <class T> inline T min (T a, T b) { return a < b ? a : b; }
21template <class T> inline T max (T a, T b) { return a > b ? a : b; }
22
23template <class T> inline T min (T a, T b, T c)
24{
25 return (min (a, min (b, c)));
26}
27template <class T> inline T max (T a, T b, T c)
28{
29 return (max (a, max (b, c)));
30}
31
32extern const char *prgName;
33
34void init (int argc, char *argv[]);
35
36inline void assertNotReached ()
37{
38 fprintf (stderr, "*** [%s] This should not happen! ***\n", prgName);
39 abort ();
40}
41
42inline void assertNotReached (const char *fmt, ...)
43{
44 va_list argp;
45 va_start(argp, fmt);
46
47 fprintf (stderr, "*** [%s] This should not happen: ", prgName);
48 vfprintf(stderr, fmt, argp);
49 fprintf (stderr, "! ***\n");
50
51 va_end(argp);
52
53 abort ();
54}
55
56inline void notImplemented (const char *name)
57{
58 fprintf (stderr, "*** [%s] Not implemented: %s ***\n", prgName, name);
59 abort ();
60}
61
62inline int roundInt(double d)
63{
64 return (int) ((d > 0) ? (d + 0.5) : (d - 0.5));
65}
66
67inline int AsciiTolower(char c)
68{
69 return ((c >= 'A' && c <= 'Z') ? c + 0x20 : c);
70}
71
72inline int AsciiToupper(char c)
73{
74 return ((c >= 'a' && c <= 'z') ? c - 0x20 : c);
75}
76
77inline int AsciiStrcasecmp(const char *s1, const char *s2)
78{
79 int ret = 0;
80
81 while ((*s1 || *s2) && !(ret = AsciiTolower(*s1) - AsciiTolower(*s2))) {
82 s1++;
83 s2++;
84 }
85 return ret;
86}
87
88inline const char *boolToStr (bool b) { return b ? "true" : "false"; }
89
94template <class T> class SimpleVector
95{
96private:
99
100 inline void resize ()
101 {
102 /* This algorithm was tuned for memory&speed with this huge page:
103 * http://downloads.mysql.com/docs/refman-6.0-en.html.tar.gz
104 */
105 if (array == NULL) {
106 this->numAlloc = 1;
107 this->array = (T*) malloc (sizeof (T));
108 }
109 if (this->numAlloc < this->num) {
110 this->numAlloc = (this->num < 100) ?
111 this->num : this->num + this->num/10;
112 this->array =
113 (T*) realloc(this->array, (this->numAlloc * sizeof (T)));
114 }
115 }
116
117public:
118 inline SimpleVector (int initAlloc = 1)
119 {
120 this->num = 0;
121 this->numAlloc = initAlloc;
122 this->array = NULL;
123 }
124
125 inline SimpleVector (const SimpleVector &o) {
126 this->array = NULL;
127 this->num = o.num;
128 this->numAlloc = o.numAlloc;
129 resize ();
130 memcpy (this->array, o.array, sizeof (T) * num);
131 }
132
134 {
135 if (this->array)
136 free (this->array);
137 }
138
142 inline int size() const { return this->num; }
143
144 inline bool empty() const { return size() == 0; }
145
146 inline T* getArray() const { return array; }
147
148 inline T* detachArray() {
149 T* arr = array;
150 array = NULL;
151 numAlloc = 0;
152 num = 0;
153 return arr;
154 }
155
161 inline void increase() { setSize(this->num + 1); }
162
168 inline void setSize(int newSize) {
169 assert (newSize >= 0);
170 this->num = newSize;
171 this->resize ();
172 }
173
179 inline void setSize (int newSize, T t) {
180 int oldSize = this->num;
181 setSize (newSize);
182 for (int i = oldSize; i < newSize; i++)
183 set (i, t);
184 }
185
191 inline T* getRef (int i) const {
192 assert (i >= 0 && this->num - i > 0);
193 return array + i;
194 }
195
202 inline T get (int i) const {
203 assert (i >= 0 && this->num - i > 0);
204 return this->array[i];
205 }
206
210 inline T* getFirstRef () const {
211 assert (this->num > 0);
212 return this->array;
213 }
214
218 inline T getFirst () const {
219 assert (this->num > 0);
220 return this->array[0];
221 }
222
226 inline T* getLastRef () const {
227 assert (this->num > 0);
228 return this->array + this->num - 1;
229 }
230
234 inline T getLast () const {
235 assert (this->num > 0);
236 return this->array[this->num - 1];
237 }
238
247 inline void set (int i, T t) {
248 assert (i >= 0 && this->num - i > 0);
249 this->array[i] = t;
250 }
251
255 inline void setLast (T t) {
256 assert (this->num > 0);
257 this->array[this->num - 1] = t;
258 }
259
267 inline void copyTo(SimpleVector<T> *dest, int thisStart = 0,
268 int thisLast = -1, int destStart = 0) {
269 assert (dest != this);
270 if (thisLast == -1)
271 thisLast = this->size () - 1;
272 for (int i = thisStart; i <= thisLast; i++)
273 dest->set (i - thisStart + destStart, get (i));
274 }
275};
276
311template <class T> class NotSoSimpleVector
312{
313private:
316
317 inline void resizeMain ()
318 {
319 /* This algorithm was tuned for memory&speed with this huge page:
320 * http://downloads.mysql.com/docs/refman-6.0-en.html.tar.gz
321 */
322 if (arrayMain == NULL) {
323 this->numAllocMain = 1;
324 this->arrayMain = (T*) malloc (sizeof (T));
325 }
326 if (this->numAllocMain < this->numMain) {
327 this->numAllocMain = (this->numMain < 100) ?
328 this->numMain : this->numMain + this->numMain/10;
329 this->arrayMain =
330 (T*) realloc(this->arrayMain, (this->numAllocMain * sizeof (T)));
331 }
332 }
333
334 inline void resizeExtra ()
335 {
336 /* This algorithm was tuned for memory&speed with this huge page:
337 * http://downloads.mysql.com/docs/refman-6.0-en.html.tar.gz
338 */
339 if (arrayExtra1 == NULL) {
340 this->numAllocExtra = 1;
341 this->arrayExtra1 = (T*) malloc (sizeof (T));
342 this->arrayExtra2 = (T*) malloc (sizeof (T));
343 }
344 if (this->numAllocExtra < this->numExtra) {
345 this->numAllocExtra = (this->numExtra < 100) ?
346 this->numExtra : this->numExtra + this->numExtra/10;
347 this->arrayExtra1 =
348 (T*) realloc(this->arrayExtra1, (this->numAllocExtra * sizeof (T)));
349 this->arrayExtra2 =
350 (T*) realloc(this->arrayExtra2, (this->numAllocExtra * sizeof (T)));
351 }
352 }
353
355 {
356 if (startExtra != -1) {
357 numMain += numExtra;
358 resizeMain ();
360 (numMain - (startExtra + numExtra)) * sizeof (T));
361 memmove (arrayMain + startExtra, arrayExtra1, numExtra * sizeof (T));
362 startExtra = -1;
363 numExtra = 0;
364 }
365 }
366
367public:
368 inline NotSoSimpleVector (int initAlloc)
369 {
370 this->numMain = this->numExtra = 0;
371 this->numAllocMain = initAlloc;
372 this->numAllocExtra = initAlloc;
373 this->arrayMain = this->arrayExtra1 = this->arrayExtra2 = NULL;
374 this->startExtra = -1;
375 }
376
378 {
379 this->arrayMain = NULL;
380 this->numMain = o.numMain;
381 this->numAllocMain = o.numAllocMain;
382 resizeMain ();
383 memcpy (this->arrayMain, o.arrayMain, sizeof (T) * numMain);
384
385 this->arrayExtra = NULL;
386 this->numExtra = o.numExtra;
387 this->numAllocExtra = o.numAllocExtra;
388 resizeExtra ();
389 memcpy (this->arrayExtra, o.arrayExtra, sizeof (T) * numExtra);
390
391 this->startExtra = o.startExtra;
392 }
393
395 {
396 if (this->arrayMain)
397 free (this->arrayMain);
398 if (this->arrayExtra1)
399 free (this->arrayExtra1);
400 if (this->arrayExtra2)
401 free (this->arrayExtra2);
402 }
403
404 inline int size() const { return this->numMain + this->numExtra; }
405
406 inline bool empty() const { return size() == 0; }
407
408 inline void increase() { setSize(size() + 1); }
409
410 inline void setSize(int newSize)
411 {
412 assert (newSize >= 0);
413 this->numMain = newSize - numExtra;
414 this->resizeMain ();
415 }
416
417 void insert (int index, int numInsert)
418 {
419 assert (numInsert >= 0);
420
421 // The following lines are a simple (but inefficient) replacement.
422 //setSize (numMain + numInsert);
423 //memmove (arrayMain + index + numInsert, arrayMain + index,
424 // (numMain - index - numInsert) * sizeof (T));
425 //return;
426
427 if (this->startExtra == -1) {
428 // simple case
429 this->numExtra = numInsert;
430 this->startExtra = index;
431 resizeExtra ();
432 } else {
433 if (index < startExtra) {
434 consolidate ();
435 insert (index, numInsert);
436 } else if (index < startExtra + numExtra) {
437 int oldNumExtra = numExtra;
438 numExtra += numInsert;
439 resizeExtra ();
440
441 int toMove = startExtra + oldNumExtra - index;
442 memmove (arrayExtra1 + numExtra - toMove,
443 arrayExtra1 + index - startExtra,
444 toMove * sizeof (T));
445 } else {
446 int oldNumExtra = numExtra;
447 numExtra += numInsert;
448 resizeExtra ();
449
450 // Note: index refers to the *logical* adress, not to the
451 // *physical* one.
452 int diff = index - this->startExtra - oldNumExtra;
453 T *arrayMainI = arrayMain + this->startExtra;
454 for (int i = diff + oldNumExtra - 1; i >= 0; i--) {
455 T *src = i < oldNumExtra ?
456 this->arrayExtra1 + i : arrayMainI + (i - oldNumExtra);
457 T *dest = i < diff ?
458 arrayMainI + i : arrayExtra2 + (i - diff);
459 *dest = *src;
460 }
461
462 memcpy (arrayExtra1, arrayExtra2, sizeof (T) * oldNumExtra);
463 startExtra = index - oldNumExtra;
464 }
465 }
466 }
467
473 inline T* getRef (int i) const
474 {
475 if (this->startExtra == -1) {
476 assert (i >= 0 && i < this->numMain);
477 return this->arrayMain + i;
478 } else {
479 if (i < this->startExtra) {
480 assert (i >= 0);
481 return this->arrayMain + i;
482 } else if (i >= this->startExtra + this->numExtra) {
483 // The original assertion
485 // "assert (i < this->numMain + this->numExtra)"
486 //
487 // causes this warnung in dw::Textblock::breakAdded:
488 //
489 // "assuming signed overflow does not occur when assuming that
490 // (X - c) > X is always false [-Wstrict-overflow]"
491 //
492 // Subtracting numExtra from both sides solves this,
493 // interrestingly.
494
495 assert (i - this->numExtra < this->numMain);
496 return this->arrayMain + i - this->numExtra;
497 } else
498 return this->arrayExtra1 + i - this->startExtra;
499 }
500 }
501
508 inline T get (int i) const
509 {
510 return *(this->getRef(i));
511 }
512
516 inline T* getFirstRef () const {
517 assert (size () > 0);
518 return this->getRef(0);
519 }
520
524 inline T getFirst () const {
525 return *(this->getFirstRef());
526 }
527
531 inline T* getLastRef () const {
532 assert (size () > 0);
533 return this->getRef(size () - 1);
534 }
535
539 inline T getLast () const {
540 return *(this->getLastRef());
541 }
542
551 inline void set (int i, T t) {
552 *(this->getRef(i)) = t;
553 }
554
558 inline void setLast (T t) {
559 *(this->getLastRef()) = t;
560 }
561};
562
567{
568private:
569 struct Node
570 {
571 char *data;
573 };
574
577 char *str;
579
580public:
581 StringBuffer();
583
590 inline void append(const char *str) { appendNoCopy(dStrdup(str)); }
591 inline void appendInt(int n)
592 { char buf[32]; sprintf (buf, "%d", n); append (buf); }
593 inline void appendPointer(void *p)
594 { char buf[32]; sprintf (buf, "%p", p); append (buf); }
595 inline void appendBool(bool b) { append (b ? "true" : "false"); }
596 void appendNoCopy(char *str);
597 const char *getChars();
598 void clear ();
599};
600
601
606{
607private:
608 unsigned char *bits;
610
611 inline int bytesForBits(int bits) { return bits == 0 ? 1 : (bits + 7) / 8; }
612
613public:
614 BitSet(int initBits);
615 ~BitSet();
617 bool get(int i) const;
618 void set(int i, bool val);
619 void clear();
620};
621
628{
629private:
631 SimpleVector <char*> *pools;
632 SimpleVector <char*> *bulk;
633
634public:
636 this->poolSize = poolSize;
637 this->poolLimit = poolSize / 4;
638 this->freeIdx = poolSize;
639 this->pools = new SimpleVector <char*> (1);
640 this->bulk = new SimpleVector <char*> (1);
641 };
642
644 zoneFree ();
645 delete pools;
646 delete bulk;
647 }
648
649 inline void * zoneAlloc (size_t t) {
650 void *ret;
651
652 if (t > poolLimit) {
653 bulk->increase ();
654 bulk->set (bulk->size () - 1, (char*) malloc (t));
655 return bulk->get (bulk->size () - 1);
656 }
657
658 if (t > poolSize - freeIdx) {
659 pools->increase ();
660 pools->set (pools->size () - 1, (char*) malloc (poolSize));
661 freeIdx = 0;
662 }
663
664 ret = pools->get (pools->size () - 1) + freeIdx;
665 freeIdx += t;
666 return ret;
667 }
668
669 inline void zoneFree () {
670 for (int i = 0; i < pools->size (); i++)
671 free (pools->get (i));
672 pools->setSize (0);
673 for (int i = 0; i < bulk->size (); i++)
674 free (bulk->get (i));
675 bulk->setSize (0);
677 }
678
679 inline const char *strndup (const char *str, size_t t) {
680 char *new_str = (char *) zoneAlloc (t + 1);
681 memcpy (new_str, str, t);
682 new_str[t] = '\0';
683 return new_str;
684 }
685
686 inline const char *strdup (const char *str) {
687 return strndup (str, strlen (str));
688 }
689};
690
691} // namespace misc
692
693} // namespace lout
694
695#endif // __LOUT_MISC_HH__
A bit set, which automatically reallocates when needed.
Definition misc.hh:606
void intoStringBuffer(misc::StringBuffer *sb)
Definition misc.cc:141
void set(int i, bool val)
Definition misc.cc:157
bool get(int i) const
Definition misc.cc:149
int bytesForBits(int bits)
Definition misc.hh:611
unsigned char * bits
Definition misc.hh:608
Container similar to lout::misc::SimpleVector, but some cases of insertion optimized (used for hyphen...
Definition misc.hh:312
NotSoSimpleVector(int initAlloc)
Definition misc.hh:368
T getFirst() const
Return the first element, explicitly.
Definition misc.hh:524
void set(int i, T t)
Store an object in the vector.
Definition misc.hh:551
T * getLastRef() const
Return the reference of the last element (convenience method).
Definition misc.hh:531
void insert(int index, int numInsert)
Definition misc.hh:417
T * getFirstRef() const
Return the reference of the first element (convenience method).
Definition misc.hh:516
void setSize(int newSize)
Definition misc.hh:410
T get(int i) const
Return the one element, explicitly.
Definition misc.hh:508
T getLast() const
Return the last element, explicitly.
Definition misc.hh:539
T * getRef(int i) const
Return the reference of one element.
Definition misc.hh:473
NotSoSimpleVector(const NotSoSimpleVector &o)
Definition misc.hh:377
void setLast(T t)
Store an object at the end of the vector.
Definition misc.hh:558
Simple (simpler than container::untyped::Vector and container::typed::Vector) template based vector.
Definition misc.hh:95
SimpleVector(const SimpleVector &o)
Definition misc.hh:125
void setSize(int newSize)
Set the size explicitly.
Definition misc.hh:168
void increase()
Increase the vector size by one.
Definition misc.hh:161
T * getArray() const
Definition misc.hh:146
void copyTo(SimpleVector< T > *dest, int thisStart=0, int thisLast=-1, int destStart=0)
Copies some elements into another vector of the same type.
Definition misc.hh:267
T getFirst() const
Return the first element, explicitly.
Definition misc.hh:218
void setSize(int newSize, T t)
Set the size explicitly and initialize new values.
Definition misc.hh:179
T * getFirstRef() const
Return the reference of the first element (convenience method).
Definition misc.hh:210
void set(int i, T t)
Store an object in the vector.
Definition misc.hh:247
T get(int i) const
Return the one element, explicitly.
Definition misc.hh:202
int size() const
Return the number of elements put into this vector.
Definition misc.hh:142
T * getRef(int i) const
Return the reference of one element.
Definition misc.hh:191
T * getLastRef() const
Return the reference of the last element (convenience method).
Definition misc.hh:226
void setLast(T t)
Store an object at the end of the vector.
Definition misc.hh:255
bool empty() const
Definition misc.hh:144
T getLast() const
Return the last element, explicitly.
Definition misc.hh:234
SimpleVector(int initAlloc=1)
Definition misc.hh:118
A class for fast concatenation of a large number of strings.
Definition misc.hh:567
void appendBool(bool b)
Definition misc.hh:595
void appendPointer(void *p)
Definition misc.hh:593
void clear()
Remove all strings appended to the string buffer.
Definition misc.cc:110
void appendInt(int n)
Definition misc.hh:591
void append(const char *str)
Append a NUL-terminated string to the buffer, with copying.
Definition misc.hh:590
void appendNoCopy(char *str)
Append a NUL-terminated string to the buffer, without copying.
Definition misc.cc:62
const char * getChars()
Return a NUL-terminated strings containing all appended strings.
Definition misc.cc:86
A simple allocator optimized to handle many small chunks of memory.
Definition misc.hh:628
const char * strdup(const char *str)
Definition misc.hh:686
const char * strndup(const char *str, size_t t)
Definition misc.hh:679
void * zoneAlloc(size_t t)
Definition misc.hh:649
ZoneAllocator(size_t poolSize)
Definition misc.hh:635
SimpleVector< char * > * bulk
Definition misc.hh:632
SimpleVector< char * > * pools
Definition misc.hh:631
char * dStrdup(const char *s)
Definition dlib.c:77
T min(T a, T b)
Definition misc.hh:20
void notImplemented(const char *name)
Definition misc.hh:56
T max(T a, T b)
Definition misc.hh:21
const char * prgName
Definition misc.cc:33
int AsciiStrcasecmp(const char *s1, const char *s2)
Definition misc.hh:77
int roundInt(double d)
Definition misc.hh:62
void init(int argc, char *argv[])
int AsciiTolower(char c)
Definition misc.hh:67
int AsciiToupper(char c)
Definition misc.hh:72
void assertNotReached()
Definition misc.hh:36
const char * boolToStr(bool b)
Definition misc.hh:88