|
|
1.1 paf 1: /** @file
2: Parser: ISAPI: pool storage class decl.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
5:
6: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
7:
1.6 ! parser 8: $Id: pool_storage.h,v 1.5 2001/09/15 11:48:41 parser Exp $
1.1 paf 9: */
10:
11: #ifndef PA_POOL_STORAGE_H
12: #define PA_POOL_STORAGE_H
13:
14: #include "pa_config_includes.h"
15:
16: /**
17: Dumb pool allocations accounter
18:
1.4 paf 19: @todo implement at least simple suballocations
1.1 paf 20: */
21: class Pool_storage {
1.6 ! parser 22:
! 23: class List {
! 24: friend Pool_storage;
! 25: public:
! 26: List(int preallocate_elements, size_t aitem_size) :
! 27: items((char *)::malloc(preallocate_elements*aitem_size)), item_size(aitem_size),
! 28: allocated_elements(0),
! 29: used_elements(0) {
! 30: if(items) // successfully preallocated?
! 31: allocated_elements=preallocate_elements;
! 32: }
! 33:
! 34: ~List() {
! 35: free(items);
! 36: }
! 37:
! 38: void *add(void *item) {
! 39: if(full())
! 40: if(!expand())
! 41: return 0;
! 42:
! 43: return memcpy(&items[(used_elements++)*item_size], item, item_size);
! 44: }
! 45:
! 46: private:
! 47:
! 48: bool full() { return used_elements==allocated_elements; }
! 49: bool expand() {
! 50: size_t new_allocated=allocated_elements*3/2;
! 51: char *new_items=(char *)::realloc(items, new_allocated*item_size);
! 52: if(new_items) {
! 53: items=new_items;
! 54: allocated_elements=new_allocated;
! 55: return true;
! 56: } else
! 57: return false;
! 58: }
! 59:
! 60: private:
! 61:
! 62: char *items; size_t item_size;
! 63: size_t allocated_elements;
! 64: size_t used_elements;
! 65:
! 66: };
! 67:
! 68: struct Cleanup_struct {
! 69: void (*cleanup) (void *);
! 70: void *data;
! 71: };
! 72:
! 73:
1.1 paf 74: public:
75:
1.6 ! parser 76: Pool_storage() :
! 77: allocations(10*0x400, sizeof(void *)),
! 78: cleanups(100, sizeof(Cleanup_struct)) {
1.1 paf 79: }
80:
1.6 ! parser 81: void *malloc(size_t size) { return allocations.add(::malloc(size)); }
! 82: void *calloc(size_t size) { return allocations.add(::calloc(size, 1)); }
1.1 paf 83:
1.6 ! parser 84: bool register_cleanup(void (*cleanup) (void *), void *data) {
! 85: Cleanup_struct item={cleanup, data};
! 86: return cleanups.add(&item)!=0;
1.1 paf 87: }
88:
1.6 ! parser 89: ~Pool_storage() {
! 90: size_t i;
1.5 parser 91:
1.6 ! parser 92: // allocations
! 93: for(i=0; i<allocations.used_elements; i++)
! 94: free((void *)allocations.items[i*allocations.item_size]);
! 95:
! 96: // Cleanup_structs
! 97: for(i=0; i<cleanups.used_elements; i++) {
! 98: Cleanup_struct *item=(Cleanup_struct *)cleanups.items[i*cleanups.item_size];
! 99: item->cleanup(item->data);
! 100: }
1.5 parser 101: }
102:
1.6 ! parser 103: private:
1.1 paf 104:
1.6 ! parser 105: List allocations; // void *
! 106: List cleanups; // Cleanup_struct
1.1 paf 107:
108: };
109:
110:
111: #endif