dir.c 2.08 KB
Newer Older
Vicent Marti committed
1 2 3 4 5 6
/*
 * Copyright (C) 2009-2011 the libgit2 contributors
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */
7
#define GIT__WIN32_NO_WRAP_DIR
8
#include "dir.h"
9 10
#include "utf-conv.h"
#include "git2/windows.h"
11 12 13

static int init_filter(char *filter, size_t n, const char *dir)
{
14
	size_t len = strlen(dir);
15 16 17 18 19 20 21 22 23 24 25 26

	if (len+3 >= n)
		return 0;

	strcpy(filter, dir);
	if (len && dir[len-1] != '/')
		strcat(filter, "/");
	strcat(filter, "*");

	return 1;
}

27
git__DIR *git__opendir(const char *dir)
28 29
{
	char filter[4096];
30
	wchar_t* filter_w;
31
	git__DIR *new;
32 33 34 35 36 37 38 39 40 41

	if (!dir || !init_filter(filter, sizeof(filter), dir))
		return NULL;

	new = git__malloc(sizeof(*new));
	if (!new)
		return NULL;

	new->dir = git__malloc(strlen(dir)+1);
	if (!new->dir) {
42
		git__free(new);
43 44 45 46
		return NULL;
	}
	strcpy(new->dir, dir);

47
	filter_w = gitwin_to_utf16(filter);
48
	new->h = FindFirstFileW(filter_w, &new->f);
49
	git__free(filter_w);
50

51
	if (new->h == INVALID_HANDLE_VALUE) {
52 53
		git__free(new->dir);
		git__free(new);
54 55 56 57 58 59 60
		return NULL;
	}
	new->first = 1;

	return new;
}

61
struct git__dirent *git__readdir(git__DIR *d)
62 63 64 65 66 67 68
{
	if (!d || d->h == INVALID_HANDLE_VALUE)
		return NULL;

	if (d->first)
		d->first = 0;
	else {
69
		if (!FindNextFileW(d->h, &d->f))
70 71 72
			return NULL;
	}

73
	if (wcslen(d->f.cFileName) >= sizeof(d->entry.d_name))
74 75 76
		return NULL;

	d->entry.d_ino = 0;
77
	WideCharToMultiByte(gitwin_get_codepage(), 0, d->f.cFileName, -1, d->entry.d_name, GIT_PATH_MAX, NULL, NULL);
78 79 80 81

	return &d->entry;
}

82
void git__rewinddir(git__DIR *d)
83 84
{
	char filter[4096];
85
	wchar_t* filter_w;
86 87 88 89 90 91

	if (d) {
		if (d->h != INVALID_HANDLE_VALUE)
			FindClose(d->h);
		d->h = INVALID_HANDLE_VALUE;
		d->first = 0;
92

93
		if (init_filter(filter, sizeof(filter), d->dir)) {
94
			filter_w = gitwin_to_utf16(filter);
95
			d->h = FindFirstFileW(filter_w, &d->f);
96
			git__free(filter_w);
97

98 99 100 101 102 103
			if (d->h != INVALID_HANDLE_VALUE)
				d->first = 1;
		}
	}
}

104
int git__closedir(git__DIR *d)
105 106 107 108 109
{
	if (d) {
		if (d->h != INVALID_HANDLE_VALUE)
			FindClose(d->h);
		if (d->dir)
110 111
			git__free(d->dir);
		git__free(d);
112 113 114 115
	}
	return 0;
}