Moves ker/ to ker-project.

This commit is contained in:
Felix Queissner 2015-11-20 12:28:29 +01:00
parent 3e55654df8
commit 3c647cf405
13 changed files with 5 additions and 1157 deletions

View file

@ -1,64 +0,0 @@
#pragma once
#include <stddef.h>
#include "fixedstring.hpp"
class BinaryReader
{
public:
const char * const start;
const size_t length;
private:
size_t current;
size_t remaining;
public:
BinaryReader(const void *src, size_t length) :
start(reinterpret_cast<const char *>(src)),
length(length),
current(0),
remaining(length)
{
}
void jumpTo(size_t offset)
{
if(offset > this->length) {
return;
}
this->current = offset;
this->remaining = this->length - offset;
}
size_t position() const {
return this->current;
}
template<typename T>
T read()
{
if(this->remaining < sizeof(T)) {
return T();
}
const T *ptr = reinterpret_cast<const T*>(this->start + this->current);
this->current += sizeof(T);
this->remaining -= sizeof(T);
return *ptr;
}
};
template<>
inline FixedString BinaryReader::read<FixedString>()
{
FixedString str;
str.len = this->read<uint32_t>();
str.front = this->start + this->current;
this->current += str.len;
this->remaining -= str.len;
return str;
}

View file

@ -1,67 +0,0 @@
#pragma once
#include <ker/vector.hpp>
#include <inttypes.h>
#include "fixedstring.hpp"
class BinaryWriter
{
private:
ker::Vector<uint8_t> mData;
uint32_t mPointer;
public:
BinaryWriter() : mData(), mPointer(0)
{
this->mData.reserve(1024);
}
ker::Vector<uint8_t> &data() { return this->mData; }
const ker::Vector<uint8_t> &data() const { return this->mData; }
size_t size() const {
return this->mData.length();
}
uint32_t tell() const {
return this->mPointer;
}
void rewind() {
this->mPointer = 0;
}
void fastForwad() {
this->mPointer = this->mData.length();
}
void seek(uint32_t position) {
this->mPointer = position;
}
template<typename T>
uint32_t write(const T &bits)
{
uint32_t loc = this->mPointer;
if((this->mPointer + sizeof(T)) > this->mData.length())
{
this->mData.resize(this->mPointer + sizeof(T));
}
this->mPointer += sizeof(T);
uint8_t *data = &(this->mData[loc]);
new (data) T (bits);
return loc;
}
};
template<>
inline uint32_t BinaryWriter::write<FixedString>(const FixedString &bits)
{
uint32_t loc = this->write<uint32_t>(bits.len);
for(uint32_t k = 0; k < bits.len; k++) {
this->write<uint8_t>(bits.front[k]);
}
return loc;
}

View file

@ -1,6 +0,0 @@
#pragma once
/**
* @brief Enables a shared pointer string implementation that does not reallocate memory on copying
*/
#define ENABLE_SHARED_STRING

View file

@ -1,152 +0,0 @@
#pragma once
#include <kernel.h>
#include <initializer_list>
#include "pair.hpp"
#include "vector.hpp"
namespace ker
{
template<typename Key, typename Value>
class Dictionary
{
public:
typedef Pair<Key, Value> Entry;
static Value _default;
public:
Vector<Entry> contents;
public:
Dictionary() :
contents()
{
}
Dictionary(const std::initializer_list<Entry> &items)
{
for(const Entry &entry : items) {
this->contents.append(entry);
}
}
Dictionary(const Dictionary &other) :
contents(other.contents)
{
}
Dictionary(Dictionary &&other) :
contents(other.contents)
{
other.contents = Vector<Entry>();
}
Dictionary & operator = (const Dictionary &other)
{
this->contents = other.contents;
return *this;
}
size_t length() const {
return this->contents.length();
}
void clear() {
this->contents.clear();
}
Value &at(const Key &key)
{
for(auto &&pair : this->contents)
{
if(pair.first == key) {
return pair.second;
}
}
return this->add(key, Value());
}
const Value &at(const Key &key) const
{
static Value _default;
for(auto &&pair : this->contents)
{
if(pair.first == key) {
return pair.second;
}
}
die("Key not found in dictionary.");
return _default;
}
Value get(const Key &key) const
{
if(this->contains(key)) {
return this->at(key);
} else {
return Value();
}
}
bool contains(const Key &key) const
{
for(const auto &pair : this->contents)
{
if(pair.first == key) {
return true;
}
}
return false;
}
Value &add(const Key &key, const Value &value)
{
if(this->contains(key)) {
for(auto &&pair : this->contents)
{
if(pair.first == key) {
pair.second = value;
return pair.second;
}
}
return _default;
} else {
return this->contents.append(Entry(key, value)).second;
}
}
Value& operator [](const Key &key)
{
return this->at(key);
}
const Value& operator [](const Key &key) const
{
return this->at(key);
}
Entry * begin()
{
return this->contents.begin();
}
Entry * end()
{
return this->contents.end();
}
const Entry * begin() const
{
return this->contents.begin();
}
const Entry * end() const
{
return this->contents.end();
}
};
template<typename Key, typename Value>
Value Dictionary<Key, Value>::_default = Value();
}

