corda/src/vector.h

147 lines
2.8 KiB
C
Raw Normal View History

2007-12-09 20:03:21 +00:00
#ifndef VECTOR_H
#define VECTOR_H
#include "system.h"
namespace vm {
class Vector {
public:
Vector(System* s, Allocator* allocator, void* context,
unsigned minimumCapacity):
2007-12-09 20:03:21 +00:00
s(s),
allocator(allocator),
context(context),
2007-12-09 20:03:21 +00:00
data(0),
position(0),
capacity(0),
minimumCapacity(minimumCapacity)
{ }
~Vector() {
dispose();
}
void dispose() {
if (data and minimumCapacity >= 0) {
allocator->free(data, capacity, false);
2007-12-09 20:03:21 +00:00
}
}
void wrap(uint8_t* data, unsigned capacity) {
dispose();
this->data = data;
this->position = 0;
this->capacity = capacity;
this->minimumCapacity = -1;
}
2007-12-09 20:03:21 +00:00
void ensure(unsigned space) {
if (position + space > capacity) {
assert(s, minimumCapacity >= 0);
2007-12-09 20:03:21 +00:00
unsigned newCapacity = max
(position + space, max(minimumCapacity, capacity * 2));
uint8_t* newData = static_cast<uint8_t*>
(allocator->allocate(context, newCapacity, false));
2007-12-09 20:03:21 +00:00
if (data) {
memcpy(newData, data, position);
allocator->free(data, capacity, false);
2007-12-09 20:03:21 +00:00
}
data = newData;
2007-12-11 00:48:09 +00:00
capacity = newCapacity;
2007-12-09 20:03:21 +00:00
}
}
void get(unsigned offset, void* dst, unsigned size) {
assert(s, offset + size <= position);
2007-12-09 22:45:43 +00:00
memcpy(dst, data + offset, size);
2007-12-09 20:03:21 +00:00
}
void set(unsigned offset, const void* src, unsigned size) {
assert(s, offset + size <= position);
2007-12-09 22:45:43 +00:00
memcpy(data + offset, src, size);
2007-12-09 20:03:21 +00:00
}
void pop(void* dst, unsigned size) {
get(position - size, dst, size);
position -= size;
}
2007-12-09 22:45:43 +00:00
void* allocate(unsigned size) {
2007-12-09 20:03:21 +00:00
ensure(size);
void* r = data + position;
position += size;
return r;
}
2007-12-09 22:45:43 +00:00
void* append(const void* p, unsigned size) {
void* r = allocate(size);
memcpy(r, p, size);
return r;
}
2007-12-09 20:03:21 +00:00
void append(uint8_t v) {
append(&v, 1);
}
void append2(uint16_t v) {
append(&v, 2);
}
void append4(uint32_t v) {
append(&v, 4);
}
void appendAddress(uintptr_t v) {
append(&v, BytesPerWord);
}
2007-12-11 00:48:09 +00:00
void appendAddress(void* v) {
append(&v, BytesPerWord);
}
unsigned get(unsigned offset) {
uint8_t v; get(offset, &v, 1);
return v;
}
unsigned get2(unsigned offset) {
uint16_t v; get(offset, &v, 2);
return v;
}
unsigned get4(unsigned offset) {
uint32_t v; get(offset, &v, 4);
return v;
}
uintptr_t getAddress(unsigned offset) {
uintptr_t v; get(offset, &v, BytesPerWord);
return v;
}
2007-12-09 22:45:43 +00:00
unsigned length() {
return position;
2007-12-09 20:03:21 +00:00
}
2007-12-09 22:45:43 +00:00
template <class T>
T* peek(unsigned offset) {
assert(s, offset + sizeof(T) <= position);
return reinterpret_cast<T*>(data + offset);
}
2007-12-09 20:03:21 +00:00
System* s;
Allocator* allocator;
void* context;
2007-12-09 20:03:21 +00:00
uint8_t* data;
unsigned position;
unsigned capacity;
int minimumCapacity;
2007-12-09 20:03:21 +00:00
};
} // namespace vm
#endif//VECTOR_H