mirror of
https://github.com/corda/corda.git
synced 2025-01-23 04:48:09 +00:00
187 lines
3.3 KiB
C++
187 lines
3.3 KiB
C++
/* Copyright (c) 2008-2015, Avian Contributors
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
for any purpose with or without fee is hereby granted, provided
|
|
that the above copyright notice and this permission notice appear
|
|
in all copies.
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
details. */
|
|
|
|
#ifndef VECTOR_H
|
|
#define VECTOR_H
|
|
|
|
#include <avian/target.h>
|
|
|
|
#include <avian/util/math.h>
|
|
#include <avian/util/abort.h>
|
|
#include <avian/util/slice.h>
|
|
#include <avian/util/allocator.h>
|
|
|
|
#undef max
|
|
#undef min
|
|
|
|
namespace vm {
|
|
|
|
class Vector {
|
|
public:
|
|
Vector(avian::util::Aborter* a,
|
|
avian::util::Alloc* allocator,
|
|
size_t minimumCapacity)
|
|
: a(a),
|
|
allocator(allocator),
|
|
data(0, 0),
|
|
position(0),
|
|
minimumCapacity(minimumCapacity)
|
|
{
|
|
}
|
|
|
|
~Vector()
|
|
{
|
|
dispose();
|
|
}
|
|
|
|
void dispose()
|
|
{
|
|
if (data.items and minimumCapacity > 0) {
|
|
allocator->free(data.items, data.count);
|
|
data.items = 0;
|
|
data.count = 0;
|
|
}
|
|
}
|
|
|
|
void ensure(size_t space)
|
|
{
|
|
if (position + space > data.count) {
|
|
assertT(a, minimumCapacity > 0);
|
|
|
|
size_t newCapacity = avian::util::max(
|
|
position + space, avian::util::max(minimumCapacity, data.count * 2));
|
|
if (data.begin()) {
|
|
data.resize(allocator, newCapacity);
|
|
} else {
|
|
data = avian::util::Slice<uint8_t>::alloc(allocator, newCapacity);
|
|
}
|
|
}
|
|
}
|
|
|
|
void get(size_t offset, void* dst, size_t size)
|
|
{
|
|
assertT(a, offset + size <= position);
|
|
memcpy(dst, data.begin() + offset, size);
|
|
}
|
|
|
|
void set(size_t offset, const void* src, size_t size)
|
|
{
|
|
assertT(a, offset + size <= position);
|
|
memcpy(data.begin() + offset, src, size);
|
|
}
|
|
|
|
void pop(void* dst, size_t size)
|
|
{
|
|
get(position - size, dst, size);
|
|
position -= size;
|
|
}
|
|
|
|
void* allocate(size_t size)
|
|
{
|
|
ensure(size);
|
|
void* r = data.begin() + position;
|
|
position += size;
|
|
return r;
|
|
}
|
|
|
|
void* append(const void* p, size_t size)
|
|
{
|
|
void* r = allocate(size);
|
|
memcpy(r, p, size);
|
|
return r;
|
|
}
|
|
|
|
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 appendTargetAddress(target_uintptr_t v)
|
|
{
|
|
append(&v, TargetBytesPerWord);
|
|
}
|
|
|
|
void appendAddress(uintptr_t v)
|
|
{
|
|
append(&v, BytesPerWord);
|
|
}
|
|
|
|
void appendAddress(void* v)
|
|
{
|
|
append(&v, BytesPerWord);
|
|
}
|
|
|
|
void set2(size_t offset, uint16_t v)
|
|
{
|
|
assertT(a, offset <= position - 2);
|
|
memcpy(data.begin() + offset, &v, 2);
|
|
}
|
|
|
|
size_t get(size_t offset)
|
|
{
|
|
uint8_t v;
|
|
get(offset, &v, 1);
|
|
return v;
|
|
}
|
|
|
|
size_t get2(size_t offset)
|
|
{
|
|
uint16_t v;
|
|
get(offset, &v, 2);
|
|
return v;
|
|
}
|
|
|
|
size_t get4(size_t offset)
|
|
{
|
|
uint32_t v;
|
|
get(offset, &v, 4);
|
|
return v;
|
|
}
|
|
|
|
uintptr_t getAddress(size_t offset)
|
|
{
|
|
uintptr_t v;
|
|
get(offset, &v, BytesPerWord);
|
|
return v;
|
|
}
|
|
|
|
size_t length()
|
|
{
|
|
return position;
|
|
}
|
|
|
|
template <class T>
|
|
T* peek(size_t offset)
|
|
{
|
|
assertT(a, offset + sizeof(T) <= position);
|
|
return reinterpret_cast<T*>(data.begin() + offset);
|
|
}
|
|
|
|
avian::util::Aborter* a;
|
|
avian::util::Alloc* allocator;
|
|
avian::util::Slice<uint8_t> data;
|
|
size_t position;
|
|
size_t minimumCapacity;
|
|
};
|
|
|
|
} // namespace vm
|
|
|
|
#endif // VECTOR_H
|