Skip to content

Commit

Permalink
Import all this stuff into a single repo called Serenity.
Browse files Browse the repository at this point in the history
  • Loading branch information
awesomekling committed Oct 10, 2018
0 parents commit 5a30055
Show file tree
Hide file tree
Showing 67 changed files with 8,836 additions and 0 deletions.
1 change: 1 addition & 0 deletions AK/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
akit-test
15 changes: 15 additions & 0 deletions AK/Assertions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <assert.h>

#define ASSERT(x) assert(x)
#define ASSERT_NOT_REACHED() assert(false)

namespace AK {

inline void notImplemented() { assert(false); }

}

using AK::notImplemented;

71 changes: 71 additions & 0 deletions AK/Bitmap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#pragma once

#include "StdLib.h"
#include "Types.h"
#include "kmalloc.h"

namespace AK {

class Bitmap {
public:
// NOTE: A wrapping Bitmap won't try to free the wrapped data.
static Bitmap wrap(byte* data, unsigned size)
{
return Bitmap(data, size);
}

static Bitmap create(unsigned size)
{
return Bitmap(size);
}

~Bitmap()
{
if (m_owned)
kfree(m_data);
m_data = nullptr;
}

unsigned size() const { return m_size; }
bool get(unsigned index) const
{
ASSERT(index < m_size);
return 0 != (m_data[index / 8] & (1u << (index % 8)));
}
void set(unsigned index, bool value) const
{
ASSERT(index < m_size);
if (value)
m_data[index / 8] |= static_cast<byte>((1u << (index % 8)));
else
m_data[index / 8] &= static_cast<byte>(~(1u << (index % 8)));
}

byte* data() { return m_data; }
const byte* data() const { return m_data; }

private:
explicit Bitmap(unsigned size)
: m_size(size)
, m_owned(true)
{
ASSERT(m_size != 0);
m_data = reinterpret_cast<byte*>(kmalloc(ceilDiv(size, 8u)));
}

Bitmap(byte* data, unsigned size)
: m_data(data)
, m_size(size)
, m_owned(false)
{
}

byte* m_data { nullptr };
unsigned m_size { 0 };
bool m_owned { false };
};

}

using AK::Bitmap;

120 changes: 120 additions & 0 deletions AK/Buffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#pragma once

#include "Assertions.h"
#include "Retainable.h"
#include "RetainPtr.h"
#include <cstdlib>
#include <cstring>
#include "kmalloc.h"

namespace AK {

template<typename T>
class Buffer : public Retainable<Buffer<T>> {
public:
static RetainPtr<Buffer> createUninitialized(size_t count);
static RetainPtr<Buffer> copy(const T*, size_t count);
static RetainPtr<Buffer> wrap(T*, size_t count);
static RetainPtr<Buffer> adopt(T*, size_t count);

~Buffer() { clear(); }

void clear()
{
if (!m_elements)
return;
kfree(m_elements);
m_elements = nullptr;
}

T& operator[](size_t i) { ASSERT(i < m_size); return m_elements[i]; }
const T& operator[](size_t i) const { ASSERT(i < m_size); return m_elements[i]; }
bool isEmpty() const { return !m_size; }
size_t size() const { return m_size; }

T* pointer() { return m_elements; }
const T* pointer() const { return m_elements; }

T* offsetPointer(size_t offset) { return m_elements + offset; }
const T* offsetPointer(size_t offset) const { return m_elements + offset; }

const void* endPointer() const { return m_elements + m_size; }

// NOTE: trim() does not reallocate.
void trim(size_t size)
{
ASSERT(size <= m_size);
m_size = size;
}

private:
enum ConstructionMode { Uninitialized, Copy, Wrap, Adopt };
explicit Buffer(size_t); // For ConstructionMode=Uninitialized
Buffer(const T*, size_t, ConstructionMode); // For ConstructionMode=Copy
Buffer(T*, size_t, ConstructionMode); // For ConstructionMode=Wrap/Adopt
Buffer() { }

T* m_elements { nullptr };
size_t m_size { 0 };
bool m_owned { false };
};

template<typename T>
inline Buffer<T>::Buffer(size_t size)
: m_size(size)
{
m_elements = static_cast<T*>(kmalloc(size * sizeof(T)));
m_owned = true;
}

template<typename T>
inline Buffer<T>::Buffer(const T* elements, size_t size, ConstructionMode mode)
: m_size(size)
{
ASSERT(mode == Copy);
m_elements = static_cast<T*>(kmalloc(size * sizeof(T)));
memcpy(m_elements, elements, size * sizeof(T));
m_owned = true;
}

template<typename T>
inline Buffer<T>::Buffer(T* elements, size_t size, ConstructionMode mode)
: m_elements(elements)
, m_size(size)
{
if (mode == Adopt) {
m_owned = true;
} else if (mode == Wrap) {
m_owned = false;
}

}

template<typename T>
inline RetainPtr<Buffer<T>> Buffer<T>::createUninitialized(size_t size)
{
return ::adopt(*new Buffer<T>(size));
}

template<typename T>
inline RetainPtr<Buffer<T>> Buffer<T>::copy(const T* elements, size_t size)
{
return ::adopt(*new Buffer<T>(elements, size, Copy));
}

template<typename T>
inline RetainPtr<Buffer<T>> Buffer<T>::wrap(T* elements, size_t size)
{
return ::adopt(*new Buffer<T>(elements, size, Wrap));
}

template<typename T>
inline RetainPtr<Buffer<T>> Buffer<T>::adopt(T* elements, size_t size)
{
return ::adopt(*new Buffer<T>(elements, size, Adopt));
}

}

