From 323e12f1f9ab33df15dcfed210e807561d98fa8c Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 15:27:34 +0200 Subject: Re-organized everything --- Source/Library/Common/BasicString.class.cpp | 175 ++++++++++++++++++++++++++ Source/Library/Common/BasicString.class.h | 53 ++++++++ Source/Library/Common/Bitset.class.cpp | 62 +++++++++ Source/Library/Common/Bitset.class.h | 31 +++++ Source/Library/Common/ByteArray.class.cpp | 59 +++++++++ Source/Library/Common/ByteArray.class.h | 27 ++++ Source/Library/Common/CMem.ns.cpp | 35 ++++++ Source/Library/Common/CMem.ns.h | 17 +++ Source/Library/Common/OrderedArray.class.cpp | 54 ++++++++ Source/Library/Common/OrderedArray.class.h | 29 +++++ Source/Library/Common/Rand.ns.cpp | 18 +++ Source/Library/Common/Rand.ns.h | 12 ++ Source/Library/Common/SimpleList.class.h | 70 +++++++++++ Source/Library/Common/String.class.cpp | 181 +++++++++++++++++++++++++++ Source/Library/Common/String.class.h | 46 +++++++ Source/Library/Common/Vector.class.cpp | 135 ++++++++++++++++++++ Source/Library/Common/Vector.class.h | 36 ++++++ Source/Library/Common/WChar.class.cpp | 155 +++++++++++++++++++++++ Source/Library/Common/WChar.class.h | 89 +++++++++++++ Source/Library/Common/types.h | 19 +++ 20 files changed, 1303 insertions(+) create mode 100644 Source/Library/Common/BasicString.class.cpp create mode 100644 Source/Library/Common/BasicString.class.h create mode 100644 Source/Library/Common/Bitset.class.cpp create mode 100644 Source/Library/Common/Bitset.class.h create mode 100644 Source/Library/Common/ByteArray.class.cpp create mode 100644 Source/Library/Common/ByteArray.class.h create mode 100644 Source/Library/Common/CMem.ns.cpp create mode 100644 Source/Library/Common/CMem.ns.h create mode 100644 Source/Library/Common/OrderedArray.class.cpp create mode 100644 Source/Library/Common/OrderedArray.class.h create mode 100644 Source/Library/Common/Rand.ns.cpp create mode 100644 Source/Library/Common/Rand.ns.h create mode 100644 Source/Library/Common/SimpleList.class.h create mode 100644 Source/Library/Common/String.class.cpp create mode 100644 Source/Library/Common/String.class.h create mode 100644 Source/Library/Common/Vector.class.cpp create mode 100644 Source/Library/Common/Vector.class.h create mode 100644 Source/Library/Common/WChar.class.cpp create mode 100644 Source/Library/Common/WChar.class.h create mode 100644 Source/Library/Common/types.h (limited to 'Source/Library/Common') 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 + +#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 +BasicString::BasicString() { + m_string = NULL; + m_length = 0; +} + +template +BasicString::BasicString(const T* string, u32int length) { + m_string = NULL; + affect(string, length); +} + +template +BasicString::BasicString(const BasicString &other) { + m_string = NULL; + affect(other); +} + +template +BasicString::BasicString(const T value, u32int count) { + m_string = NULL; + affect(value, count); +} + +template +BasicString::~BasicString() { + FREE; +} + +template +void BasicString::affect(const BasicString &other) { + FREE; + m_length = other.m_length; + VRFY; + ALLOC; + memcpy((u8int*)m_string, (u8int*)(other.m_string), m_length * sizeof(T)); +} + +template +void BasicString::affect(const T* string, u32int length) { + FREE; + m_length = length; + VRFY; + ALLOC; + memcpy((u8int*)string, (u8int*)string, m_length * sizeof(T)); +} + +template +void BasicString::affect(const T value, u32int count) { + FREE; + m_length = count; + VRFY; + ALLOC; + for (u32int i = 0; i < count; i++) { + m_string[i] = value; + } +} + +template +bool BasicString::compare(const BasicString &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 +bool BasicString::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 +BasicString &BasicString::append(const BasicString &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 +BasicString &BasicString::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 +BasicString &BasicString::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 +BasicString BasicString::concat(const BasicString &other) const { + BasicString ret(*this); + return (ret.append(other)); +} + +template +BasicString BasicString::concat(const T* string, u32int length) const { + BasicString ret(*this); + return (ret.append(string, length)); +} + +template +BasicString BasicString::concat(const T other) const { + BasicString ret(*this); + return (ret.append(other)); +} + +template +void BasicString::clear() { + FREE; + m_string = 0; + m_length = 0; +} + +template +Vector< BasicString > BasicString::split(T sep) const { + Vector< BasicString > ret; + ret.push(BasicString()); + for (u32int i = 0; i < m_length; i++) { + if (m_string[i] == sep) { + ret.push(BasicString()); + } else { + ret.back().append(m_string[i]); + } + } + return ret; +} + +template +BasicString BasicString::substr(s32int start, u32int size) { + if (start < 0) start = m_length - start; + BasicString 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 + +template class Vector; + +template +class BasicString { + protected: + T *m_string; + u32int m_length; + + public: + BasicString(); + BasicString(const T* string, u32int length); + BasicString(const BasicString &other); + BasicString(const T, u32int count = 1); + virtual ~BasicString(); + + void affect(const BasicString &other); + void affect(const T* string, u32int length); + void affect(const T value, u32int count = 1); + void operator= (const BasicString &other) { affect(other); } + + bool compare(const BasicString &other) const; + bool compare(const T* string, u32int length) const; + bool operator== (const BasicString &other) const { return compare(other); } + bool operator!= (const BasicString &other) const { return !compare(other); } + + BasicString& append(const BasicString &other); + BasicString& append(const T* string, u32int length); + BasicString& append(const T other); + BasicString& operator+= (const BasicString &other) { return append(other); } + BasicString& operator+= (const T other) { return append(other); } + + BasicString concat(const BasicString &other) const; + BasicString concat(const T* string, u32int length) const; + BasicString 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 > split(T sep) const; + BasicString 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 + +#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() { + 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 + +class ByteArray : public BasicString { + public: + ByteArray() : BasicString() {} + ByteArray(const BasicString &bs) : BasicString() { + 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(other) {} + ByteArray(const char* c); + ByteArray(u32int size) : BasicString((u8int)0, size) {} + ByteArray(const String &string, u8int encoding = UE_UTF8) : BasicString() { 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 + +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 +OrderedArray::OrderedArray(u32int max_size) { + m_array = (T*)Memory::alloc(max_size * sizeof(T*)); + m_size = 0; + m_maxSize = max_size; +} + +template +OrderedArray::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 +OrderedArray::~OrderedArray() { + //Free memory +} + +template +void OrderedArray::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 +T *OrderedArray::lookup(int index) { + return m_array[index]; +} + +template +void OrderedArray::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 + +template +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 + +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 +class SimpleList { + protected: + T m_value; + SimpleList* m_next; + + public: + SimpleList(const T& value, SimpleList* 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* cons(const T& value) { + return new SimpleList(value, this); + } + + SimpleList* next() { + return m_next; + } + + SimpleList* last() { + if (m_next == 0) return this; + return m_next->last(); + } + + SimpleList* delThis() { + SimpleList* ret = m_next; + Mem::kfree(this); + return ret; + } + + void delNext() { + if (m_next == 0) return; + SimpleList* temp = m_next; + m_next = m_next->m_next; + Mem::kfree(temp); + } + + SimpleList* removeOnce(const T& value) { + if (value == m_value) return delThis(); + for (SimpleList *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 + +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::split(WChar c) const { + Vector 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 +#include + +class String : public BasicString { + public: + static String hex(u32int number); + static String number(s32int number); + + String(const char* string, u8int encoding = UE_UTF8); + String() : BasicString() {} + String(const String &other) : BasicString (other) {} + + void affect(const char* string, u8int encoding = UE_UTF8); + void operator= (const char* other) { affect(other); } + void operator= (const String& other) { BasicString::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::compare(other); } + bool operator!= (const String& other) const { return !BasicString::compare(other); } + + String& append(const char* other, u8int encoding = UE_UTF8); + String &operator+= (const String &other) { BasicString::append(other); return *this; } + String &operator+= (const char* other) { return append(other); } + String &operator+= (WChar other) { BasicString::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 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 +Vector::Vector() { + //DEBUG_HEX((u32int)this); DEBUG(" NEW EMPTY"); + //DEBUG_HEX(sizeof(T)); DEBUG(" sizeof(T)"); + m_data = 0; + m_size = 0; +} + +template +Vector::Vector(u32int size) { + //DEBUG_HEX((u32int)this); DEBUG(" NEW ZERO"); + m_data = new T[size]; + m_size = size; +} + +template +Vector::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 +Vector::Vector(const Vector &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 +Vector& Vector::operator= (const Vector &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 +Vector::~Vector() { + //DEBUG_HEX((u32int)this); DEBUG(" DELETE"); + DELDATA; + //if (m_data != 0) delete[] m_data; +} + +template +T& Vector::operator[] (u32int index) const { + return m_data[index]; +} + +template +void Vector::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 +void Vector::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 +void Vector::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 +T& Vector::back() const { + return m_data[m_size - 1]; +} + +template +T& Vector::front() const { + return m_data[0]; +} + + +template +u32int Vector::size() const { + return m_size; +} + +template +bool Vector::empty() const { + return m_size == 0; +} + +template +void Vector::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 + +template +class Vector { + private: + T *m_data; + u32int m_size; + + public: + Vector(); + Vector(u32int size); + Vector(u32int size, const T& value); + Vector(const Vector &other); + Vector& operator= (const Vector &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 + +#ifndef THIS_IS_NOT_MELON +#include +#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 -- cgit v1.2.3 From e589a45295a871f38d4a1d1f23b370b612f99be5 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 17:17:36 +0200 Subject: Syscall interface starts being implemented ! --- Source/Library/Common/SimpleList.class.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'Source/Library/Common') diff --git a/Source/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h index 64e37aa..3e0f968 100644 --- a/Source/Library/Common/SimpleList.class.h +++ b/Source/Library/Common/SimpleList.class.h @@ -1,6 +1,8 @@ #ifndef DEF_SIMPLELIST_CLASS_H #define DEF_SIMPLELIST_CLASS_H +#include + /* This class implements a singly linked list. It is also used to represent one of its elements. */ template -- cgit v1.2.3 From ccf807eb4ff541bb849c4f370d34123cb23d7d76 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 18:39:52 +0200 Subject: Heap included as well in userland library --- Source/Library/Common/Heap-index.class.cpp | 51 +++++++ Source/Library/Common/Heap.class.cpp | 232 +++++++++++++++++++++++++++++ Source/Library/Common/Heap.class.h | 92 ++++++++++++ Source/Library/Common/Mutex.class.cpp | 45 ++++++ Source/Library/Common/Mutex.class.h | 21 +++ 5 files changed, 441 insertions(+) create mode 100644 Source/Library/Common/Heap-index.class.cpp create mode 100644 Source/Library/Common/Heap.class.cpp create mode 100644 Source/Library/Common/Heap.class.h create mode 100644 Source/Library/Common/Mutex.class.cpp create mode 100644 Source/Library/Common/Mutex.class.h (limited to 'Source/Library/Common') 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 +#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 +#include + +//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 +#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 +#endif + +#ifdef THIS_IS_MELON_USERLAND +#include +#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 + +#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 -- cgit v1.2.3 From 776753bfa0c411f4b1a5680409104904961fcbeb Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 18:46:59 +0200 Subject: Mem::kalloc and Mem::kfree renamed to Mem::alloc and Mem::kfree I renamed them so that they could have the same name in userland and in kernel space. We'll just know that if we're writing kernel code then we are allocating stuff in kernel memory, and if we're writing user code then we're allocating userland memory. --- Source/Library/Common/Bitset.class.cpp | 4 ++-- Source/Library/Common/SimpleList.class.h | 4 ++-- Source/Library/Common/Vector.class.cpp | 16 ++++++++-------- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'Source/Library/Common') diff --git a/Source/Library/Common/Bitset.class.cpp b/Source/Library/Common/Bitset.class.cpp index ec4e62c..a8d7ec8 100644 --- a/Source/Library/Common/Bitset.class.cpp +++ b/Source/Library/Common/Bitset.class.cpp @@ -4,7 +4,7 @@ Bitset::Bitset() { } Bitset::Bitset(u32int size) { - init(size, (u32int*)Mem::kalloc(INDEX_FROM_BIT(size))); + init(size, (u32int*)Mem::alloc(INDEX_FROM_BIT(size))); } Bitset::Bitset(u32int size, u32int *ptr) { @@ -12,7 +12,7 @@ Bitset::Bitset(u32int size, u32int *ptr) { } Bitset::~Bitset() { - Mem::kfree(m_data); + Mem::free(m_data); } void Bitset::init(u32int size, u32int *ptr) { diff --git a/Source/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h index 3e0f968..7b731db 100644 --- a/Source/Library/Common/SimpleList.class.h +++ b/Source/Library/Common/SimpleList.class.h @@ -36,7 +36,7 @@ class SimpleList { SimpleList* delThis() { SimpleList* ret = m_next; - Mem::kfree(this); + Mem::free(this); return ret; } @@ -44,7 +44,7 @@ class SimpleList { if (m_next == 0) return; SimpleList* temp = m_next; m_next = m_next->m_next; - Mem::kfree(temp); + Mem::free(temp); } SimpleList* removeOnce(const T& value) { diff --git a/Source/Library/Common/Vector.class.cpp b/Source/Library/Common/Vector.class.cpp index 02ae9be..c546a42 100644 --- a/Source/Library/Common/Vector.class.cpp +++ b/Source/Library/Common/Vector.class.cpp @@ -4,7 +4,7 @@ using namespace CMem; //strlen and memcpy for (u32int i = 0; i < m_size; i++) { \ m_data[i].~T(); \ } \ - Mem::kfree(m_data); \ + Mem::free(m_data); \ } template @@ -25,7 +25,7 @@ Vector::Vector(u32int size) { template Vector::Vector(u32int size, const T& value) { //DEBUG_HEX((u32int)this); DEBUG(" NEW FILLED"); - //m_data = (T*)Mem::kalloc(size * sizeof(T)); + //m_data = (T*)Mem::alloc(size * sizeof(T)); m_data = new T[size]; m_size = size; for (u32int i = 0; i < m_size; i++) { @@ -40,7 +40,7 @@ template Vector::Vector(const Vector &other) { //DEBUG_HEX((u32int)this); DEBUG(" COPY REF"); m_size = other.m_size; - m_data = (T*)Mem::kalloc(m_size * sizeof(T)); + 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]); } @@ -51,7 +51,7 @@ Vector& Vector::operator= (const Vector &other) { //DEBUG_HEX((u32int)this); DEBUG(" COPY EQ"); DELDATA; m_size = other.m_size; - m_data = (T*)Mem::kalloc(m_size * sizeof(T)); + 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]); } @@ -72,14 +72,14 @@ T& Vector::operator[] (u32int index) const { template void Vector::push(const T& element) { - T* newdata = (T*)Mem::kalloc((m_size + 1) * sizeof(T)); + 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::kfree(m_data); + Mem::free(m_data); m_data = newdata; } @@ -99,9 +99,9 @@ void Vector::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)); + T* newdata = (T*)Mem::alloc(m_size * sizeof(T)); memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T)); - Mem::kfree(m_data); + Mem::free(m_data); m_data = newdata; } -- cgit v1.2.3 From 0cca2d68451849b5ea96a3620566fd0b42dde3c0 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 21:56:26 +0200 Subject: More work on syscalls --- Source/Library/Common/String.class.cpp | 20 ++++++++++++++++++++ Source/Library/Common/String.class.h | 5 ++++- 2 files changed, 24 insertions(+), 1 deletion(-) (limited to 'Source/Library/Common') diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp index d8913d9..c217807 100644 --- a/Source/Library/Common/String.class.cpp +++ b/Source/Library/Common/String.class.cpp @@ -49,6 +49,26 @@ String String::number(s32int number) { 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() { + 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; diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h index 3e50d35..5db9858 100644 --- a/Source/Library/Common/String.class.h +++ b/Source/Library/Common/String.class.h @@ -9,6 +9,9 @@ class String : public BasicString { static String hex(u32int number); static String number(s32int number); + static String unserialize(u32int w); + u32int serialize(); + String(const char* string, u8int encoding = UE_UTF8); String() : BasicString() {} String(const String &other) : BasicString (other) {} @@ -34,7 +37,7 @@ class String : public BasicString { 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 -- cgit v1.2.3 From 9836acd720988af30250c2c1ec18d618664dea4e Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 20 Oct 2009 19:21:34 +0200 Subject: Started working on a userland shell This means I'll have to do syscalls for everything I need. --- Source/Library/Common/String.class.cpp | 2 +- Source/Library/Common/String.class.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Library/Common') diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp index c217807..ac0eba0 100644 --- a/Source/Library/Common/String.class.cpp +++ b/Source/Library/Common/String.class.cpp @@ -60,7 +60,7 @@ String String::unserialize(u32int w) { return ret; } -u32int String::serialize() { +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++) { diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h index 5db9858..0d48ce6 100644 --- a/Source/Library/Common/String.class.h +++ b/Source/Library/Common/String.class.h @@ -10,7 +10,7 @@ class String : public BasicString { static String number(s32int number); static String unserialize(u32int w); - u32int serialize(); + u32int serialize() const; String(const char* string, u8int encoding = UE_UTF8); String() : BasicString() {} -- cgit v1.2.3