View file

@ -1,50 +0,0 @@
#pragma once
#include <inttypes.h>
#define FIXED_STRING_AVAILABLE
#include <ker/string.hpp>
struct FixedString
{
uint32_t len;
const char *front;
FixedString() :
len(0),
front(nullptr)
{
}
FixedString(const char *first, uint32_t length) :
len(length),
front(first)
{
}
#if defined(_STRING_H)
FixedString(const char *str) :
len(strlen(str)),
front(str)
{
}
#endif
#if defined(KER_STRING_AVAILABLE)
FixedString(const ker::String &text) :
FixedString(text.str(), text.length()) {
}
explicit operator ker::String() {
return ker::String(reinterpret_cast<const uint8_t*>(front), len);
}
#endif
#if defined(_GLIBCXX_STRING)
FixedString(const std::string &text) :
FixedString(text.c_str(), text.size()) {
}
explicit operator std::string() {
return std::string(front, len);
}
#endif
};

View file

@ -1,20 +0,0 @@
#pragma once
#include <inttypes.h>
#if defined(CIRCUIT_OS)
inline void* operator new(size_t, void* __p)
{
return __p;
}
inline void* operator new[](size_t, void* __p)
{
return __p;
}
inline void operator delete (void*, void*) { }
inline void operator delete[](void*, void*) { }
#endif

View file

@ -1,54 +0,0 @@
#pragma once
namespace ker
{
template<typename First, typename Second>
struct Pair
{
First first;
Second second;
Pair() : first(), second() { }
Pair(const First &first, const Second &second) :
first(first),
second(second)
{
}
Pair(const Pair &other) :
first(other.first),
second(other.second)
{
}
Pair(Pair &&other) :
first(other.first),
second(other.second)
{
other.first = First();
other.second = Second();
}
Pair & operator = (const Pair &other)
{
this->first = other.first;
this->second = other.second;
return *this;
}
};
template<typename T1, typename T2>
static inline bool operator == (const Pair<T1,T2> &lhs, const Pair<T1,T2> &rhs)
{
return (lhs.first == rhs.first) && (lhs.second == rhs.second);
}
template<typename T1, typename T2>
static inline bool operator != (const Pair<T1,T2> &lhs, const Pair<T1,T2> &rhs)
{
return (lhs.first != rhs.first) || (lhs.second != rhs.second);
}
}

View file

@ -1,31 +0,0 @@
#pragma once
#include <stddef.h>
#include <inttypes.h>
class ReferenceCounted
{
public:
static int32_t counter;
private:
size_t mReferenceCount;
protected:
ReferenceCounted() :
mReferenceCount(1)
{
counter++;
}
virtual ~ReferenceCounted() { counter--; }
public:
void aquire() {
this->mReferenceCount += 1;
}
void release() {
this->mReferenceCount -= 1;
if(this->mReferenceCount == 0) {
delete this;
}
}
};

View file

