跨平臺編程之Windows模擬Linux dirent API

跨平臺編程之Windows模擬Linux opendir / readdir 函數

Windows下模擬Linux opendir, readdir, closedir函數

#include <stdio.h>
#ifdef _MSC_VER
#include <memory>
#include <io.h>
#include <windows.h>
#include <tchar.h> 
#include <strsafe.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <vector>
#include <unistd.h>
#include <dirent.h>

#ifdef _MSC_VER

typedef struct dirent
{
#ifndef __USE_FILE_OFFSET64
	__ino_t d_ino;
	__off_t d_off;
#else
	__ino64_t d_ino;
	__off64_t d_off;
#endif
	unsigned short int d_reclen;
	unsigned char d_type;
	char d_name[256];		/* We must not include limits.h! */
} dirent_t;


class dirs_container_t
{
public:
	dirs_container_t(int placeholder)
		: hFind(INVALID_HANDLE_VALUE)
		, readdirInvokedCount(0x00)
	{
		placeholder++;
	}
	~dirs_container_t() {
	}
public:
	DIR * opendir (const char * __name)
	{
		DWORD dwError=0;
		StringCchCopy(szDir, MAX_PATH, __name);
		StringCchCat(szDir, MAX_PATH, TEXT("\\*"));
		hFind = FindFirstFile(szDir, &ffd);

		if (INVALID_HANDLE_VALUE == hFind) {
			return (DIR *)INVALID_HANDLE_VALUE;
		} 
		return (DIR *)hFind;
	}
	struct dirent * readdir (DIR *__dirp)
	{
		while (__dirp == hFind) {
			if (readdirInvokedCount) {
				if (FindNextFile(hFind, &ffd) == 0) {
					return NULL;
				}
			}
			
			readdirInvokedCount++;

			if (ffd.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)) {
				;
			} else {
				//filesize.LowPart  = ffd.nFileSizeLow;
				//filesize.HighPart = ffd.nFileSizeHigh;
				//_tprintf(TEXT("  %s   %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
				entry_.d_name[sizeof(entry_.d_name) - 1] = '\0';
				entry_.d_type = DT_REG;
				strncpy(entry_.d_name, ffd.cFileName, sizeof(entry_.d_name) - 1);

				return &entry_;
			}
		}
		return NULL;
	}
	int closedir (DIR *__dirp)
	{
		if (__dirp == hFind) {
			FindClose(hFind);
		}
		return 0;
	}
private:
	struct  dirent  entry_;
	int		readdirInvokedCount;
	HANDLE  hFind;
	WIN32_FIND_DATA ffd;
	LARGE_INTEGER filesize;
	TCHAR szDir[MAX_PATH]; 
};


class dirs_container_t_loader {
public:
	dirs_container_t_loader() {};
	~dirs_container_t_loader() {
		if (NULL != getInstance()) { delete getInstance(); }
	};
	static dirs_container_t * getInstance(void) {
		static dirs_container_t * g_sema_container_obj = NULL; //(8888);
		if (NULL == g_sema_container_obj) { g_sema_container_obj = new dirs_container_t(8888); }
		return g_sema_container_obj;
	}
};

DIR * opendir (const char * __name)
{
	return dirs_container_t_loader::getInstance()->opendir(__name);
}

struct dirent * readdir (DIR *__dirp)
{
	return dirs_container_t_loader::getInstance()->readdir(__dirp);
}

int closedir (DIR *__dirp)
{
	return dirs_container_t_loader::getInstance()->closedir(__dirp);
}

#endif	/* _MSC_VER */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章