diff options
author | Alexis211 <alexis211@gmail.com> | 2009-10-18 15:27:34 +0200 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2009-10-18 15:27:34 +0200 |
commit | 323e12f1f9ab33df15dcfed210e807561d98fa8c (patch) | |
tree | 7d76e6932d4a979a1f2bfafc94478b66b1479bbc /Source/Library | |
parent | bc2eccdd11c27029096fb3e891073503eb269e27 (diff) | |
download | Melon-323e12f1f9ab33df15dcfed210e807561d98fa8c.tar.gz Melon-323e12f1f9ab33df15dcfed210e807561d98fa8c.zip |
Re-organized everything
Diffstat (limited to 'Source/Library')
24 files changed, 1375 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..ec4e62c --- /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::kalloc(INDEX_FROM_BIT(size))); +} + +Bitset::Bitset(u32int size, u32int *ptr) { + init(size, ptr); +} + +Bitset::~Bitset() { + Mem::kfree(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/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..64e37aa --- /dev/null +++ b/Source/Library/Common/SimpleList.class.h @@ -0,0 +1,70 @@ +#ifndef DEF_SIMPLELIST_CLASS_H +#define DEF_SIMPLELIST_CLASS_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::kfree(this); + return ret; + } + + void delNext() { + if (m_next == 0) return; + SimpleList<T>* temp = m_next; + m_next = m_next->m_next; + Mem::kfree(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..d8913d9 --- /dev/null +++ b/Source/Library/Common/String.class.cpp @@ -0,0 +1,181 @@ +#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(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..3e50d35 --- /dev/null +++ b/Source/Library/Common/String.class.h @@ -0,0 +1,46 @@ +#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); + + 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..02ae9be --- /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::kfree(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::kalloc(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::kalloc(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::kalloc(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::kalloc((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::kfree(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::kalloc(m_size * sizeof(T)); + memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T)); + Mem::kfree(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 diff --git a/Source/Library/Makefile b/Source/Library/Makefile new file mode 100644 index 0000000..f7d337b --- /dev/null +++ b/Source/Library/Makefile @@ -0,0 +1,33 @@ +.PHONY: clean, mrproper + +CXX = g++ +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I Common -I Userland -D THIS_IS_MELON_USERLAND + +LDFLAGS = -r +LD = ld + +Library = Melon.o +Objects = Common/WChar.class.uo \ + Common/CMem.ns.uo \ + Userland/Syscall/Syscall.wtf.uo + +all: $(Library) + echo "* Done with library" + +rebuild: mrproper all + +$(Library): $(Objects) + echo "* Linking melon library $(Library)..." + $(LD) $(LDFLAGS) $^ -o $@ + +%.uo: %.cpp + echo "* Compiling $<..." + $(CXX) $(CXXFLAGS) -c $< -o $@ + +clean: + echo "* Removing object files..." + rm -rf $(Objects) + +mrproper: clean + echo "* Removing library..." + rm -rf $(Library) diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.cpp b/Source/Library/Userland/Syscall/Syscall.wtf.cpp new file mode 100644 index 0000000..2c03b20 --- /dev/null +++ b/Source/Library/Userland/Syscall/Syscall.wtf.cpp @@ -0,0 +1,20 @@ +#include "Syscall.wtf.h" + +int main(); + +unsigned int syscall(unsigned int n, unsigned int a, unsigned int b, unsigned int c) { + unsigned int r; + asm volatile ("int $64;" + : "=a"(r) : "a"(n), "b"(a), "c"(b), "d"(c)); + return r; +} + +extern "C" void start() { + unsigned int r = main(); + asm volatile("int $66" : : "a"(r)); +} + +void putch(char c) { + unsigned int x = c; + syscall(0xFFFFFF01, x); +} diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.h b/Source/Library/Userland/Syscall/Syscall.wtf.h new file mode 100644 index 0000000..b220d14 --- /dev/null +++ b/Source/Library/Userland/Syscall/Syscall.wtf.h @@ -0,0 +1,9 @@ +#ifndef DEF_SYSCALL_WTF_H +#define DEF_SYSCALL_WTF_H + +#include <types.h> + +void putch(char); +unsigned int syscall(unsigned int n, unsigned int a, unsigned int b = 0, unsigned int c = 0); + +#endif diff --git a/Source/Library/Userland/common.h b/Source/Library/Userland/common.h new file mode 100644 index 0000000..27218f7 --- /dev/null +++ b/Source/Library/Userland/common.h @@ -0,0 +1,10 @@ +#ifndef DEF_COMMON +#define DEF_COMMON + +#define NULL 0 + +#include <types.h> + +#include <CMem.ns.h> + +#endif |