@ -1,310 +0,0 @@
#pragma once
#include <inttypes.h>
#if defined(CIRCUIT_OS)
#include <kstdlib.h>
#else
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#endif
#include "config.hpp"
#define KER_STRING_AVAILABLE
namespace ker
{
class String
{
private:
#if defined(ENABLE_SHARED_STRING)
uint32_t *mReferences;
#endif
uint8_t *mText;
size_t mLength;
#if !defined(ENABLE_SHARED_STRING)
void copyFrom(const uint8_t *bytes, size_t length)
{
if(this->mText != nullptr) {
free(this->mText);
}
this->mText = (uint8_t*)malloc(length + 1);
memcpy(this->mText, bytes, length);
this->mLength = length;
this->mText[this->mLength] = 0; // last byte is always 0
}
#endif
public:
#if defined(ENABLE_SHARED_STRING)
String() :
mReferences(nullptr),
mText(nullptr),
mLength(0)
{
}
// Here just plain copy the string resources and increase the reference counter
String(const String &other) :
mReferences(other.mReferences),
mText(other.mText),
mLength(other.mLength)
{
// Increase reference count
if(this->mReferences != nullptr) {
*this->mReferences += 1;
}
}
// Here move the string resources and don't modify reference counter
String(String &&other) :
mReferences(other.mReferences),
mText(other.mText),
mLength(other.mLength)
{
other.mReferences = nullptr;
other.mText = nullptr;
other.mLength = 0;
}
String(const uint8_t *bytes, size_t length)
{
// Allocate memory for n bytes + nulltermination + length
this->mReferences = static_cast<uint32_t*>(malloc(sizeof(*this->mReferences) + sizeof(uint8_t) * (length + 1)));
this->mText = reinterpret_cast<uint8_t *>(&this->mReferences[1]);
this->mLength = length;
// We have a single reference
(*this->mReferences) = 1;
// Initialize string
memcpy(this->mText, bytes, length);
this->mText[length] = 0;
}
~String()
{
if(this->mReferences != nullptr) {
(*this->mReferences) -= 1;
if((*this->mReferences) == 0) {
// Last reference was released, now destroy the memory.
free(this->mReferences);
}
}
this->mReferences = nullptr;
this->mText = nullptr;
this->mLength = 0;
}
String & operator = (const String &other)
{
if(this->mReferences == other.mReferences) {
// We have copied the string in circles.
// Everything is just fine
return *this;
}
if(this->mReferences != nullptr) {
*this->mReferences -= 1;
if(this->mReferences == 0) {
free(this->mReferences);
}
}
this->mReferences = other.mReferences;
this->mText = other.mText;
this->mLength = other.mLength;
if(this->mReferences != nullptr) {
*this->mReferences += 1;
}
return *this;
}
#else
String() :
mText(nullptr),
mLength(0)
{
}
String(const String &other) :
String(other.mText, other.mLength)
{
}
String(String &&other) :
mText(other.mText),
mLength(other.mLength)
{
other.mText = nullptr;
other.mLength = 0;
}
String(const uint8_t *bytes, size_t length) :
mText(nullptr),
mLength(length)
{
this->copyFrom(bytes, length);
}
~String()
{
if(this->mText != nullptr) {
free(this->mText);
}
}
String & operator = (const String &other)
{
this->copyFrom(other.mText, other.mLength);
return *this;
}
#endif
String(const char *text) :
String(text, strlen(text))
{
}
String(const char *bytes, size_t length) :
String(reinterpret_cast<const uint8_t *>(bytes), length)
{
}
uint8_t at(size_t index) const
{
return this->mText[index];
}
size_t length() const
{
return this->mLength;
}
bool equals(const String &other) const
{
#if defined(ENABLE_SHARED_STRING)
if(this->mText == other.mText) {
// This is a quite useful equality test.
return true;
}
#endif
if(this->mLength != other.mLength) {
return false;
}
return memcmp(this->mText, other.mText, this->mLength) == 0;
}
bool equals(const char *other) const
{
return strcmp(this->str(), other) == 0;
}
String append(const String &other) const
{
uint8_t *data = (uint8_t*)malloc(this->mLength + other.mLength);
memcpy(&data[0], this->mText, this->mLength);
memcpy(&data[this->mLength], other.mText, other.mLength);
String cat(data, this->mLength + other.mLength);
free(data);
return cat;
}
const uint8_t *text() const
{
static const uint8_t empty[] = { 0 };
if(this->mText != nullptr) {
return this->mText;
} else {
return empty;
}
}
const char *str() const
{
return (char*)this->text();
}
operator const uint8_t *() const
{
return this->text();
}
operator const char *() const
{
return this->str();
}
uint8_t & operator [](size_t index)
{
return this->mText[index];
}
const uint8_t & operator [](size_t index) const
{
return this->mText[index];
}
bool operator ==(const String &other) const
{
return this->equals(other);
}
bool operator ==(const char *other) const
{
return this->equals(other);
}
bool operator !=(const String &other) const
{
return !this->equals(other);
}
bool operator !=(const char *other) const
{
return !this->equals(other);
}
String operator +(const String &other) const
{
return this->append(other);
}
public:
static String concat(const String &lhs, const String &rhs)
{
return lhs.append(rhs);
}
/*
static String fromNumber(int32_t number, int radix = 10)
{
static char buffer[64];
itoa(number, buffer, radix);
return String(buffer);
}
*/
template<typename T>
static String from(const T &);
};
static inline String operator + (const char *lhs, const String &rhs)
{
return String::concat(lhs, rhs);
}
static inline String operator + (const String &lhs, const char *rhs)
{
return String::concat(lhs, rhs);
}
};

