summaryrefslogtreecommitdiff
path: root/Source/Library/Common
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-20 19:23:33 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-20 19:23:33 +0200
commit768ada13917aeda373e6ff5fee21faf90c963746 (patch)
tree9e26d7d65e1693d1a7f9fd93c9fd33b41d175464 /Source/Library/Common
parent6ec4b3d31080f90393e72989d559cfb76eff6f9d (diff)
parent9836acd720988af30250c2c1ec18d618664dea4e (diff)
downloadMelon-768ada13917aeda373e6ff5fee21faf90c963746.tar.gz
Melon-768ada13917aeda373e6ff5fee21faf90c963746.zip
Merge branch 'usermode_syscalls'
Conflicts: Source/Kernel/Makefile
Diffstat (limited to 'Source/Library/Common')
-rw-r--r--Source/Library/Common/BasicString.class.cpp175
-rw-r--r--Source/Library/Common/BasicString.class.h53
-rw-r--r--Source/Library/Common/Bitset.class.cpp62
-rw-r--r--Source/Library/Common/Bitset.class.h31
-rw-r--r--Source/Library/Common/ByteArray.class.cpp59
-rw-r--r--Source/Library/Common/ByteArray.class.h27
-rw-r--r--Source/Library/Common/CMem.ns.cpp35
-rw-r--r--Source/Library/Common/CMem.ns.h17
-rw-r--r--Source/Library/Common/Heap-index.class.cpp51
-rw-r--r--Source/Library/Common/Heap.class.cpp232
-rw-r--r--Source/Library/Common/Heap.class.h92
-rw-r--r--Source/Library/Common/Mutex.class.cpp45
-rw-r--r--Source/Library/Common/Mutex.class.h21
-rw-r--r--Source/Library/Common/OrderedArray.class.cpp54
-rw-r--r--Source/Library/Common/OrderedArray.class.h29
-rw-r--r--Source/Library/Common/Rand.ns.cpp18
-rw-r--r--Source/Library/Common/Rand.ns.h12
-rw-r--r--Source/Library/Common/SimpleList.class.h72
-rw-r--r--Source/Library/Common/String.class.cpp201
-rw-r--r--Source/Library/Common/String.class.h49
-rw-r--r--Source/Library/Common/Vector.class.cpp135
-rw-r--r--Source/Library/Common/Vector.class.h36
-rw-r--r--Source/Library/Common/WChar.class.cpp155
-rw-r--r--Source/Library/Common/WChar.class.h89
-rw-r--r--Source/Library/Common/types.h19
25 files changed, 1769 insertions, 0 deletions
diff --git a/Source/Library/Common/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp
new file mode 100644
index 0000000..ceab60b
--- /dev/null
+++ b/Source/Library/Common/BasicString.class.cpp
@@ -0,0 +1,175 @@
+#include <Vector.class.h>
+
+#define FREE if (m_string != 0) delete m_string;
+#define ALLOC m_string = new T[m_length];
+#define VRFY if (m_length == 0) { m_string = NULL; return; }
+
+using namespace CMem;
+
+template <typename T>
+BasicString<T>::BasicString() {
+ m_string = NULL;
+ m_length = 0;
+}
+
+template <typename T>
+BasicString<T>::BasicString(const T* string, u32int length) {
+ m_string = NULL;
+ affect(string, length);
+}
+
+template <typename T>
+BasicString<T>::BasicString(const BasicString<T> &other) {
+ m_string = NULL;
+ affect(other);
+}
+
+template <typename T>
+BasicString<T>::BasicString(const T value, u32int count) {
+ m_string = NULL;
+ affect(value, count);
+}
+
+template <typename T>
+BasicString<T>::~BasicString() {
+ FREE;
+}
+
+template <typename T>
+void BasicString<T>::affect(const BasicString<T> &other) {
+ FREE;
+ m_length = other.m_length;
+ VRFY;
+ ALLOC;
+ memcpy((u8int*)m_string, (u8int*)(other.m_string), m_length * sizeof(T));
+}
+
+template <typename T>
+void BasicString<T>::affect(const T* string, u32int length) {
+ FREE;
+ m_length = length;
+ VRFY;
+ ALLOC;
+ memcpy((u8int*)string, (u8int*)string, m_length * sizeof(T));
+}
+
+template <typename T>
+void BasicString<T>::affect(const T value, u32int count) {
+ FREE;
+ m_length = count;
+ VRFY;
+ ALLOC;
+ for (u32int i = 0; i < count; i++) {
+ m_string[i] = value;
+ }
+}
+
+template <typename T>
+bool BasicString<T>::compare(const BasicString<T> &other) const {
+ if (m_length != other.m_length) return false;
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] != other.m_string[i]) return false;
+ }
+ return true;
+}
+
+template <typename T>
+bool BasicString<T>::compare(const T* string, u32int length) const {
+ if (m_length != length) return false;
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] != string[i]) return false;
+ }
+ return true;
+}
+
+template <typename T>
+BasicString<T> &BasicString<T>::append(const BasicString<T> &other) {
+ T* newdata = new T[m_length + other.m_length];
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ for (u32int i = 0; i < other.m_length; i++) {
+ newdata[i + m_length] = other.m_string[i];
+ }
+ FREE;
+ m_string = newdata;
+ m_length += other.m_length;
+ return *this;
+}
+
+template <typename T>
+BasicString<T> &BasicString<T>::append(const T* string, u32int length) {
+ T* newdata = new T[m_length + length];
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ for (u32int i = 0; i < length; i++) {
+ newdata[i + m_length] = string[i];
+ }
+ FREE;
+ m_string = newdata;
+ m_length += length;
+ return *this;
+}
+
+template <typename T>
+BasicString<T> &BasicString<T>::append(const T other) {
+ T* newdata = new T[m_length + 1];
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ FREE;
+ m_string = newdata;
+ m_string[m_length] = other;
+ m_length++;
+ return *this;
+}
+
+template <typename T>
+BasicString<T> BasicString<T>::concat(const BasicString<T> &other) const {
+ BasicString<T> ret(*this);
+ return (ret.append(other));
+}
+
+template <typename T>
+BasicString<T> BasicString<T>::concat(const T* string, u32int length) const {
+ BasicString<T> ret(*this);
+ return (ret.append(string, length));
+}
+
+template <typename T>
+BasicString<T> BasicString<T>::concat(const T other) const {
+ BasicString<T> ret(*this);
+ return (ret.append(other));
+}
+
+template <typename T>
+void BasicString<T>::clear() {
+ FREE;
+ m_string = 0;
+ m_length = 0;
+}
+
+template <typename T>
+Vector< BasicString<T> > BasicString<T>::split(T sep) const {
+ Vector< BasicString<T> > ret;
+ ret.push(BasicString<T>());
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] == sep) {
+ ret.push(BasicString<T>());
+ } else {
+ ret.back().append(m_string[i]);
+ }
+ }
+ return ret;
+}
+
+template <typename T>
+BasicString<T> BasicString<T>::substr(s32int start, u32int size) {
+ if (start < 0) start = m_length - start;
+ BasicString<T> ret;
+ ret.m_string = new T[size + 1];
+ ret.m_length = size;
+ memcpy((u8int*)ret.m_string, (u8int*)(&m_string[start]), size * sizeof(T));
+ return ret;
+}
diff --git a/Source/Library/Common/BasicString.class.h b/Source/Library/Common/BasicString.class.h
new file mode 100644
index 0000000..17055e8
--- /dev/null
+++ b/Source/Library/Common/BasicString.class.h
@@ -0,0 +1,53 @@
+#ifndef DEF_BASICSTRING_CLASS_H
+#define DEF_BASICSTRING_CLASS_H
+
+#include <common.h>
+
+template <typename T> class Vector;
+
+template <typename T>
+class BasicString {
+ protected:
+ T *m_string;
+ u32int m_length;
+
+ public:
+ BasicString();
+ BasicString(const T* string, u32int length);
+ BasicString(const BasicString<T> &other);
+ BasicString(const T, u32int count = 1);
+ virtual ~BasicString();
+
+ void affect(const BasicString<T> &other);
+ void affect(const T* string, u32int length);
+ void affect(const T value, u32int count = 1);
+ void operator= (const BasicString<T> &other) { affect(other); }
+
+ bool compare(const BasicString<T> &other) const;
+ bool compare(const T* string, u32int length) const;
+ bool operator== (const BasicString<T> &other) const { return compare(other); }
+ bool operator!= (const BasicString<T> &other) const { return !compare(other); }
+
+ BasicString<T>& append(const BasicString<T> &other);
+ BasicString<T>& append(const T* string, u32int length);
+ BasicString<T>& append(const T other);
+ BasicString<T>& operator+= (const BasicString<T> &other) { return append(other); }
+ BasicString<T>& operator+= (const T other) { return append(other); }
+
+ BasicString<T> concat(const BasicString<T> &other) const;
+ BasicString<T> concat(const T* string, u32int length) const;
+ BasicString<T> concat(const T other) const;
+
+ T& operator[] (int index) const { return m_string[index]; }
+
+ u32int size() const { return m_length; }
+ void clear();
+ bool empty() const { return m_length == 0; }
+
+ Vector< BasicString<T> > split(T sep) const;
+ BasicString<T> substr(s32int start, u32int size);
+};
+
+#include "BasicString.class.cpp"
+
+#endif
diff --git a/Source/Library/Common/Bitset.class.cpp b/Source/Library/Common/Bitset.class.cpp
new file mode 100644
index 0000000..a8d7ec8
--- /dev/null
+++ b/Source/Library/Common/Bitset.class.cpp
@@ -0,0 +1,62 @@
+#include "Bitset.class.h"
+
+Bitset::Bitset() {
+}
+
+Bitset::Bitset(u32int size) {
+ init(size, (u32int*)Mem::alloc(INDEX_FROM_BIT(size)));
+}
+
+Bitset::Bitset(u32int size, u32int *ptr) {
+ init(size, ptr);
+}
+
+Bitset::~Bitset() {
+ Mem::free(m_data);
+}
+
+void Bitset::init(u32int size, u32int *ptr) {
+ m_size = size;
+ m_data = ptr;
+ for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) {
+ m_data[i] = 0;
+ }
+ m_usedCount = 0;
+}
+
+void Bitset::setBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ m_data[idx] |= (0x1 << off);
+ m_usedCount++;
+}
+
+void Bitset::clearBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ m_data[idx] &= ~(0x1 << off);
+ m_usedCount--;
+}
+
+bool Bitset::testBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ return (m_data[idx] & (0x1 << off));
+}
+
+u32int Bitset::firstFreeBit() {
+ for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) {
+ if (m_data[i] != 0xFFFFFFFF) {
+ for (int j = 0; j < 32; j++) {
+ if (!(m_data[i] & (0x1 << j))) {
+ return (i * 4 * 8) + j;
+ }
+ }
+ }
+ }
+ return (u32int) - 1;
+}
+
+u32int Bitset::usedBits() {
+ return m_usedCount;
+}
diff --git a/Source/Library/Common/Bitset.class.h b/Source/Library/Common/Bitset.class.h
new file mode 100644
index 0000000..8a0707d
--- /dev/null
+++ b/Source/Library/Common/Bitset.class.h
@@ -0,0 +1,31 @@
+#ifndef DEF_BITSET_CLASS_H
+#define DEF_BITSET_CLASS_H
+
+#include <common.h>
+
+#define INDEX_FROM_BIT(a) (a/(8*4))
+#define OFFSET_FROM_BIT(a) (a%(8*4))
+
+class Bitset {
+ private:
+ u32int m_size;
+ u32int *m_data;
+ u32int m_usedCount;
+
+ public:
+ Bitset();
+ Bitset(u32int size);
+ Bitset(u32int size, u32int *ptr);
+ ~Bitset();
+
+ void init(u32int size, u32int *ptr);
+
+ void setBit(u32int number);
+ void clearBit(u32int number);
+ bool testBit(u32int number);
+ u32int firstFreeBit();
+
+ u32int usedBits();
+};
+
+#endif
diff --git a/Source/Library/Common/ByteArray.class.cpp b/Source/Library/Common/ByteArray.class.cpp
new file mode 100644
index 0000000..2a42702
--- /dev/null
+++ b/Source/Library/Common/ByteArray.class.cpp
@@ -0,0 +1,59 @@
+#include "ByteArray.class.h"
+
+//Define size of a uchar_repr_t
+#define CHARSZ(x) (x.c[0] == 0 ? 0 : (x.c[1] == 0 ? 1 : (x.c[2] == 0 ? 2 : (x.c[3] == 0 ? 3 : 4))))
+
+using namespace CMem;
+
+ByteArray::ByteArray(const char* c) : BasicString<u8int>() {
+ m_length = strlen(c);
+ memcpy(m_string, (u8int*)c, m_length);
+}
+
+void ByteArray::affect(const String &string, u8int encoding) {
+ m_length = 0;
+ for (u32int i = 0; i < string.size(); i++) {
+ uchar_repr_t a = string[i].encode(encoding);
+ m_length += CHARSZ(a);
+ }
+ if (m_string != 0) delete m_string;
+ if (m_length == 0) {
+ m_string = 0;
+ return;
+ }
+ m_string = new u8int[m_length];
+ u32int x = 0;
+ for (u32int i = 0; i < string.size(); i++) {
+ uchar_repr_t a = string[i].encode(encoding);
+ memcpy(m_string + x, (u8int*)a.c, CHARSZ(a));
+ x += CHARSZ(a);
+ }
+}
+
+void ByteArray::resize(u32int size) {
+ if (size == m_length) return;
+ if (size == 0) {
+ delete m_string;
+ m_length = 0;
+ m_string = 0;
+ }
+ u8int *nd = new u8int[size];
+ if (size < m_length) {
+ memcpy(nd, m_string, size);
+ } else {
+ memcpy(nd, m_string, m_length);
+ memset(nd + m_length, 0, size - m_length);
+ }
+ delete m_string;
+ m_string = nd;
+ m_length = size;
+}
+
+String ByteArray::toString (u8int encoding) {
+ char* c = new char[m_length + 1];
+ memcpy((u8int*)c, m_string, m_length);
+ c[m_length] = 0; //Add NULL terminator
+ String r(c, encoding);
+ delete c;
+ return r;
+}
diff --git a/Source/Library/Common/ByteArray.class.h b/Source/Library/Common/ByteArray.class.h
new file mode 100644
index 0000000..339e0d4
--- /dev/null
+++ b/Source/Library/Common/ByteArray.class.h
@@ -0,0 +1,27 @@
+#ifndef DEF_BYTEARRAY_CLASS_H
+#define DEF_BYTEARRAY_CLASS_H
+
+#include <String.class.h>
+
+class ByteArray : public BasicString<u8int> {
+ public:
+ ByteArray() : BasicString<u8int>() {}
+ ByteArray(const BasicString<u8int> &bs) : BasicString<u8int>() {
+ m_length = bs.size();
+ m_string = new u8int[m_length];
+ for (u32int i = 0; i < m_length; i++)
+ m_string[i] = bs[i];
+ }
+ ByteArray(const ByteArray& other) : BasicString<u8int>(other) {}
+ ByteArray(const char* c);
+ ByteArray(u32int size) : BasicString<u8int>((u8int)0, size) {}
+ ByteArray(const String &string, u8int encoding = UE_UTF8) : BasicString<u8int>() { affect(string, encoding); }
+
+ void affect(const String& string, u8int encoding = UE_UTF8);
+ void resize(u32int size);
+
+ String toString(u8int encoding = UE_UTF8);
+ operator u8int* () { return m_string; }
+};
+
+#endif
diff --git a/Source/Library/Common/CMem.ns.cpp b/Source/Library/Common/CMem.ns.cpp
new file mode 100644
index 0000000..37cdf0c
--- /dev/null
+++ b/Source/Library/Common/CMem.ns.cpp
@@ -0,0 +1,35 @@
+#include <common.h>
+
+namespace CMem {
+
+//Standard C functions
+u8int *memcpy(u8int *dest, const u8int *src, int count) {
+ for (int i = 0; i < count; i++) {
+ dest[i] = src[i];
+ }
+ return dest;
+}
+
+u8int *memset(u8int *dest, u8int val, int count) {
+ for (int i = 0; i < count; i++) {
+ dest[i] = val;
+ }
+ return dest;
+}
+
+u16int *memsetw(u16int *dest, u16int val, int count) {
+ for (int i = 0; i < count; i++) {
+ dest[i] = val;
+ }
+ return dest;
+}
+
+u32int strlen(const char *str) {
+ u32int i = 0;
+ while (str[i]) {
+ i++;
+ }
+ return i;
+}
+
+}
diff --git a/Source/Library/Common/CMem.ns.h b/Source/Library/Common/CMem.ns.h
new file mode 100644
index 0000000..f0c15da
--- /dev/null
+++ b/Source/Library/Common/CMem.ns.h
@@ -0,0 +1,17 @@
+#ifdef DEF_COMMON
+
+#ifndef DEF_CMEM_NS_H
+#define DEF_CMEM_NS_H
+
+//This namespace contains basic memory managment functions
+
+namespace CMem {
+ u8int *memcpy(u8int *dest, const u8int *src, int count);
+ u8int *memset(u8int *dest, u8int val, int count);
+ u16int *memsetw(u16int *dest, u16int val, int count);
+ u32int strlen(const char *str);
+}
+
+#endif
+
+#endif
diff --git a/Source/Library/Common/Heap-index.class.cpp b/Source/Library/Common/Heap-index.class.cpp
new file mode 100644
index 0000000..3280736
--- /dev/null
+++ b/Source/Library/Common/Heap-index.class.cpp
@@ -0,0 +1,51 @@
+#include "Heap.class.h"
+
+/*
+ * Implementation of the functions for managing heap index
+ */
+
+void Heap::insertIntoIndex(heap_header_t *e) {
+ //If index is full, return
+ if ((m_index.size * sizeof(heap_header_t*) + (u32int)m_index.data) >= m_start) return;
+
+ u32int iterator = 0;
+ while (iterator < m_index.size && m_index.data[iterator]->size < e->size) {
+ if (m_index.data[iterator] == e) return;
+ iterator++;
+ }
+ if (iterator == m_index.size) {
+ m_index.data[m_index.size++] = e;
+ } else {
+ u32int pos = iterator;
+ iterator = m_index.size;
+ while (iterator > pos) {
+ m_index.data[iterator] = m_index.data[iterator - 1];
+ iterator--;
+ }
+ m_index.size++;
+ m_index.data[pos] = e;
+ }
+}
+
+u32int Heap::findIndexEntry(heap_header_t *e) {
+ for (u32int i = 0; i < m_index.size; i++) {
+ if (m_index.data[i] == e)
+ return i;
+ }
+ return (u32int) - 1;
+}
+
+void Heap::removeFromIndex(u32int idx) {
+ m_index.size--;
+ while (idx < m_index.size) {
+ m_index.data[idx] = m_index.data[idx + 1];
+ idx++;
+ }
+}
+
+void Heap::removeFromIndex(heap_header_t *e) {
+ u32int i = findIndexEntry(e);
+ if (i != (u32int) - 1) {
+ removeFromIndex(i);
+ }
+}
diff --git a/Source/Library/Common/Heap.class.cpp b/Source/Library/Common/Heap.class.cpp
new file mode 100644
index 0000000..34e4dc4
--- /dev/null
+++ b/Source/Library/Common/Heap.class.cpp
@@ -0,0 +1,232 @@
+#include "Heap.class.h"
+
+#ifdef THIS_IS_MELON_KERNEL
+#include <MemoryManager/PageDirectory.class.h>
+#define ALLOC(x) m_pagedir->allocFrame(x, m_user, m_rw)
+#define FREE(x) m_pagedir->freeFrame(x)
+#else
+#define ALLOC(x) m_process.allocPage(x)
+#define FREE(x) m_process.freePage(x)
+#endif
+
+#ifdef THIS_IS_MELON_KERNEL
+Heap::Heap() : m_mutex(MUTEX_FALSE) {
+#else
+Heap::Heap() : m_mutex(MUTEX_FALSE), m_process(Process::get()) {
+#endif
+ m_usable = false;
+ m_index.data = 0;
+ m_index.size = 0;
+}
+
+Heap::~Heap() {
+ //TODO (optionnal) : free pages.
+}
+
+#ifdef THIS_IS_MELON_KERNEL
+void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw) {
+#else
+void Heap::create(u32int start, u32int size, u32int idxsize) {
+#endif
+ if (m_usable) return;
+
+ if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000;
+ if (size & 0x0FFF) size = (size & 0xFFFFF000) + 0x1000;
+ m_start = start + idxsize; //m_start is start of real data, start is start of index.
+ m_end = start + size;
+
+#ifdef THIS_IS_MELON_KERNEL
+ m_pagedir = pagedir;
+ m_user = user;
+ m_rw = rw;
+#endif
+
+ //Allocate frames for heap
+ for (u32int i = start ; i < m_end; i += 0x1000) {
+ ALLOC(i);
+ }
+#ifdef THIS_IS_MELON_KERNEL
+ m_pagedir->switchTo();
+#endif
+
+ m_index.data = (heap_header_t **)start; //Set index start. start == start of all heap
+ m_index.size = 0;
+
+ heap_header_t *hole = (heap_header_t*) m_start; //m_start == start of data
+ hole->size = (m_end - m_start);
+ hole->magic = HEAP_MAGIC;
+ hole->is_hole = true;
+
+ heap_footer_t *hole_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t));
+ hole_footer->header = hole;
+ hole_footer->magic = HEAP_MAGIC;
+
+ insertIntoIndex(hole);
+
+ m_usable = true;
+ m_free = (m_end - m_start);
+
+ m_mutex.unlock();
+}
+
+void Heap::expand(u32int quantity) {
+ if (quantity & 0x00000FFF)
+ quantity = (quantity & 0xFFFFF000) + 0x1000;
+
+ u32int newEnd = m_end + quantity;
+
+ for (u32int i = m_end; i < newEnd; i++) {
+ ALLOC(i);
+ }
+
+ heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t));
+ heap_header_t *last_header = last_footer->header;
+ if (last_header->is_hole) { //Last block of heap is a hole, update its size
+ removeFromIndex(last_header);
+ last_header->size += quantity;
+
+ last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t));
+
+ last_footer->magic = HEAP_MAGIC;
+ last_footer->header = last_header;
+
+ insertIntoIndex(last_header);
+ } else { //Last block is not a hole. Just add a new hole at the end
+ last_header = (heap_header_t*)m_end;
+ last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t));
+
+ last_header->is_hole = true;
+ last_header->magic = HEAP_MAGIC;
+ last_header->size = quantity;
+
+ last_footer->magic = HEAP_MAGIC;
+ last_footer->header = last_header;
+
+ insertIntoIndex(last_header);
+ }
+
+ m_end = newEnd;
+ m_free += quantity;
+}
+
+void Heap::contract() { //Automatically work out how much we can contract
+ heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t));
+ heap_header_t *last_header = last_footer->header;
+ if (last_header->is_hole == false) return; //We need a hole at end of heap
+
+ u32int quantity = 0;
+ while ((m_end - m_start) - quantity > HEAP_MIN_SIZE and
+ (last_header->size - quantity) > 0x1000) //Always keep at least 0x1000 free at end
+ quantity += 0x1000;
+ if (quantity == 0) return;
+
+ u32int newEnd = m_end - quantity;
+ m_free -= quantity;
+
+ removeFromIndex(last_header);
+ last_header->size -= quantity;
+ last_footer = (heap_footer_t*)((u32int)last_footer - quantity);
+ last_footer->magic = HEAP_MAGIC;
+ last_footer->header = last_header;
+ insertIntoIndex(last_header);
+
+ for (u32int i = newEnd; i < m_end; i += 0x1000) {
+ FREE(i);
+ }
+
+ m_end = newEnd;
+}
+
+void *Heap::alloc(u32int sz, bool no_expand) {
+ m_mutex.waitLock();
+
+ u32int newsize = sz + sizeof(heap_header_t) + sizeof(heap_footer_t);
+ u32int iterator = 0;
+ while (iterator < m_index.size) {
+ if (m_index.data[iterator]->size >= newsize) break;
+ iterator++;
+ }
+ if (iterator == m_index.size) { //No hole is big enough
+ if (no_expand) {
+ m_mutex.unlock();
+ return 0;
+ }
+ expand((sz & 0xFFFFF000) + 0x1000);
+ m_mutex.unlock();
+ return alloc(sz, true); //Recurse call
+ }
+
+ heap_header_t *loc = m_index.data[iterator];
+ heap_footer_t *footer = (heap_footer_t*)((u32int)loc + loc->size - sizeof(heap_footer_t));
+ loc->is_hole = false; //Update current header
+
+ removeFromIndex(loc);
+
+ //Here we create a new hole after currently allocated block, but only if we have enough space. If we don't, we simply allocate a bigger block so that we don't loose space
+ if (loc->size > (newsize + sizeof(heap_header_t) + sizeof(heap_footer_t))) {
+ loc->size = newsize; //Update header for return block
+
+ heap_footer_t *newfooter = (heap_footer_t*)((u32int)loc + newsize - sizeof(heap_footer_t)); //Write footer for return block
+ newfooter->header = loc;
+ newfooter->magic = HEAP_MAGIC;
+
+ heap_header_t *nextloc = (heap_header_t*)((u32int)loc + newsize); //Write header for new hole
+ nextloc->is_hole = true;
+ nextloc->magic = HEAP_MAGIC;
+ nextloc->size = ((u32int)footer - (u32int)nextloc + sizeof(heap_footer_t));
+
+ footer->header = nextloc; //Write footer for new hole
+ footer->magic = HEAP_MAGIC;
+
+ insertIntoIndex(nextloc);
+ }
+
+ m_free -= loc->size;
+
+ m_mutex.unlock();
+
+ return (void*)((u32int)loc + sizeof(heap_header_t));
+}
+
+void Heap::free(void *ptr) {
+ if (ptr == 0) return;
+
+ heap_header_t *header = (heap_header_t*) ((u32int)ptr - sizeof(heap_header_t));
+ heap_footer_t *footer = (heap_footer_t*)((u32int)header + header->size - sizeof(heap_footer_t));
+ if (header->magic != HEAP_MAGIC or footer->magic != HEAP_MAGIC) return;
+
+ m_mutex.waitLock();
+
+ m_free += header->size;
+
+ //Unify left
+ heap_footer_t *prev_footer = (heap_footer_t*)((u32int)header - sizeof(heap_footer_t));
+ if (prev_footer->magic == HEAP_MAGIC && prev_footer->header->is_hole) {
+ header = prev_footer->header;
+ removeFromIndex(header);
+
+ footer->header = header;
+ header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t));
+ }
+
+ //Unify right
+ heap_header_t *next_header = (heap_header_t*)((u32int)footer + sizeof(heap_footer_t));
+ if (next_header->magic == HEAP_MAGIC && next_header->is_hole) {
+ removeFromIndex(next_header);
+ footer = (heap_footer_t*)((u32int)footer + next_header->size);
+
+ footer->header = header;
+ header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t));
+ }
+
+ header->is_hole = true;
+
+ insertIntoIndex(header);
+
+ if ((u32int)footer == (m_end - sizeof(heap_footer_t)) and
+ header->size >= 0x2000 and (m_end - m_start > HEAP_MIN_SIZE)) {
+ contract();
+ }
+
+ m_mutex.unlock();
+}
diff --git a/Source/Library/Common/Heap.class.h b/Source/Library/Common/Heap.class.h
new file mode 100644
index 0000000..f5895c7
--- /dev/null
+++ b/Source/Library/Common/Heap.class.h
@@ -0,0 +1,92 @@
+#ifndef DEF_HEAP_CLASS_H
+#define DEF_HEAP_CLASS_H
+
+#include <common.h>
+#include <Mutex.class.h>
+
+//Heap minimum size : 2M
+#define HEAP_MIN_SIZE 0x00200000
+//Heap magic number, for verifications
+#define HEAP_MAGIC 0xBEEF1337
+
+struct heap_header_t {
+ u32int magic;
+ bool is_hole;
+ u32int size;
+};
+
+struct heap_footer_t {
+ u32int magic;
+ heap_header_t *header;
+};
+
+struct heap_index_t {
+ heap_header_t **data;
+ u32int size;
+};
+
+#ifdef THIS_IS_MELON_KERNEL
+class PageDirectory;
+#else
+#include <Binding/Process.class.h>
+#endif
+
+class Heap {
+ private:
+ u32int m_free, m_start, m_end;
+ bool m_usable;
+ heap_index_t m_index;
+#ifdef THIS_IS_MELON_KERNEL
+ bool m_user, m_rw;
+ PageDirectory* m_pagedir;
+#else
+ Process m_process;
+#endif
+
+ Mutex m_mutex;
+
+ void insertIntoIndex(heap_header_t *e);
+ u32int findIndexEntry(heap_header_t *e);
+ void removeFromIndex(u32int idx);
+ void removeFromIndex(heap_header_t *e);
+
+ void expand(u32int quantity);
+ void contract(); //Quantity is automatically calculated
+
+ public:
+ Heap();
+ ~Heap();
+
+#ifdef THIS_IS_MELON_KERNEL
+ void create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw);
+#else
+ void create(u32int start, u32int size, u32int idxsize);
+#endif
+
+ void* alloc(u32int sz, bool no_expand = false);
+ void free(void* ptr);
+
+ bool usable() {
+ m_mutex.waitLock();
+ bool ret = m_usable;
+ m_mutex.unlock();
+ return ret;
+ }
+
+ u32int size() {
+ m_mutex.waitLock();
+ u32int ret = m_end - m_start;
+ m_mutex.unlock();
+ return ret;
+ }
+
+ u32int free() {
+ m_mutex.waitLock();
+ u32int ret = m_free;
+ m_mutex.unlock();
+ return ret;
+ }
+};
+
+
+#endif
diff --git a/Source/Library/Common/Mutex.class.cpp b/Source/Library/Common/Mutex.class.cpp
new file mode 100644
index 0000000..2e9a63c
--- /dev/null
+++ b/Source/Library/Common/Mutex.class.cpp
@@ -0,0 +1,45 @@
+#include "Mutex.class.h"
+
+#ifdef THIS_IS_MELON_KERNEL
+#include <TaskManager/Task.ns.h>
+#endif
+
+#ifdef THIS_IS_MELON_USERLAND
+#include <Binding/Thread.class.h>
+#endif
+
+u32int atomic_exchange(u32int* ptr, u32int newval) {
+ u32int r;
+ asm volatile("xchg (%%ecx), %%eax" : "=a"(r) : "c"(ptr), "a"(newval));
+ return r;
+}
+
+Mutex::Mutex(u32int locked) {
+ m_locked = locked;
+}
+
+bool Mutex::lock() {
+ if (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) return false; //The lock was already locked
+ return true;
+}
+
+void Mutex::waitLock() {
+ while (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) {
+#ifdef THIS_IS_MELON_KERNEL
+ if (Task::currThread() != 0) Task::currThread()->sleep(10); //Wait 10ms
+ else return;
+#endif
+
+#ifdef THIS_IS_MELON_USERLAND
+ Thread::get().sleep(10);
+#endif
+ }
+}
+
+void Mutex::unlock() {
+ m_locked = MUTEX_FALSE;
+}
+
+bool Mutex::locked() {
+ return m_locked;
+}
diff --git a/Source/Library/Common/Mutex.class.h b/Source/Library/Common/Mutex.class.h
new file mode 100644
index 0000000..1e3f63d
--- /dev/null
+++ b/Source/Library/Common/Mutex.class.h
@@ -0,0 +1,21 @@
+#ifndef DEF_MUTEX_CLASS_H
+#define DEF_MUTEX_CLASS_H
+
+#include <common.h>
+
+#define MUTEX_FALSE 0
+#define MUTEX_TRUE 1
+
+class Mutex {
+ private:
+ u32int m_locked;
+
+ public:
+ Mutex(u32int locked = MUTEX_FALSE);
+ bool lock(); //Locks the mutex if it is not locked. Returns true if mutex could be locked, false if already locked
+ void waitLock(); //Locks the mutex, waiting for it to be unlocked before if necessary
+ void unlock();
+ bool locked();
+};
+
+#endif
diff --git a/Source/Library/Common/OrderedArray.class.cpp b/Source/Library/Common/OrderedArray.class.cpp
new file mode 100644
index 0000000..8b8f24f
--- /dev/null
+++ b/Source/Library/Common/OrderedArray.class.cpp
@@ -0,0 +1,54 @@
+template <typename T>
+OrderedArray<T>::OrderedArray(u32int max_size) {
+ m_array = (T*)Memory::alloc(max_size * sizeof(T*));
+ m_size = 0;
+ m_maxSize = max_size;
+}
+
+template <typename T>
+OrderedArray<T>::OrderedArray(T **addr, u32int max_size) {
+ m_array = addr;
+ memset((u8int*)addr, 0, max_size * sizeof(T*));
+ m_size = 0;
+ m_maxSize = max_size;
+}
+
+template <typename T>
+OrderedArray<T>::~OrderedArray() {
+ //Free memory
+}
+
+template <typename T>
+void OrderedArray<T>::insert(T *element) {
+ if (m_size == m_maxSize) return; //Array is full
+ u32int iterator = 0;
+ while (iterator < m_size && *(m_array[iterator]) < *element) {
+ iterator++;
+ }
+ if (iterator == m_size) {
+ m_array[m_size++] = element;
+ } else {
+ u32int pos = iterator;
+ while (iterator < m_size) {
+ iterator++;
+ m_array[iterator] = m_array[iterator - 1];
+ }
+ m_size++;
+ m_array[pos] = element;
+ }
+}
+
+template <typename T>
+T *OrderedArray<T>::lookup(int index) {
+ return m_array[index];
+}
+
+template <typename T>
+void OrderedArray<T>::remove(int index) {
+ m_size--;
+ while (index < m_size) {
+ m_array[index] = m_array[index + 1];
+ index++;
+ }
+}
+
diff --git a/Source/Library/Common/OrderedArray.class.h b/Source/Library/Common/OrderedArray.class.h
new file mode 100644
index 0000000..3091249
--- /dev/null
+++ b/Source/Library/Common/OrderedArray.class.h
@@ -0,0 +1,29 @@
+#ifndef DEF_ORDARRAY_CLASS
+#define DEF_ORDARRAY_CLASS
+
+#include <common.h>
+
+template <typename T>
+class OrderedArray {
+ private:
+ T *m_array[];
+ u32int m_size;
+ u32int m_maxSize;
+
+ public:
+ OrderedArray(u32int max_size);
+ OrderedArray(T **addr, u32int max_size);
+ ~OrderedArray();
+
+ u32int size() { return m_size; }
+
+ void insert(T *element);
+ T *lookup(int index);
+ void remove(int index);
+
+ T *operator[] (int index) { return lookup(index); }
+};
+
+#include "OrderedArray.class.cpp"
+
+#endif
diff --git a/Source/Library/Common/Rand.ns.cpp b/Source/Library/Common/Rand.ns.cpp
new file mode 100644
index 0000000..e568678
--- /dev/null
+++ b/Source/Library/Common/Rand.ns.cpp
@@ -0,0 +1,18 @@
+#include "Rand.ns.h"
+
+namespace Rand {
+
+u32int m = 2073741824, a = 50000, b = 1534;
+u64int current = RANDOM_SEED;
+
+u64int rand() {
+ current = (u32int)(a*current + b);
+ while (current > m) current -= m;
+ return current;
+}
+
+u64int max() {
+ return m;
+}
+
+}
diff --git a/Source/Library/Common/Rand.ns.h b/Source/Library/Common/Rand.ns.h
new file mode 100644
index 0000000..71d4f60
--- /dev/null
+++ b/Source/Library/Common/Rand.ns.h
@@ -0,0 +1,12 @@
+#ifndef DEF_RAND_NS_H
+#define DEF_RAND_NS_H
+
+#include <common.h>
+
+namespace Rand {
+ u64int rand();
+ u64int max();
+}
+
+#endif
+
diff --git a/Source/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h
new file mode 100644
index 0000000..7b731db
--- /dev/null
+++ b/Source/Library/Common/SimpleList.class.h
@@ -0,0 +1,72 @@
+#ifndef DEF_SIMPLELIST_CLASS_H
+#define DEF_SIMPLELIST_CLASS_H
+
+#include <common.h>
+
+/* This class implements a singly linked list. It is also used to represent one of its elements. */
+
+template <typename T>
+class SimpleList {
+ protected:
+ T m_value;
+ SimpleList<T>* m_next;
+
+ public:
+ SimpleList(const T& value, SimpleList<T>* next = 0) : m_value(value), m_next(next) {}
+ ~SimpleList() {
+ if (m_next != 0)
+ delete m_next;
+ }
+
+ T& v() { return m_value; }
+ T& operator* () { return m_value; }
+
+ SimpleList<T>* cons(const T& value) {
+ return new SimpleList<T>(value, this);
+ }
+
+ SimpleList<T>* next() {
+ return m_next;
+ }
+
+ SimpleList<T>* last() {
+ if (m_next == 0) return this;
+ return m_next->last();
+ }
+
+ SimpleList<T>* delThis() {
+ SimpleList<T>* ret = m_next;
+ Mem::free(this);
+ return ret;
+ }
+
+ void delNext() {
+ if (m_next == 0) return;
+ SimpleList<T>* temp = m_next;
+ m_next = m_next->m_next;
+ Mem::free(temp);
+ }
+
+ SimpleList<T>* removeOnce(const T& value) {
+ if (value == m_value) return delThis();
+ for (SimpleList<T> *iter = this; iter->next() != 0; iter = iter->next()) {
+ if (iter->next()->v() == value) {
+ iter->delNext();
+ break;
+ }
+ }
+ return this;
+ }
+
+ bool isEnd() {
+ return m_next == 0;
+ }
+
+ u32int size() {
+ if (m_next == 0)
+ return 0;
+ return m_next->size() + 1;
+ }
+};
+
+#endif
diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp
new file mode 100644
index 0000000..ac0eba0
--- /dev/null
+++ b/Source/Library/Common/String.class.cpp
@@ -0,0 +1,201 @@
+#include "String.class.h"
+#include <Vector.class.h>
+
+using namespace CMem; //strlen and memcpy
+
+String String::hex(u32int number) {
+ String ret;
+ ret.m_length = 10;
+ ret.m_string = new WChar[11];
+ ret.m_string[0] = '0';
+ ret.m_string[1] = 'x';
+ ret.m_string[10] = 0;
+
+ char hexdigits[] = "0123456789ABCDEF";
+ for (unsigned int j = 0; j < 8; j++) {
+ ret.m_string[j + 2] = hexdigits[(number & 0xF0000000) >> 28];
+ number = number << 4;
+ }
+ return ret;
+}
+
+String String::number(s32int number) {
+ if (number == 0) return String("0");
+ bool negative = false;
+ if (number < 0) {
+ negative = true;
+ number = 0 - number;
+ }
+ u32int order = 0, temp = number;
+ char numbers[] = "0123456789";
+ while (temp > 0) {
+ order++;
+ temp /= 10;
+ }
+
+ String ret;
+ ret.m_length = order;
+ ret.m_string = new WChar[order + 1];
+
+ for (u32int i = order; i > 0; i--) {
+ ret.m_string[i - 1] = numbers[number % 10];
+ number /= 10;
+ }
+
+ ret.m_string[order] = 0;
+
+ if (negative) return String("-") += ret;
+
+ return ret;
+}
+
+String String::unserialize(u32int w) {
+ u32int* a = (u32int*)w;
+ String ret;
+ ret.m_length = a[0];
+ ret.m_string = (WChar*)Mem::alloc(a[0] * sizeof(WChar));
+ for (u32int i = 0; i < a[0]; i++) {
+ ret[i] = a[i + 1];
+ }
+ return ret;
+}
+
+u32int String::serialize() const {
+ u32int* x = (u32int*)Mem::mkXchgSpace((m_length + 1) * sizeof(u32int));
+ x[0] = m_length;
+ for (u32int i = 0; i < m_length; i++) {
+ x[i + 1] = m_string[i];
+ }
+ return (u32int)x;
+}
+
+String::String(const char* string, u8int encoding) {
+ m_string = 0;
+ m_length = 0;
+ affect(string, encoding);
+}
+
+void String::affect (const char* string, u8int encoding) {
+ m_length = WChar::utfLen(string, encoding);
+ if (m_string != 0) delete [] m_string;
+ if (m_length == 0) {
+ m_string = 0;
+ return;
+ }
+ m_string = new WChar[m_length + 1];
+ int i = 0, l = strlen(string), c = 0;
+ while (i < l) {
+ i += m_string[c].affect(string + i, encoding);
+ c++;
+ }
+ m_string[m_length] = 0;
+}
+
+bool String::compare (const char* string, u8int encoding) const {
+ if (m_length != WChar::utfLen(string, encoding)) return false;
+ int i = 0, l = strlen(string), c = 0;
+ WChar tmp;
+ while (i < l) {
+ i += tmp.affect(string + i, encoding);
+ if (m_string[c] != tmp) return false;
+ c++;
+ }
+ return true;
+}
+
+String& String::append (const char* other, u8int encoding) {
+ WChar* newdata = new WChar[m_length + WChar::utfLen(other, encoding) + 1];
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ int i = 0, l = strlen(other), c = 0;
+ while (i < l) {
+ i += newdata[c + m_length].affect(other + i, encoding);
+ c++;
+ }
+ if (m_string != 0) delete [] m_string;
+ m_string = newdata;
+ m_length += strlen(other);
+ m_string[m_length] = 0;
+ return *this;
+}
+
+String String::concat (const String &other) const { //Can be optimized
+ String ret(*this);
+ return (ret += other);
+}
+
+String String::concat (const char* other, u8int encoding) const { //Can be optimized
+ String ret(*this);
+ return (ret.append(other, encoding));
+}
+
+String String::concat (WChar other) const {
+ String ret(*this);
+ return (ret += other);
+}
+
+s64int String::toInt() const {
+ if (m_string == 0) return 0;
+ s32int pos = 0;
+ s64int number = 0;
+ bool negative = false;
+ if (m_string[0].value == '-') {
+ negative = true;
+ pos = 1;
+ }
+ while (m_string[pos] >= '0' && m_string[pos] <= '9') {
+ number *= 10;
+ number += (m_string[pos].value - '0');
+ pos++;
+ }
+ if (negative) return 0 - number;
+ return number;
+}
+
+u64int String::toInt16() const {
+ if (m_string == 0) return 0;
+ u32int pos = 0;
+ u64int number = 0;
+ if (m_string[0].value == '0' && m_string[1].value == 'x') pos = 2;
+ while (1) {
+ char c = m_string[pos];
+ pos++;
+ if (c >= 'a' && c <= 'f') c -= ('a' - 'A'); //To uppercase
+ if (c >= '0' && c <= '9') {
+ number *= 16;
+ number += (c - '0');
+ continue;
+ }
+ if (c >= 'A' && c <= 'F') {
+ number *= 16;
+ number += (c - 'A' + 10);
+ continue;
+ }
+ break;
+ }
+ return number;
+}
+
+Vector<String> String::split(WChar c) const {
+ Vector<String> ret;
+ ret.push(String(""));
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] == c) {
+ ret.push(String(""));
+ } else {
+ ret.back() += m_string[i];
+ }
+ }
+ return ret;
+}
+
+String String::substr(s32int start, u32int size) {
+ if (start < 0) start = m_length - start;
+ String ret;
+ ret.m_string = new WChar[size + 1];
+ ret.m_length = size;
+ memcpy((u8int*)ret.m_string, (const u8int*)(m_string + start), size * sizeof(WChar));
+ ret.m_string[size] = 0;
+ return ret;
+}
diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h
new file mode 100644
index 0000000..0d48ce6
--- /dev/null
+++ b/Source/Library/Common/String.class.h
@@ -0,0 +1,49 @@
+#ifndef DEF_STRING_CLASS
+#define DEF_STRING_CLASS
+
+#include <BasicString.class.h>
+#include <WChar.class.h>
+
+class String : public BasicString<WChar> {
+ public:
+ static String hex(u32int number);
+ static String number(s32int number);
+
+ static String unserialize(u32int w);
+ u32int serialize() const;
+
+ String(const char* string, u8int encoding = UE_UTF8);
+ String() : BasicString<WChar>() {}
+ String(const String &other) : BasicString<WChar> (other) {}
+
+ void affect(const char* string, u8int encoding = UE_UTF8);
+ void operator= (const char* other) { affect(other); }
+ void operator= (const String& other) { BasicString<WChar>::affect(other); }
+
+ bool compare(const char* string, u8int encoding = UE_UTF8) const;
+ bool operator== (const char* other) const { return compare(other); }
+ bool operator!= (const char* other) { return !compare(other); }
+ bool operator== (const String& other) const { return BasicString<WChar>::compare(other); }
+ bool operator!= (const String& other) const { return !BasicString<WChar>::compare(other); }
+
+ String& append(const char* other, u8int encoding = UE_UTF8);
+ String &operator+= (const String &other) { BasicString<WChar>::append(other); return *this; }
+ String &operator+= (const char* other) { return append(other); }
+ String &operator+= (WChar other) { BasicString<WChar>::append(other); return *this; }
+
+ String concat(const String &other) const;
+ String concat(const char* other, u8int encoding = UE_UTF8) const;
+ String concat(WChar other) const;
+ String operator+ (const String &other) const { return concat(other); }
+ String operator+ (const char* other) const { return concat(other); }
+ String operator+ (WChar other) const { return concat(other); }
+
+ s64int toInt() const; //Convert from DEC
+ u64int toInt16() const; //Convert from HEX
+
+ Vector<String> split(WChar c) const;
+
+ String substr(s32int start, u32int size);
+};
+
+#endif
diff --git a/Source/Library/Common/Vector.class.cpp b/Source/Library/Common/Vector.class.cpp
new file mode 100644
index 0000000..c546a42
--- /dev/null
+++ b/Source/Library/Common/Vector.class.cpp
@@ -0,0 +1,135 @@
+using namespace CMem; //strlen and memcpy
+
+#define DELDATA if (m_data != NULL and m_size != 0) { \
+ for (u32int i = 0; i < m_size; i++) { \
+ m_data[i].~T(); \
+ } \
+ Mem::free(m_data); \
+}
+
+template <typename T>
+Vector<T>::Vector() {
+ //DEBUG_HEX((u32int)this); DEBUG(" NEW EMPTY");
+ //DEBUG_HEX(sizeof(T)); DEBUG(" sizeof(T)");
+ m_data = 0;
+ m_size = 0;
+}
+
+template <typename T>
+Vector<T>::Vector(u32int size) {
+ //DEBUG_HEX((u32int)this); DEBUG(" NEW ZERO");
+ m_data = new T[size];
+ m_size = size;
+}
+
+template <typename T>
+Vector<T>::Vector(u32int size, const T& value) {
+ //DEBUG_HEX((u32int)this); DEBUG(" NEW FILLED");
+ //m_data = (T*)Mem::alloc(size * sizeof(T));
+ m_data = new T[size];
+ m_size = size;
+ for (u32int i = 0; i < m_size; i++) {
+ new (&m_data[i]) T(value);
+ }
+ /*for (u32int i = 0; i < size; i++) {
+ m_data[i] = new(&m_data[i]) T(value);
+ }*/
+}
+
+template <typename T>
+Vector<T>::Vector(const Vector<T> &other) {
+ //DEBUG_HEX((u32int)this); DEBUG(" COPY REF");
+ m_size = other.m_size;
+ m_data = (T*)Mem::alloc(m_size * sizeof(T));
+ for (u32int i = 0; i < m_size; i++) {
+ new(&m_data[i]) T(other.m_data[i]);
+ }
+}
+
+template <typename T>
+Vector<T>& Vector<T>::operator= (const Vector<T> &other) {
+ //DEBUG_HEX((u32int)this); DEBUG(" COPY EQ");
+ DELDATA;
+ m_size = other.m_size;
+ m_data = (T*)Mem::alloc(m_size * sizeof(T));
+ for (u32int i = 0; i < m_size; i++) {
+ new(&m_data[i]) T(other.m_data[i]);
+ }
+ return *this;
+}
+
+template <typename T>
+Vector<T>::~Vector() {
+ //DEBUG_HEX((u32int)this); DEBUG(" DELETE");
+ DELDATA;
+ //if (m_data != 0) delete[] m_data;
+}
+
+template <typename T>
+T& Vector<T>::operator[] (u32int index) const {
+ return m_data[index];
+}
+
+template <typename T>
+void Vector<T>::push(const T& element) {
+ T* newdata = (T*)Mem::alloc((m_size + 1) * sizeof(T));
+ if (m_size != 0 and m_data != 0) {
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ }
+ new(&newdata[m_size]) T(element); //Construct by copy
+ //newdata[m_size] = element;
+ m_size++;
+ Mem::free(m_data);
+ m_data = newdata;
+}
+
+/* template <typename T>
+void Vector<T>::push(T& element) {
+ T* newdata = (T*)Memory::alloc((m_size + 1) * sizeof(T));
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ //memcpy((u8int*)newdata + (m_size * sizeof(T)), (const u8int*) element, sizeof(T)); //Copy
+ new(&newdata[m_size]) T(element); //Construct by copy
+ m_size++;
+ Memory::free(m_data);
+ m_data = newdata;
+} */
+
+template <typename T>
+void Vector<T>::pop() {
+ m_size--;
+ //delete(&m_data[m_size], &m_data[m_size]); //implicitly call destructor with placement delete
+ m_data[m_size].~T(); //Call destructor
+ T* newdata = (T*)Mem::alloc(m_size * sizeof(T));
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ Mem::free(m_data);
+ m_data = newdata;
+}
+
+template <typename T>
+T& Vector<T>::back() const {
+ return m_data[m_size - 1];
+}
+
+template <typename T>
+T& Vector<T>::front() const {
+ return m_data[0];
+}
+
+
+template <typename T>
+u32int Vector<T>::size() const {
+ return m_size;
+}
+
+template <typename T>
+bool Vector<T>::empty() const {
+ return m_size == 0;
+}
+
+template <typename T>
+void Vector<T>::clear() {
+ if (empty()) return;
+ DELDATA
+ m_data = 0;
+ m_size = 0;
+}
diff --git a/Source/Library/Common/Vector.class.h b/Source/Library/Common/Vector.class.h
new file mode 100644
index 0000000..436e2f9
--- /dev/null
+++ b/Source/Library/Common/Vector.class.h
@@ -0,0 +1,36 @@
+#ifndef DEF_VECTOR_CLASS
+#define DEF_VECTOR_CLASS
+
+#include <common.h>
+
+template <typename T>
+class Vector {
+ private:
+ T *m_data;
+ u32int m_size;
+
+ public:
+ Vector();
+ Vector(u32int size);
+ Vector(u32int size, const T& value);
+ Vector(const Vector<T> &other);
+ Vector<T>& operator= (const Vector<T> &other);
+ ~Vector();
+
+ T& operator[] (u32int index) const;
+
+ void push(const T& element);
+ //void push(T& element);
+ void pop();
+
+ T& back() const;
+ T& front() const;
+
+ u32int size() const;
+ bool empty() const;
+ void clear();
+};
+
+#include "Vector.class.cpp"
+
+#endif
diff --git a/Source/Library/Common/WChar.class.cpp b/Source/Library/Common/WChar.class.cpp
new file mode 100644
index 0000000..5485bb8
--- /dev/null
+++ b/Source/Library/Common/WChar.class.cpp
@@ -0,0 +1,155 @@
+#include "WChar.class.h"
+
+#ifdef THIS_IS_MELON_KERNEL
+using namespace CMem;
+#endif
+
+#ifdef THIS_IS_MELON_USERLAND
+using namespace CMem;
+#endif
+
+WChar WChar::CP437[] = { //These are the UTF8 equivalents for the 128 extra characters of code page 437
+ "Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å",
+ "É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ",
+ "á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»",
+ "░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐",
+ "└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "¤",
+ "╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀",
+ "α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩",
+ "≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■", "⍽"
+};
+
+WChar::WChar() {
+ value = 0;
+}
+
+WChar::WChar(char c) {
+ affectAscii(c);
+}
+
+WChar::WChar(const char* c, u8int encoding) {
+ if (encoding == UE_UTF8) affectUtf8(c);
+ if (encoding == UE_UTF16) affectUtf16(c);
+ if (encoding == UE_UTF32) affectUtf32(c);
+}
+
+u32int WChar::ucharLen(const char* c, u8int encoding) {
+ if (encoding == UE_UTF8) {
+ if ((c[0] & 0x80) == 0) return 1;
+ else if ((c[0] & 0xE0) == 0xC0) return 2;
+ else if ((c[0] & 0xF0) == 0xE0) return 3;
+ else if ((c[0] & 0xF8) == 0xF0) return 4;
+ else return 1;
+ } else if (encoding == UE_UTF16) {
+ if ((c[0] & 0xFC) == 0xD8 and (c[2] & 0xFC) == 0xDC) return 4;
+ else return 2;
+ } else if (encoding == UE_UTF32) {
+ return 4;
+ }
+ return 1;
+}
+
+u32int WChar::utfLen(const char* c, u8int encoding) {
+ int i = 0, l = strlen(c), co = 0;
+ while (i < l) {
+ i += ucharLen(c + i, encoding);
+ co++;
+ }
+ return co;
+}
+
+void WChar::affectAscii(char c) {
+ if (c >= 0) value = c;
+ else value = CP437[c + 128];
+}
+
+u32int WChar::affectUtf8(const char* c) { //Returns the number of bytes for the character
+ if ((c[0] & 0x80) == 0) {
+ value = c[0]; //0x80 = 10000000b
+ return 1;
+ }
+ if ((c[0] & 0xE0) == 0xC0) { // 11100000b, 11000000b
+ value = ((c[0] & 0x1F) << 6) | (c[1] & 0x3F);
+ if (value < 128) value = 0; //Bad value
+ return 2;
+ }
+ if ((c[0] & 0xF0) == 0xE0) { // 11110000b, 11100000b
+ value = ((c[0] & 0x0F) << 12) | ((c[1] & 0x3F) << 6) | (c[2] & 0x3F);
+ if (value < 2048) value = 0; //Bad value
+ if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed
+ if (value >= 0xFFFE and value <= 0xFFFF) value = 0;
+ return 3;
+ }
+ if ((c[0] & 0xF8) == 0xF0) { // 11111000b, 11110000b
+ value = ((c[0] & 0x0E) << 18) | ((c[1] & 0x3F) << 12) | ((c[2] & 0x3F) << 6) | (c[3] & 0x3F);
+ if (value < 65536) value = 0; //Bad value
+ return 4;
+ }
+ value = 0; //Something wrong happenned
+ return 1;
+}
+
+u32int WChar::affectUtf16(const char* c) {
+ if ((c[0] & 0xFC) == 0xD8 and // 11111100b, 11011000b
+ (c[2] & 0xFC) == 0xDC) { // 11111100b, 11011100b
+ u32int w = ((c[0] & 0x03) << 2) | ((c[1] & 0xC0) >> 6);
+ u32int x = (c[1] & 0x3F);
+ u32int y = ((c[2] & 0x03) << 8) | (c[2]);
+ value = ((w + 1) << 16) | (x << 10) | y;
+ if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed
+ if (value >= 0xFFFE and value <= 0xFFFF) value = 0;
+ return 4;
+ } else {
+ value = (c[0] << 8) | (c[1]);
+ if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed
+ if (value >= 0xFFFE and value <= 0xFFFF) value = 0;
+ return 2;
+ }
+}
+
+u32int WChar::affectUtf32(const char* c) {
+ value = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
+ if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed
+ if (value >= 0xFFFE and value <= 0xFFFF) value = 0;
+ return 4;
+}
+
+u8int WChar::toAscii() {
+ if (value < 128) return (char)value;
+ for (int i = 0; i < 128; i++) {
+ if (CP437[i] == value) return (i + 128);
+ }
+ return '?';
+}
+
+uchar_repr_t WChar::toUtf8() {
+ uchar_repr_t r;
+ r.i = 0;
+ if (value < 128) {
+ r.c[0] = value;
+ } else if (value < 4096) {
+ r.c[0] = 0xC0 | ((value & 0x07C0) >> 6);
+ r.c[1] = 0x80 | (value & 0x3F);
+ } else if (value < 65536) {
+ r.c[0] = 0xE0 | ((value & 0xF000) >> 12);
+ r.c[1] = 0x80 | ((value & 0x0FC0) >> 6);
+ r.c[2] = 0x80 | (value & 0x003F);
+ } else {
+ r.c[0] = 0xF0 | ((value & 0x1C0000) >> 18);
+ r.c[1] = 0x80 | ((value & 0x3F000) >> 12);
+ r.c[2] = 0x80 | ((value & 0x0FC0) >> 6);
+ r.c[3] = 0x80 | (value & 0x003F);
+ }
+ return r;
+}
+
+//TODO : code WChar::toUtf16
+
+uchar_repr_t WChar::toUtf32() {
+ uchar_repr_t r;
+ r.c[0] = (value >> 24) & 0xFF;
+ r.c[1] = (value >> 16) & 0xFF;
+ r.c[2] = (value >> 8) & 0xFF;
+ r.c[3] = value & 0xFF;
+ return r;
+}
diff --git a/Source/Library/Common/WChar.class.h b/Source/Library/Common/WChar.class.h
new file mode 100644
index 0000000..3eca3d3
--- /dev/null
+++ b/Source/Library/Common/WChar.class.h
@@ -0,0 +1,89 @@
+#ifndef DEF_UCHAR_CLASS_H
+#define DEF_UCHAR_CLASS_H
+
+#include <types.h>
+
+#ifndef THIS_IS_NOT_MELON
+#include <common.h>
+#endif
+
+enum {
+ UE_UTF8,
+ UE_UTF16,
+ UE_UTF32,
+};
+
+union uchar_repr_t {
+ char c[4];
+ u32int i;
+};
+
+struct WChar {
+ u32int value;
+ static WChar CP437[]; //Codepage 437, used for conversion from/to ascii
+
+ WChar(); //Creates a null character
+ WChar(char c); //From ascii character
+ WChar(const char* c, u8int encoding = UE_UTF8); //From utf8 string
+
+ static u32int ucharLen(const char* c, u8int encoding = UE_UTF8); //Returns count of bytes in one unicode character
+ static u32int utfLen(const char* c, u8int encoding = UE_UTF8); //Returns count of utf8 characters in string
+
+ void affectAscii(char c);
+ u32int affectUtf8(const char* c);
+ u32int affectUtf16(const char* c);
+ u32int affectUtf32(const char* c);
+
+ u32int affect(const char* c, u8int encoding = UE_UTF8) {
+ if (encoding == UE_UTF8) return affectUtf8(c);
+ if (encoding == UE_UTF16) return affectUtf16(c);
+ if (encoding == UE_UTF32) return affectUtf32(c);
+ affectAscii(c[0]); //Default case :/
+ return 1;
+ }
+
+ u8int toAscii();
+
+ uchar_repr_t toUtf8();
+ uchar_repr_t toUtf16();
+ uchar_repr_t toUtf32();
+
+ uchar_repr_t encode(u8int encoding = UE_UTF8) {
+ if (encoding == UE_UTF8) return toUtf8();
+ //if (encoding == UE_UTF16) return toUtf16();
+ if (encoding == UE_UTF32) return toUtf32();
+ uchar_repr_t x;
+ x.c[0] = toAscii();
+ return x;
+ }
+
+ inline WChar operator+ (u32int other) {
+ WChar r;
+ r.value = value + other;
+ return r;
+ }
+ inline WChar operator- (u32int other) {
+ WChar r;
+ r.value = value - other;
+ return r;
+ }
+ inline WChar& operator+= (u32int other) {
+ value += other;
+ return *this;
+ }
+ inline WChar& operator-= (u32int other) {
+ value -= other;
+ return *this;
+ }
+ inline bool operator== (u32int other) {
+ return value == other;
+ }
+ inline u32int operator= (u32int v) {
+ value = v;
+ return v;
+ }
+
+ inline operator u32int () { return value; }
+};
+
+#endif
diff --git a/Source/Library/Common/types.h b/Source/Library/Common/types.h
new file mode 100644
index 0000000..ca6f73d
--- /dev/null
+++ b/Source/Library/Common/types.h
@@ -0,0 +1,19 @@
+#ifndef DEF_TYPES_WTF_H
+#define DEF_TYPES_WTF_H
+
+//This file defines base types. It's made to be used also by C programs
+
+typedef unsigned int addr_t;
+typedef unsigned long long u64int;
+typedef unsigned int u32int;
+typedef unsigned short u16int;
+typedef unsigned char u8int;
+typedef long long s64int;
+typedef int s32int;
+typedef short s16int;
+typedef char s8int;
+
+#define U64 unsigned long long
+#define S64 long long
+
+#endif