using AK::Buffer;

85 changes: 85 additions & 0 deletions AK/ByteBuffer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#pragma once

#include "Buffer.h"
#include "Types.h"
#include <cstdlib>
#include <cstring>
#include <cstdio>

namespace AK {

class ByteBuffer {
public:
ByteBuffer() { }
ByteBuffer(std::nullptr_t) { }
ByteBuffer(const ByteBuffer& other)
: m_impl(other.m_impl.copyRef())
{
}
ByteBuffer(ByteBuffer&& other)
: m_impl(std::move(other.m_impl))
{
}
ByteBuffer& operator=(ByteBuffer&& other)
{
if (this != &other)
m_impl = std::move(other.m_impl);
return *this;
}

static ByteBuffer createUninitialized(size_t size) { return ByteBuffer(Buffer<byte>::createUninitialized(size)); }
static ByteBuffer copy(const byte* data, size_t size) { return ByteBuffer(Buffer<byte>::copy(data, size)); }
static ByteBuffer wrap(byte* data, size_t size) { return ByteBuffer(Buffer<byte>::wrap(data, size)); }
static ByteBuffer adopt(byte* data, size_t size) { return ByteBuffer(Buffer<byte>::adopt(data, size)); }

~ByteBuffer() { clear(); }
void clear() { m_impl = nullptr; }

operator bool() const { return !isNull(); }
bool operator!() const { return isNull(); }
bool isNull() const { return m_impl == nullptr; }

byte& operator[](size_t i) { ASSERT(m_impl); return (*m_impl)[i]; }
byte operator[](size_t i) const { ASSERT(m_impl); return (*m_impl)[i]; }
bool isEmpty() const { return !m_impl || m_impl->isEmpty(); }
size_t size() const { return m_impl ? m_impl->size() : 0; }

byte* pointer() { return m_impl ? m_impl->pointer() : nullptr; }
const byte* pointer() const { return m_impl ? m_impl->pointer() : nullptr; }

byte* offsetPointer(size_t offset) { return m_impl ? m_impl->offsetPointer(offset) : nullptr; }
const byte* offsetPointer(size_t offset) const { return m_impl ? m_impl->offsetPointer(offset) : nullptr; }

const void* endPointer() const { return m_impl ? m_impl->endPointer() : nullptr; }

// NOTE: trim() does not reallocate.
void trim(size_t size)
{
if (m_impl)
m_impl->trim(size);
}

ByteBuffer slice(size_t offset, size_t size) const
{
if (isNull())
return { };
if (offset >= this->size())
return { };
if (offset + size >= this->size())
size = this->size() - offset;
return copy(offsetPointer(offset), size);
}

private:
explicit ByteBuffer(RetainPtr<Buffer<byte>>&& impl)
: m_impl(std::move(impl))
{
}

RetainPtr<Buffer<byte>> m_impl;
};

}

using AK::ByteBuffer;

95 changes: 95 additions & 0 deletions AK/HashMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#pragma once

#include "HashTable.h"
#include <utility>

namespace AK {

template<typename K, typename V>
class HashMap {
private:
struct Entry {
K key;
V value;

bool operator==(const Entry& other)
{
return key == other.key;
}
};

struct EntryTraits {
static unsigned hash(const Entry& entry) { return Traits<K>::hash(entry.key); }
static void dump(const Entry& entry)
{
printf("key=");
Traits<K>::dump(entry.key);
printf(" value=");
Traits<V>::dump(entry.value);
}
};

public:
HashMap() { }

HashMap(HashMap&& other)
: m_table(std::move(other.m_table))
{
}

HashMap& operator=(HashMap&& other)
{
if (this != &other) {
m_table = std::move(other.m_table);
}
return *this;
}

bool isEmpty() const { return m_table.isEmpty(); }
unsigned size() const { return m_table.size(); }
unsigned capacity() const { return m_table.capacity(); }

void set(const K&, V&&);

typedef HashTable<Entry, EntryTraits> HashTableType;
typedef typename HashTableType::Iterator IteratorType;
typedef typename HashTableType::ConstIterator ConstIteratorType;

IteratorType begin() { return m_table.begin(); }
IteratorType end() { return m_table.end(); }
IteratorType find(const K&);

ConstIteratorType begin() const { return m_table.begin(); }
ConstIteratorType end() const { return m_table.end(); }
ConstIteratorType find(const K&) const;

void dump() const { m_table.dump(); }

private:
HashTable<Entry, EntryTraits> m_table;
};

template<typename K, typename V>
void HashMap<K, V>::set(const K& key, V&& value)
{
m_table.set(Entry{key, std::move(value)});
}

template<typename K, typename V>
auto HashMap<K, V>::find(const K& key) -> IteratorType
{
Entry dummy { key, V() };
return m_table.find(dummy);
}

template<typename K, typename V>
auto HashMap<K, V>::find(const K& key) const -> ConstIteratorType
{
Entry dummy { key, V() };
return m_table.find(dummy);
}

}

using AK::HashMap;

Loading

0 comments on commit 5a30055

Please sign in to comment.