@@ -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) {} | File(); | ||||
inline ~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 */ | ||||