| @@ -95,6 +95,13 @@ public: | |||||
| return ((Super const &)*this).Count() - 1; | return ((Super const &)*this).Count() - 1; | ||||
| } | } | ||||
| /* Return a C string */ | |||||
| inline char const *C() const | |||||
| { | |||||
| return &(*this)[0]; | |||||
| } | |||||
| /* Does not initialise the newly allocated characters */ | |||||
| void Resize(int count) | void Resize(int count) | ||||
| { | { | ||||
| ASSERT(count >= 0); | ASSERT(count >= 0); | ||||
| @@ -20,6 +20,7 @@ namespace lol | |||||
| template<typename T> class Atomic | template<typename T> class Atomic | ||||
| { | { | ||||
| public: | public: | ||||
| inline Atomic() : m_value(0) {} | |||||
| inline Atomic(T const &value) : m_value(value) {} | inline Atomic(T const &value) : m_value(value) {} | ||||
| operator T() const | operator T() const | ||||
| @@ -42,7 +43,7 @@ public: | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| inline T& operator++() | |||||
| inline T operator++() | |||||
| { | { | ||||
| m_mutex.Lock(); | m_mutex.Lock(); | ||||
| T ret = ++m_value; | T ret = ++m_value; | ||||
| @@ -58,7 +59,7 @@ public: | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| inline T& operator--() | |||||
| inline T operator--() | |||||
| { | { | ||||
| m_mutex.Lock(); | m_mutex.Lock(); | ||||
| T ret = --m_value; | T ret = --m_value; | ||||
| @@ -37,11 +37,13 @@ struct FileAccess | |||||
| class File | class File | ||||
| { | { | ||||
| public: | public: | ||||
| inline File() : m_data(0) {} | |||||
| inline ~File() {} | |||||
| File(); | |||||
| File(File const &that); | |||||
| File &operator =(File const &that); | |||||
| ~File(); | |||||
| void Open(String const &file, FileAccess mode); | void Open(String const &file, FileAccess mode); | ||||
| String const &ReadString(); | |||||
| String ReadString(); | |||||
| void Close(); | void Close(); | ||||
| private: | private: | ||||
| @@ -21,7 +21,100 @@ class FileData | |||||
| { | { | ||||
| friend class File; | friend class File; | ||||
| void Open(String const &file, FileAccess mode) | |||||
| { | |||||
| #if HAVE_STDIO_H | |||||
| /* FIXME: no modes, no error checking, no nothing */ | |||||
| m_fd = fopen(file.C(), "r"); | |||||
| #endif | |||||
| } | |||||
| String ReadString() | |||||
| { | |||||
| String ret; | |||||
| #if HAVE_STDIO_H | |||||
| while (!feof(m_fd)) | |||||
| { | |||||
| char buf[BUFSIZ]; | |||||
| size_t count = fread(buf, 1, BUFSIZ, m_fd); | |||||
| if (count <= 0) | |||||
| break; | |||||
| int oldsize = ret.Count(); | |||||
| ret.Resize(oldsize + count); | |||||
| memcpy(&ret[oldsize], buf, count); | |||||
| } | |||||
| #endif | |||||
| return ret; | |||||
| } | |||||
| void Close() | |||||
| { | |||||
| #if HAVE_STDIO_H | |||||
| fclose(m_fd); | |||||
| #endif | |||||
| } | |||||
| #if HAVE_STDIO_H | |||||
| FILE *m_fd; | |||||
| #endif | |||||
| Atomic<int> m_refcount; | |||||
| }; | }; | ||||
| File::File() | |||||
| : m_data(new FileData) | |||||
| { | |||||
| ++m_data->m_refcount; | |||||
| } | |||||
| File::File(File const &that) | |||||
| : m_data(that.m_data) | |||||
| { | |||||
| ++m_data->m_refcount; | |||||
| } | |||||
| File &File::operator =(File const &that) | |||||
| { | |||||
| if (this == &that) | |||||
| return *this; | |||||
| int refcount = --m_data->m_refcount; | |||||
| if (refcount == 0) | |||||
| { | |||||
| m_data->Close(); | |||||
| delete m_data; | |||||
| } | |||||
| m_data = that.m_data; | |||||
| ++m_data->m_refcount; | |||||
| return *this; | |||||
| } | |||||
| File::~File() | |||||
| { | |||||
| int refcount = --m_data->m_refcount; | |||||
| if (refcount == 0) | |||||
| { | |||||
| m_data->Close(); | |||||
| delete m_data; | |||||
| } | |||||
| } | |||||
| void File::Open(String const &file, FileAccess mode) | |||||
| { | |||||
| return m_data->Open(file, mode); | |||||
| } | |||||
| String File::ReadString() | |||||
| { | |||||
| return m_data->ReadString(); | |||||
| } | |||||
| void File::Close() | |||||
| { | |||||
| m_data->Close(); | |||||
| } | |||||
| } /* namespace lol */ | } /* namespace lol */ | ||||