Пример #1
0
static FILE * fopen_utf8(const char * path, const char * mode)
{
    wchar_t * pathW = utf8_to_widechar(path);
    wchar_t * modeW = utf8_to_widechar(mode);
    FILE * file = _wfopen(pathW, modeW);
    free(pathW);
    free(modeW);
    return file;
}
Пример #2
0
int platform_enumerate_directories_begin(const utf8 *directory)
{
	enumerate_file_info *enumFileInfo;
	wchar_t *wpattern = utf8_to_widechar(directory);
	int length = min(utf8_length(directory), MAX_PATH);
	char *npattern = malloc(length+1);
	int converted;
	converted = wcstombs(npattern, wpattern, length);
	npattern[length - 1] = '\0';
	if (converted == MAX_PATH) {
		log_warning("truncated string %s", npattern);
	}
	log_verbose("begin directory listing, path: %s", npattern);

	// TODO: add some checking for stringness and directoryness

	int cnt;
	for (int i = 0; i < countof(_enumerateFileInfoList); i++) {
		enumFileInfo = &_enumerateFileInfoList[i];
		if (!enumFileInfo->active) {
			safe_strcpy(enumFileInfo->pattern, npattern, length);
			cnt = scandir(npattern, &enumFileInfo->fileListTemp, dirfilter, alphasort);
			if (cnt < 0)
			{
				break;
			}
			log_verbose("found %d files in dir '%s'", cnt, npattern);
			enumFileInfo->cnt = cnt;
			enumFileInfo->paths = malloc(cnt * sizeof(char *));
			char **paths = enumFileInfo->paths;
			// 256 is size of dirent.d_name
			const int buf_len = min(MAX_PATH, 256);
			const int dir_name_len = strnlen(npattern, MAX_PATH);
			char separator[] = {platform_get_path_separator(), 0};
			for (int idx = 0; idx < cnt; idx++)
			{
				struct dirent *d = enumFileInfo->fileListTemp[idx];
				const int entry_len = strnlen(d->d_name, MAX_PATH);
				// 1 for separator, 1 for trailing null
				size_t path_len = sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2);
				paths[idx] = malloc(path_len);
				paths[idx][0] = '\0';
				log_verbose("dir_name: %s", npattern);
				strncat(paths[idx], npattern, path_len - 2);
				strncat(paths[idx], separator, path_len - strnlen(paths[idx], path_len) - 1);
				strncat(paths[idx], d->d_name, path_len - strnlen(paths[idx], path_len) - 1);
				log_verbose("paths[%d] = %s", idx, paths[idx]);
			}
			enumFileInfo->handle = 0;
			enumFileInfo->active = 1;
			free(wpattern);
			free(npattern);
			return i;
		}
	}

	free(wpattern);
	free(npattern);
	return -1;
}
Пример #3
0
    FileStream(const utf8 * path, sint32 fileMode)
    {
        const char * mode;
        switch (fileMode) {
        case FILE_MODE_OPEN:
            mode = "rb";
            _canRead = true;
            _canWrite = false;
            break;
        case FILE_MODE_WRITE:
            mode = "w+b";
            _canRead = true;
            _canWrite = true;
            break;
        case FILE_MODE_APPEND:
            mode = "a";
            _canRead = false;
            _canWrite = true;
            break;
        default:
            throw;
        }

#ifdef _WIN32
        wchar_t * pathW = utf8_to_widechar(path);
        wchar_t * modeW = utf8_to_widechar(mode);
        _file = _wfopen(pathW, modeW);
        free(pathW);
        free(modeW);
#else
        _file = fopen(path, mode);
#endif
        if (_file == nullptr)
        {
            throw IOException(String::StdFormat("Unable to open '%s'", path));
        }

        Seek(0, STREAM_SEEK_END);
        _fileSize = GetPosition();
        Seek(0, STREAM_SEEK_BEGIN);

        _ownsFilePtr = true;
    }
