#ifndef _NPT_FILE_H_
#define _NPT_FILE_H_
#include "NptTypes.h"
#include "NptStreams.h"
#include "NptTime.h"
const int NPT_ERROR_NO_SUCH_FILE = NPT_ERROR_BASE_FILE - 0;
const int NPT_ERROR_FILE_NOT_OPEN = NPT_ERROR_BASE_FILE - 1;
const int NPT_ERROR_FILE_BUSY = NPT_ERROR_BASE_FILE - 2;
const int NPT_ERROR_FILE_ALREADY_OPEN = NPT_ERROR_BASE_FILE - 3;
const int NPT_ERROR_FILE_NOT_READABLE = NPT_ERROR_BASE_FILE - 4;
const int NPT_ERROR_FILE_NOT_WRITABLE = NPT_ERROR_BASE_FILE - 5;
const int NPT_ERROR_FILE_NOT_DIRECTORY = NPT_ERROR_BASE_FILE - 6;
const int NPT_ERROR_FILE_ALREADY_EXISTS = NPT_ERROR_BASE_FILE - 7;
const int NPT_ERROR_FILE_NOT_ENOUGH_SPACE = NPT_ERROR_BASE_FILE - 8;
const int NPT_ERROR_DIRECTORY_NOT_EMPTY = NPT_ERROR_BASE_FILE - 9;
const unsigned int NPT_FILE_OPEN_MODE_READ = 0x01;
const unsigned int NPT_FILE_OPEN_MODE_WRITE = 0x02;
const unsigned int NPT_FILE_OPEN_MODE_CREATE = 0x04;
const unsigned int NPT_FILE_OPEN_MODE_TRUNCATE = 0x08;
const unsigned int NPT_FILE_OPEN_MODE_UNBUFFERED = 0x10;
const unsigned int NPT_FILE_OPEN_MODE_APPEND = 0x20;
const unsigned int NPT_FILE_ATTRIBUTE_READ_ONLY = 0x01;
const unsigned int NPT_FILE_ATTRIBUTE_LINK = 0x02;
#define NPT_FILE_STANDARD_INPUT "@STDIN"
#define NPT_FILE_STANDARD_OUTPUT "@STDOUT"
#define NPT_FILE_STANDARD_ERROR "@STDERR"
class NPT_DataBuffer;
struct NPT_FileInfo
{
typedef enum {
FILE_TYPE_NONE,
FILE_TYPE_REGULAR,
FILE_TYPE_DIRECTORY,
FILE_TYPE_SPECIAL,
FILE_TYPE_OTHER
} FileType;
NPT_FileInfo() : m_Type(FILE_TYPE_NONE), m_Size(0), m_AttributesMask(0), m_Attributes(0) {}
FileType m_Type;
NPT_UInt64 m_Size;
NPT_Flags m_AttributesMask;
NPT_Flags m_Attributes;
NPT_TimeStamp m_CreationTime;
NPT_TimeStamp m_ModificationTime;
};
class NPT_FilePath
{
public:
static const char* const Separator;
static NPT_String BaseName(const char* path, bool with_extension = true);
static NPT_String DirName(const char* path);
static NPT_String FileExtension(const char* path);
static NPT_String Create(const char* directory, const char* base);
private:
NPT_FilePath() {}
};
class NPT_FileInterface
{
public:
typedef unsigned int OpenMode;
virtual ~NPT_FileInterface() {}
virtual NPT_Result Open(OpenMode mode) = 0;
virtual NPT_Result Close() = 0;
virtual NPT_Result GetInputStream(NPT_InputStreamReference& stream) = 0;
virtual NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) = 0;
};
class NPT_File : public NPT_FileInterface
{
public:
static NPT_Result GetRoots(NPT_List<NPT_String>& roots);
static NPT_Result GetSize(const char* path, NPT_LargeSize &size);
static NPT_Result GetInfo(const char* path, NPT_FileInfo* info = NULL);
static bool Exists(const char* path) { return NPT_SUCCEEDED(GetInfo(path)); }
static NPT_Result Remove(const char* path, bool recurse = false);
static NPT_Result RemoveFile(const char* path);
static NPT_Result RemoveDir(const char* path);
static NPT_Result RemoveDir(const char* path, bool force_if_not_empty);
static NPT_Result Rename(const char* from_path, const char* to_path);
static NPT_Result ListDir(const char* path, NPT_List<NPT_String>& entries, NPT_Ordinal start = 0, NPT_Cardinal count = 0);
static NPT_Result CreateDir(const char* path);
static NPT_Result CreateDir(const char* path, bool create_intermediate_dirs);
static NPT_Result GetWorkingDir(NPT_String& path);
static NPT_Result Load(const char* path, NPT_DataBuffer& buffer, NPT_FileInterface::OpenMode mode = NPT_FILE_OPEN_MODE_READ);
static NPT_Result Load(const char* path, NPT_String& data, NPT_FileInterface::OpenMode mode = NPT_FILE_OPEN_MODE_READ);
static NPT_Result Save(const char* path, NPT_String& data);
static NPT_Result Save(const char* path, const NPT_DataBuffer& buffer);
NPT_File(const char* path);
~NPT_File() { delete m_Delegate; }
NPT_Result Load(NPT_DataBuffer& buffer);
NPT_Result Save(const NPT_DataBuffer& buffer);
const NPT_String& GetPath() { return m_Path; }
NPT_Result GetSize(NPT_LargeSize &size);
NPT_Result GetInfo(NPT_FileInfo& info);
NPT_Result ListDir(NPT_List<NPT_String>& entries);
NPT_Result Rename(const char* path);
NPT_Result Open(OpenMode mode) {
return m_Delegate->Open(mode);
}
NPT_Result Close() {
return m_Delegate->Close();
}
NPT_Result GetInputStream(NPT_InputStreamReference& stream) {
return m_Delegate->GetInputStream(stream);
}
NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) {
return m_Delegate->GetOutputStream(stream);
}
NPT_File& operator=(const NPT_File& file);
protected:
NPT_FileInterface* m_Delegate;
NPT_String m_Path;
bool m_IsSpecial;
};
class NPT_FileDateComparator {
public:
NPT_FileDateComparator(const char* directory) : m_Directory(directory) {}
NPT_Int32 operator()(const NPT_String& file1, const NPT_String& file2) const {
NPT_FileInfo info1, info2;
if (NPT_FAILED(NPT_File::GetInfo(NPT_FilePath::Create(m_Directory, file1), &info1))) return -1;
if (NPT_FAILED(NPT_File::GetInfo(NPT_FilePath::Create(m_Directory, file2), &info2))) return -1;
return (info1.m_ModificationTime == info2.m_ModificationTime) ? 0 : (info1.m_ModificationTime < info2.m_ModificationTime ? -1 : 1);
}
private:
NPT_String m_Directory;
};
#endif