View file

@ -1,5 +0,0 @@
#pragma once
#define DO_PRAGMA(x) _Pragma (#x)
#define TODO(...) DO_PRAGMA(message ("TODO - " #__VA_ARGS__))
#define FIXME(...) DO_PRAGMA(message ("FIX - " #__VA_ARGS__))

View file

@ -1,252 +0,0 @@
#pragma once
#include <inttypes.h>
#include <stddef.h>
#include <initializer_list>
#if defined(CIRCUIT_OS)
#include "kstdlib.h"
#include "new.hpp"
#else
#include <stdlib.h>
#include <string.h>
#include <new>
#endif
namespace ker
{
template<typename T>
class Vector
{
public:
static const size_t initialCap = 32;
private:
T *mData;
size_t mLength;
size_t mReserved;
public:
Vector() :
mData(nullptr),
mLength(0),
mReserved(0)
{
this->reserve(Vector<T>::initialCap);
}
Vector(const Vector &other) :
mData(nullptr),
mLength(0),
mReserved(0)
{
this->mLength = other.mLength;
if(this->mLength > 0) {
this->reserve(this->mLength);
for(size_t i = 0; i < this->mLength; i++) {
new (&this->mData[i]) T(other.mData[i]);
}
}
}
Vector(Vector &&other) :
mData(other.mData),
mLength(other.mLength),
mReserved(other.mReserved)
{
other.mData = nullptr;
other.mLength = 0;
other.mReserved = 0;
}
Vector(const std::initializer_list<T> &init) :
Vector()
{
this->reserve(init.size());
for(auto & value : init) {
this->append(value);
}
}
Vector & operator = (const Vector &other)
{
this->resize(other.mLength);
for(size_t i = 0; i < this->mLength; i++)
{
this->mData[i] = other.mData[i];
}
return *this;
}
explicit Vector(size_t initialReserve) :
Vector()
{
this->reserve(initialReserve);
}
~Vector()
{
if(this->mData != nullptr) {
for(size_t i = 0; i < this->mLength; i++) {
this->mData[i].~T();
}
free(this->mData);
}
}
size_t length() const
{
return this->mLength;
}
T &at(size_t index)
{
return this->mData[index];
}
const T &at(size_t index) const
{
return this->mData[index];
}
T& append(const T &value)
{
this->reserve(this->mLength + 1);
new (&this->mData[this->mLength]) T(value);
this->mLength += 1;
return this->mData[this->mLength - 1];
}
/**
* @brief Removes the last element.
*/
void pop()
{
if(this->length() > 0) {
this->resize(this->length() - 1);
}
}
void clear()
{
this->resize(0);
}
T& insert(size_t index, const T& value)
{
this->resize(this->mLength + 1);
for(int32_t i = this->mLength - 2; i >= static_cast<int32_t>(index); i--) {
// Move every item backwards
this->mData[i+1] = this->mData[i];
}
// then override
this->mData[index] = value;
return this->mData[index];
}
void remove(size_t index)
{
for(uint32_t i = index; i < this->mLength; i++) {
// Move every item backwards
this->mData[i] = this->mData[i+1];
}
// then override
this->mData[this->mLength - 1].~T();
this->mLength -= 1;
}
void resize(size_t size)
{
size_t current = this->mLength;
this->reserve(size);
if(current > size) {
// "Downgrade"
for(int32_t i = static_cast<int32_t>(this->mLength) - 1; i >= static_cast<int32_t>(size); i--) {
this->mData[i].~T();
}
} else {
// "Upgrade"
for(size_t i = this->mLength; i < size; i++) {
new (&this->mData[i]) T ();
}
}
this->mLength = size;
}
void reserve(size_t space)
{
if(this->mReserved >= space) {
return;
}
if((this->mReserved + initialCap) > space) {
space = this->mReserved + initialCap;
}
const size_t newSize = sizeof(T) * space;
T *newData = (T*)malloc(newSize);
if(this->mData != nullptr) {
// Ermahgerd, what a leak. Not obvious but it leaks.
// memcpy(newData, this->mData, newSize);
// Fix: copy construct all objects into the new memory, then destroy the original data.
for(size_t i = 0; i < this->mLength; i++) {
new (&newData[i]) T (this->mData[i]);
this->mData[i].~T();
}
free(this->mData);
}
this->mData = newData;
this->mReserved = space;
}
T& operator [](size_t idx)
{
return this->at(idx);
}
const T& operator [](size_t idx) const
{
return this->at(idx);
}
const T &front() const {
return this->mData[0];
}
const T &back() const {
return this->mData[this->mLength - 1];
}
T &front() {
return this->mData[0];
}
T &back() {
return this->mData[this->mLength - 1];
}
T* begin()
{
return &this->mData[0];
}
T* end()
{
return &this->mData[this->mLength];
}
const T* begin() const
{
return &this->mData[0];
}
const T* end() const
{
return &this->mData[this->mLength];
}
const T *data() const
{
return &this->mData[0];
}
};
}

