#ifndef _NORM_FILE
#define _NORM_FILE
#ifdef WIN32
#else
#include <unistd.h>
#include <dirent.h>
#endif
#ifdef _WIN32_WCE
#include <stdio.h>
#else
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include "protokit.h"
#ifdef _WIN32_WCE
enum
{
O_CREAT = 0x01,
O_TRUNC = 0x02,
O_RDONLY = 0x04,
O_WRONLY = 0x08,
O_RDWR = 0x10,
O_BINARY = 0x20
};
#endif
class NormFile
{
public:
#ifdef WIN32
typedef __int64 Offset;
#else
typedef off_t Offset;
#endif enum Type {INVALID, NORMAL, DIRECTORY};
NormFile();
~NormFile();
bool Open(const char* path, int theFlags);
bool Lock();
void Unlock();
bool Rename(const char* oldName, const char* newName);
static bool Unlink(const char *path);
void Close();
bool IsOpen() const
{
#ifdef _WIN32_WCE
return (NULL != file_ptr);
#else
return (fd >= 0);
#endif }
size_t Read(char* buffer, size_t len);
size_t Write(const char* buffer, size_t len);
bool Seek(Offset theOffset);
NormFile::Offset GetOffset() const {return (offset);}
NormFile::Offset GetSize() const;
bool Pad(Offset theOffset);
static NormFile::Type GetType(const char *path);
static NormFile::Offset GetSize(const char* path);
static time_t GetUpdateTime(const char* path);
static bool IsLocked(const char *path);
static bool Exists(const char* path)
{
#ifdef WIN32
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
size_t count = mbstowcs(wideBuffer, path, strlen(path)+1);
return (0xFFFFFFFF != GetFileAttributes(wideBuffer));
#else
return (0xFFFFFFFF != GetFileAttributes(path));
#endif #else
return (0 == access(path, F_OK));
#endif }
static bool IsWritable(const char* path)
{
#ifdef WIN32
#ifdef _UNICODE
wchar_t wideBuffer[MAX_PATH];
size_t count = mbstowcs(wideBuffer, path, strlen(path)+1);
DWORD attr = GetFileAttributes(wideBuffer);
#else
DWORD attr = GetFileAttributes(path);
#endif return ((0xFFFFFFFF == attr) ?
false : (0 == (attr & FILE_ATTRIBUTE_READONLY)));
#else
return (0 == access(path, W_OK));
#endif }
#ifdef _WIN32_WCE
FILE* file_ptr;
#else
int fd;
#endif int flags;
#ifdef WIN32
__int64 offset;
#else
off_t offset;
#endif };
class NormDirectoryIterator
{
public:
NormDirectoryIterator();
~NormDirectoryIterator();
bool Open(const char*thePath);
void Close();
bool GetPath(char* pathBuffer);
bool GetNextFile(char* buffer);
private:
class NormDirectory
{
friend class NormDirectoryIterator;
private:
char path[PATH_MAX];
NormDirectory* parent;
#ifdef WIN32
HANDLE hSearch;
#else
DIR* dptr;
#endif NormDirectory(const char *thePath, NormDirectory* theParent = NULL);
~NormDirectory();
void GetFullName(char* namePtr);
bool Open();
void Close();
const char* Path() const {return path;}
void RecursiveCatName(char* ptr);
};
NormDirectory* current;
int path_len;
};
class NormFileList
{
public:
NormFileList();
~NormFileList();
void Destroy();
bool IsEmpty() {return (NULL == head);}
void ResetIterator()
{
last_time = this_time;
this_time = big_time;
next = NULL;
reset = true;
}
void InitUpdateTime(bool updatesOnly, time_t initTime = 0)
{
updates_only = updatesOnly;
last_time = this_time = big_time = initTime;
if (0 == initTime)
{
struct timeval currentTime;
ProtoSystemTime(currentTime);
this_time = currentTime.tv_sec;
}
}
bool Append(const char* path);
bool Remove(const char* path);
bool GetNextFile(char* pathBuffer);
void GetCurrentBasePath(char* pathBuffer);
private:
class FileItem
{
friend class NormFileList;
public:
FileItem(const char* thePath);
virtual ~FileItem();
NormFile::Type GetType() {return NormFile::GetType(path);}
NormFile::Offset Size() const {return size;}
virtual bool GetNextFile(char* thePath,
bool reset,
bool updatesOnly,
time_t lastTime,
time_t thisTime,
time_t& bigTime);
protected:
const char* Path() {return path;}
char path[PATH_MAX];
NormFile::Offset size;
FileItem* prev;
FileItem* next;
};
class DirectoryItem : public FileItem
{
friend class NormFileList;
public:
DirectoryItem(const char* thePath);
~DirectoryItem();
virtual bool GetNextFile(char* thePath,
bool reset,
bool updatesOnly,
time_t lastTime,
time_t thisTime,
time_t& bigTime);
private:
NormDirectoryIterator diterator;
};
time_t this_time;
time_t big_time;
time_t last_time;
bool updates_only;
FileItem* head;
FileItem* tail;
FileItem* next;
bool reset;
};
#endif