Moves ker/ to ker-project.
This commit is contained in:
parent
3e55654df8
commit
3c647cf405
13 changed files with 5 additions and 1157 deletions
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Enables a shared pointer string implementation that does not reallocate memory on copying
|
|
||||||
*/
|
|
||||||
#define ENABLE_SHARED_STRING
|
|
|
@ -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();
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
};
|
|
|
@ -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
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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__))
|
|
|
@ -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];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
138
ker/string.cpp
138
ker/string.cpp
|
@ -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
|
|
||||||
}
|
|
13
trainOS.pro
13
trainOS.pro
|
@ -2,6 +2,8 @@ TEMPLATE = app
|
||||||
CONFIG += console
|
CONFIG += console
|
||||||
CONFIG -= app_bundle
|
CONFIG -= app_bundle
|
||||||
CONFIG -= qt
|
CONFIG -= qt
|
||||||
|
CONFIG += ker_shared_string
|
||||||
|
CONFIG += ker_standalone
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
src/console.c \
|
src/console.c \
|
||||||
|
@ -31,10 +33,6 @@ HEADERS += \
|
||||||
include/varargs.h \
|
include/varargs.h \
|
||||||
include/vmm.h \
|
include/vmm.h \
|
||||||
include/timer.h \
|
include/timer.h \
|
||||||
include/ker/string.hpp \
|
|
||||||
include/ker/pair.hpp \
|
|
||||||
include/ker/vector.hpp \
|
|
||||||
include/ker/dictionary.hpp \
|
|
||||||
include/kstring.h \
|
include/kstring.h \
|
||||||
include/ker/new.hpp \
|
include/ker/new.hpp \
|
||||||
include/dynamic.h \
|
include/dynamic.h \
|
||||||
|
@ -42,9 +40,7 @@ HEADERS += \
|
||||||
include/serial.h \
|
include/serial.h \
|
||||||
include/malloc.h \
|
include/malloc.h \
|
||||||
csl/cpustatetype.hpp \
|
csl/cpustatetype.hpp \
|
||||||
csl/io.hpp \
|
csl/io.hpp
|
||||||
include/ker/config.hpp \
|
|
||||||
include/ker/todo.hpp
|
|
||||||
|
|
||||||
DISTFILES += \
|
DISTFILES += \
|
||||||
asm/intr_common_handler.S \
|
asm/intr_common_handler.S \
|
||||||
|
@ -67,8 +63,9 @@ DEPENDPATH += include
|
||||||
INCLUDEPATH += $$quote("/home/felix/projects/Electronics/Electronics/Conductance")
|
INCLUDEPATH += $$quote("/home/felix/projects/Electronics/Electronics/Conductance")
|
||||||
DEPENDPATH += $$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_CFLAGS = -m32 -Dnullptr=0 -std=c11 -Wall -fno-stack-protector -ffreestanding
|
||||||
|
|
||||||
QMAKE_LINK = ld
|
QMAKE_LINK = ld
|
||||||
QMAKE_LFLAGS = -g -melf_i386 -Tkernel.ld
|
QMAKE_LFLAGS = -g -melf_i386 -Tkernel.ld
|
||||||
|
|
||||||
|
include("/home/felix/projects/ker/ker.pri")
|
||||||
|
|
Loading…
Reference in a new issue