View file

@ -1,138 +0,0 @@
#include <inttypes.h>
#include "../include/ker/string.hpp"
#define SPEC(type) template<> String String::from<type>(const type &val)
static void reverse(char *str, int length)
{
int start = 0;
int end = length -1;
while (start < end)
{
char tmp = *(str+start);
*(str+start) = *(str+end);
*(str+end) = tmp;
start++;
end--;
}
}
static char *_itoa(int num, char *str, int base, bool useUnsigned)
{
int i = 0;
int isNegative = 0;
if(str == nullptr) {
static char tmp[64];
str = tmp;
}
/* Handle 0 explicitely, otherwise empty string is printed for 0 */
if (num == 0)
{
str[i++] = '0';
str[i] = '\0';
return str;
}
// In standard itoa(), negative numbers are handled only with
// base 10. Otherwise numbers are considered unsigned.
if ((useUnsigned == false) && (num < 0) && (base == 10))
{
isNegative = 1;
num = -num;
}
// Process individual digits
while (num != 0)
{
int rem = num % base;
str[i++] = (rem > 9)? (rem-10) + 'A' : rem + '0';
num = num/base;
}
// If number is negative, append '-'
if (isNegative)
{
str[i++] = '-';
}
str[i] = '\0'; // Append string terminator
// Reverse the string
reverse(str, i);
return str;
}
namespace ker
{
SPEC(bool)
{
return val ? "true" : "false";
}
SPEC(String)
{
return val;
}
SPEC(int8_t) {
static char buffer[16];
_itoa(val, buffer, 10, false);
return buffer;
}
SPEC(int16_t) {
static char buffer[16];
_itoa(val, buffer, 10, false);
return buffer;
}
SPEC(int32_t) {
static char buffer[16];
_itoa(val, buffer, 10, false);
return buffer;
}
SPEC(uint8_t) {
static char buffer[16];
_itoa(val, buffer, 10, true);
return buffer;
}
SPEC(uint16_t) {
static char buffer[16];
_itoa(val, buffer, 10, true);
return buffer;
}
SPEC(uint32_t) {
static char buffer[16];
_itoa(val, buffer, 10, true);
return buffer;
}
SPEC(float) {
(void)val;
return "f32";
}
#if defined(CONDUCTANCE_64BIT)
SPEC(int64_t)
{
return "i64";
}
SPEC(uint64_t)
{
return "u64";
}
SPEC(double)
{
return "f64";
}
#endif
}

View file

@ -2,6 +2,8 @@ TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
CONFIG += ker_shared_string
CONFIG += ker_standalone
SOURCES += \
src/console.c \
@ -31,10 +33,6 @@ HEADERS += \
include/varargs.h \
include/vmm.h \
include/timer.h \
include/ker/string.hpp \
include/ker/pair.hpp \
include/ker/vector.hpp \
include/ker/dictionary.hpp \
include/kstring.h \
include/ker/new.hpp \
include/dynamic.h \
@ -42,9 +40,7 @@ HEADERS += \
include/serial.h \
include/malloc.h \
csl/cpustatetype.hpp \
csl/io.hpp \
include/ker/config.hpp \
include/ker/todo.hpp
csl/io.hpp
DISTFILES += \
asm/intr_common_handler.S \
@ -67,8 +63,9 @@ DEPENDPATH += include
INCLUDEPATH += $$quote("/home/felix/projects/Electronics/Electronics/Conductance")
DEPENDPATH += $$quote("/home/felix/projects/Electronics/Electronics/Conductance")
QMAKE_CFLAGS = -m32 -Dnullptr=0 -std=c11 -Wall -fno-stack-protector -ffreestanding
QMAKE_LINK = ld
QMAKE_LFLAGS = -g -melf_i386 -Tkernel.ld
include("/home/felix/projects/ker/ker.pri")