Пример #4
0
static std::wstring GetDumpDirectory()
{
    char userDirectory[MAX_PATH];
    platform_get_user_directory(userDirectory, NULL, sizeof(userDirectory));

    wchar_t * userDirectoryW = utf8_to_widechar(userDirectory);
    auto result = std::wstring(userDirectoryW);
    free(userDirectoryW);

    return result;
}
Пример #5
0
bool platform_file_exists(const utf8 *path)
{
	wchar_t *wPath = utf8_to_widechar(path);
	int len = min(MAX_PATH, utf8_length(path));
	char buffer[MAX_PATH];
	wcstombs(buffer, wPath, len);
	buffer[len] = '\0';
	free(wPath);
	bool exists = access(buffer, F_OK) != -1;
	log_warning("file '%s' exists = %i", buffer, exists);
	return exists;
}
Пример #6
0
bool platform_original_game_data_exists(const utf8 *path)
{
	wchar_t *wPath = utf8_to_widechar(path);
	int len = min(MAX_PATH, utf8_length(path));
	char buffer[MAX_PATH];
	wcstombs(buffer, wPath, len);
	buffer[len] = '\0';
	free(wPath);
	char checkPath[MAX_PATH];
	sprintf(checkPath, "%s%c%s%c%s", buffer, platform_get_path_separator(), "Data", platform_get_path_separator(), "g1.dat");
	return platform_file_exists(checkPath);
}
Пример #7
0
bool platform_ensure_directory_exists(const utf8 *path)
{
	mode_t mask = getumask();

	wchar_t *wPath = utf8_to_widechar(path);
	int len = min(MAX_PATH, utf8_length(path));
	char buffer[MAX_PATH];
	wcstombs(buffer, wPath, len);
	buffer[len - 1] = '\0';
	free(wPath);
	log_verbose("%s", buffer);
	const int result = mkdir(buffer, mask);
	if (result == 0 || (result == -1 && errno == EEXIST))
		return true;
	return false;
}
Пример #8
0
static size_t platform_utf8_to_multibyte(const utf8 *path, char *buffer, size_t buffer_size)
{
    wchar_t *wpath = utf8_to_widechar(path);
    setlocale(LC_CTYPE, "UTF-8");
    size_t len = wcstombs(NULL, wpath, 0);
    bool truncated = false;
    if (len > buffer_size - 1) {
        truncated = true;
        len = buffer_size - 1;
    }
    wcstombs(buffer, wpath, len);
    buffer[len] = '\0';
    if (truncated)
        log_warning("truncated string %s", buffer);
    free(wpath);
    return len;
}
Пример #9
0
bool platform_directory_exists(const utf8 *path)
{
	wchar_t *wPath = utf8_to_widechar(path);
	int len = min(MAX_PATH, utf8_length(path));
	char buffer[MAX_PATH];
	wcstombs(buffer, wPath, len);
	buffer[len] = '\0';
	free(wPath);
	struct stat dirinfo;
	int result = stat(buffer, &dirinfo);
	log_verbose("checking dir %s, result = %d, is_dir = %d", buffer, result, S_ISDIR(dirinfo.st_mode));
	if ((result != 0) || !S_ISDIR(dirinfo.st_mode))
	{
		return false;
	}
	return true;
}
Пример #10
0
int platform_enumerate_files_begin(const utf8 *pattern)
{
	enumerate_file_info *enumFileInfo;
	wchar_t *wpattern = utf8_to_widechar(pattern);
	int length = min(utf8_length(pattern), MAX_PATH);
	char *npattern = malloc(length);
	int converted;
	converted = wcstombs(npattern, wpattern, length);
	npattern[length - 1] = '\0';
	if (converted == MAX_PATH) {
		log_warning("truncated string %s", npattern);
	}
	log_warning("begin file search, pattern: %s", npattern);

	char *file_name = strrchr(npattern, platform_get_path_separator());
	char *dir_name;
	if (file_name != NULL)
	{
		dir_name = strndup(npattern, file_name - npattern);
		file_name = &file_name[1];
	} else {
		file_name = npattern;
		dir_name = strdup(".");
	}

	char *smatch = strchr(file_name, '*');
	if ((smatch != file_name) && (smatch != NULL))
	{
		log_error("Sorry, can only match '*' at start of filename.");
		return -1;
	} else {
		// '*' found
		if (smatch != NULL)
		{
			// some boundary checking needed
			// skip the '*'
			smatch = &smatch[1];
			char *match2 = strchr(&smatch[1], '*');
			if (match2 != NULL)
			{
				log_error("Sorry, can only match one '*' wildcard.");
				return -1;
			}
		} else {
			// '*' not found
			smatch = file_name;
		}
	}
	char *qmatch = strchr(file_name, '?');
	if ((qmatch != &npattern[length - 1]) && (qmatch != NULL))
	{
		log_error("Sorry, can only match '?' at end of filename.");
		return -1;
	} else {
		qmatch = &npattern[length];
	}
	int pattern_length = qmatch - smatch;
	g_file_pattern = strndup(smatch, pattern_length);
	for (int j = 0; j < pattern_length; j++)
	{
		g_file_pattern[j] = (char)toupper(g_file_pattern[j]);
	}
	log_warning("looking for file matching %s", g_file_pattern);
	int cnt;
	for (int i = 0; i < countof(_enumerateFileInfoList); i++) {
		enumFileInfo = &_enumerateFileInfoList[i];
		if (!enumFileInfo->active) {
			safe_strncpy(enumFileInfo->pattern, npattern, length);
			cnt = scandir(dir_name, &enumFileInfo->fileListTemp, winfilter, alphasort);
			if (cnt < 0)
			{
				break;
			}
			log_warning("found %d files matching in dir '%s'", cnt, dir_name);
			enumFileInfo->cnt = cnt;
			enumFileInfo->paths = malloc(cnt * sizeof(char *));
			char **paths = enumFileInfo->paths;
			// 256 is size of dirent.d_name
			const int buf_len = min(MAX_PATH, 256);
			const int dir_name_len = strnlen(dir_name, MAX_PATH);
			char separator[] = {platform_get_path_separator(), 0};
			for (int idx = 0; idx < cnt; idx++)
			{
				struct dirent *d = enumFileInfo->fileListTemp[idx];
				const int entry_len = strnlen(d->d_name, MAX_PATH);
				// 1 for separator, 1 for trailing null
				paths[idx] = malloc(sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2));
				paths[idx][0] = '\0';
				log_verbose("dir_name: %s", dir_name);
				strncat(paths[idx], dir_name, MAX_PATH);
				strncat(paths[idx], separator, MAX_PATH);
				strncat(paths[idx], d->d_name, MAX_PATH);
				log_verbose("paths[%d] = %s", idx, paths[idx]);
			}
			enumFileInfo->handle = 0;
			enumFileInfo->active = 1;
			free(dir_name);
			free(g_file_pattern);
			g_file_pattern = NULL;
			free(wpattern);
			free(npattern);
			return i;
		}
	}

	free(dir_name);
	free(g_file_pattern);
	g_file_pattern = NULL;
	free(wpattern);
	free(npattern);
	return -1;
}
Пример #11
0
int platform_enumerate_files_begin(const utf8 *pattern)
{
	enumerate_file_info *enumFileInfo;
	wchar_t *wpattern = utf8_to_widechar(pattern);
	int length = min(utf8_length(pattern), MAX_PATH);
	char *npattern = malloc(length+1);
	int converted;
	converted = wcstombs(npattern, wpattern, length);
	npattern[length] = '\0';
	if (converted == MAX_PATH) {
		log_warning("truncated string %s", npattern);
	}
	log_verbose("begin file search, pattern: %s", npattern);

	char *file_name = strrchr(npattern, platform_get_path_separator());
	char *dir_name;
	if (file_name != NULL)
	{
		dir_name = strndup(npattern, file_name - npattern);
		file_name = &file_name[1];
	} else {
		file_name = npattern;
		dir_name = strdup(".");
	}


	int pattern_length = strlen(file_name);
	g_file_pattern = strndup(file_name, pattern_length);
	for (int j = 0; j < pattern_length; j++)
	{
		g_file_pattern[j] = (char)toupper(g_file_pattern[j]);
	}
	log_verbose("looking for file matching %s", g_file_pattern);
	int cnt;
	for (int i = 0; i < countof(_enumerateFileInfoList); i++) {
		enumFileInfo = &_enumerateFileInfoList[i];
		if (!enumFileInfo->active) {
			safe_strcpy(enumFileInfo->pattern, npattern, sizeof(enumFileInfo->pattern));
			cnt = scandir(dir_name, &enumFileInfo->fileListTemp, winfilter, alphasort);
			if (cnt < 0)
			{
				break;
			}
			log_verbose("found %d files matching in dir '%s'", cnt, dir_name);
			enumFileInfo->cnt = cnt;
			enumFileInfo->paths = malloc(cnt * sizeof(char *));
			char **paths = enumFileInfo->paths;
			// 256 is size of dirent.d_name
			const int buf_len = min(MAX_PATH, 256);
			const int dir_name_len = strnlen(dir_name, MAX_PATH);
			char separator[] = {platform_get_path_separator(), 0};
			for (int idx = 0; idx < cnt; idx++)
			{
				struct dirent *d = enumFileInfo->fileListTemp[idx];
				const int entry_len = strnlen(d->d_name, MAX_PATH);
				// 1 for separator, 1 for trailing null
				size_t path_len = sizeof(char) * min(MAX_PATH, entry_len + dir_name_len + 2);
				paths[idx] = malloc(path_len);
				paths[idx][0] = '\0';
				log_verbose("dir_name: %s", dir_name);
				strncat(paths[idx], dir_name, path_len - 2);
				strncat(paths[idx], separator, path_len - strnlen(paths[idx], path_len) - 1);
				strncat(paths[idx], d->d_name, path_len - strnlen(paths[idx], path_len) - 1);
				log_verbose("paths[%d] = %s", idx, paths[idx]);
			}
			enumFileInfo->handle = 0;
			enumFileInfo->active = 1;
			free(dir_name);
			free(g_file_pattern);
			g_file_pattern = NULL;
			free(wpattern);
			free(npattern);
			return i;
		}
	}

	free(dir_name);
	free(g_file_pattern);
	g_file_pattern = NULL;
	free(wpattern);
	free(npattern);
	return -1;
}