#ifndef __stack_h__ #define __stack_h__ #include #include #include #include using namespace std; #include "debug.h" #define ALLOC_BLOB (2*1024) #define LOCAL_COPY_PLACES 3 #define LOCAL_COPY_SIZE 128 // class stack { private: struct local_copy { unsigned int length; int type; int blob; }; public: stack() { _base = (char*)malloc(ALLOC_BLOB); _total_size = ALLOC_BLOB; _current = _base; _count = 0; } virtual ~stack() { free(_base); } void push_back(void* obj, unsigned int size, int type = 0, bool dont_copy = false) { if (_current + size > _base + _total_size) { //TODO gerer les pbs de memoire _total_size += ALLOC_BLOB; _base = (char*)realloc(_base, _total_size); } if (!dont_copy) memcpy(_current, obj, size); _vlen.push_back(size); _vpointer.push_back(_current); _vtype.push_back(type); _count++; _current += size; } void pop_back() { if (_count > 0) { _current = _vpointer[_count - 1]; _vlen.pop_back(); _vpointer.pop_back(); _vtype.pop_back(); _count--; } } unsigned int size() { return _count; } // stack access (index is counted from back) void* get_obj(unsigned int index) { if (index<_count) return _vpointer[_count-index-1]; else return NULL; } void* operator[](unsigned int index) { return get_obj(index); } void* back() { if (_count>0) return _vpointer[_count-1]; else return NULL; } unsigned int get_len(unsigned int index) { if (index<_count) return _vlen[_count-index-1]; else return 0; } int get_type(unsigned int index) { if (index<_count) return _vtype[_count-index-1]; else return 0; } // sequential access (index is counted from front) void* seq_obj(unsigned int index) { if (index<_count) return _vpointer[index]; else return NULL; } unsigned int seq_len(unsigned int index) { if (index<_count) return _vlen[index]; else return 0; } int seq_type(unsigned int index) { if (index<_count) return _vtype[index]; else return 0; } // local objects copy void copy_obj_to_local(unsigned int index, unsigned int to_place) { assert(to_place < LOCAL_COPY_PLACES); struct local_copy* local = (struct local_copy*)_places[to_place]; local->length = get_len(index); local->type= get_type(index); memcpy(&local->blob, get_obj(index), local->length); } void push_obj_from_local(unsigned int from_place) { assert(from_place < LOCAL_COPY_PLACES); struct local_copy* local = (struct local_copy*)_places[from_place]; push_back(&local->blob, local->length, local->type); } void dump(void) { dump8((unsigned char*)_base, 0, (unsigned long)(_current - _base)); } private: char* _base; char* _current; vector _vlen;// size of each entry in bytes vector _vpointer;//pointer on each entry vector _vtype;//type of each entry unsigned int _count;// =_vlen.size()=_vpointer.size()=_vtype.size() unsigned int _total_size;//total allocated size in bytes char _places[LOCAL_COPY_PLACES][LOCAL_COPY_SIZE]; }; // class heap { private: struct local_var { unsigned int length; int type; int blob; }; public: heap() { } virtual ~heap() { for(map::iterator i=_map.begin(); i!=_map.end(); i++) free(i->second); } void add(const string name, void* obj, unsigned int size, int type = 0) { struct local_var* blob = _map[name]; if (blob == NULL) { //TODO gerer les pbs de memoire blob = (struct local_var*)malloc(size + sizeof(local_var)); _map[name] = blob; } else if (size != blob->length) { //TODO gerer les pbs de memoire blob = (struct local_var*)realloc(blob, size + sizeof(local_var)); _map[name] = blob; } blob->length = size; blob->type= type; memcpy(&blob->blob, obj, size); } bool get(const string name, void*& obj, unsigned int& size, int& type) { map::iterator i = _map.find(name); if (i != _map.end()) { if (i->second != NULL) { obj = &i->second->blob; size = i->second->length; type = i->second->type; } return true; } else return false; } bool exist(const string name) { return (_map.find(name) != _map.end()); } bool get_by_index(int num, string& name, void*& obj, unsigned int& size, int& type) { if (num>=0 && num<(int)_map.size()) { struct local_var* blob; map::iterator i=_map.begin(); //TODO moche moche moche for(int j=0;jsecond; assert(blob != NULL); name = i->first; obj = &blob->blob; size = blob->length; type = blob->type; return true; } else return false; } bool erase(const string& name) { map::iterator i = _map.find(name); if (i != _map.end()) { free(i->second); _map.erase(i->first); return true; } return false; } unsigned int size() { return _map.size(); } private: map _map; }; #endif // __stack_h__