#define __STDC_CONSTANT_MACROS #include #ifndef UINT64_C # error missing c99 support, define UINT64_C yourself # define UINT64_C(c) c ## LL #endif #include "global.h" #include dynbuf::dynbuf (int initial, int extend) { _size = 0; ext = extend; first = last = (chunk *)new char [sizeof (chunk) + initial]; first->next = 0; room = initial; ptr = first->data; } dynbuf::~dynbuf () { clear (); } void dynbuf::clear () { while (first) { chunk *next = first->next; delete [] (char *)first; first = next; } } void dynbuf::finish () { // finalise current chunk _size += last->size = ptr - last->data; } void dynbuf::_reserve (int size) { finish (); do { ext += ext >> 1; ext = (ext + 15) & ~15; } while (ext < size); chunk *add = (chunk *)new char [sizeof (chunk) + ext]; add->next = 0; last->next = add; last = add; room = ext; ptr = last->data; } void dynbuf::linearise (void *data) { char *p = (char *)data; last->size = ptr - last->data; for (chunk *c = first; c; c = c->next) { memcpy (p, c->data, c->size); p += c->size; } } char *dynbuf::linearise () { if (first->next) { finish (); chunk *add = (chunk *)new char [sizeof (chunk) + _size]; add->next = 0; linearise ((void *)add->data); clear (); first = last = add; ptr = last->data + _size; _size = 0; room = 0; } return first->data; } void dynbuf::add (sint32 i) { char buf [max_sint32_size]; char *p = buf + sizeof (buf); char neg; if (i < 0) { neg = '-'; i = -i; } else neg = 0; uint32 val = i; do { uint32 div = val / 10; *--p = '0' + char (val - div * 10); val = div; } while (val); if (neg) *--p = neg; add ((void *)p, buf + sizeof (buf) - p); } void dynbuf::add (sint64 i) { if (i > -10000000 && i < 10000000) { add (sint32 (i)); return; } uint64 val; if (i < 0) { add ('-'); val = -i; } else val = i; if (val > UINT64_C (1000000000000000)) { add (sint32 (val / UINT64_C (1000000000000000))); val %= UINT64_C (1000000000000000); } if (val > 10000000) { add (sint32 (val / 10000000)); val %= 10000000; } add (sint32 (val)); }