Cleanup: remove redundant doxygen \file argument
[blender.git] / source / blender / blenlib / intern / winstuff_dir.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  * Windows-posix compatibility layer for opendir/readdir/closedir
16  */
17
18 /** \file \ingroup bli
19  *
20  * Posix compatibility functions for windows dealing with DIR
21  * (opendir, readdir, closedir)
22  */
23
24 #ifdef WIN32
25
26 /* standalone for inclusion in binaries other then blender */
27 #  ifdef USE_STANDALONE
28 #    define MEM_mallocN(size, str) ((void)str, malloc(size))
29 #    define MEM_callocN(size, str) ((void)str, calloc(size, 1))
30 #    define MEM_freeN(ptr) free(ptr)
31 #  else
32 #    include "MEM_guardedalloc.h"
33 #  endif
34
35 #define WIN32_SKIP_HKEY_PROTECTION      // need to use HKEY
36 #include "BLI_winstuff.h"
37 #include "BLI_utildefines.h"
38 #include "utfconv.h"
39
40 #define PATH_SUFFIX     "\\*"
41 #define PATH_SUFFIX_LEN 2
42
43 /* keep local to this file */
44 struct __dirstream {
45         HANDLE handle;
46         WIN32_FIND_DATAW data;
47         char path[MAX_PATH + PATH_SUFFIX_LEN];
48         long dd_loc;
49         long dd_size;
50         char dd_buf[4096];
51         void *dd_direct;
52
53         struct dirent direntry;
54 };
55
56 /* Note: MinGW (FREE_WINDOWS) has opendir() and _wopendir(), and only the
57  * latter accepts a path name of wchar_t type.  Rather than messing up with
58  * extra #ifdef's here and there, Blender's own implementations of opendir()
59  * and related functions are used to properly support paths with non-ASCII
60  * characters. (kjym3)
61  */
62
63 DIR *opendir(const char *path)
64 {
65         wchar_t *path_16 = alloc_utf16_from_8(path, 0);
66         int path_len;
67         DIR *newd = NULL;
68
69         if ((GetFileAttributesW(path_16) & FILE_ATTRIBUTE_DIRECTORY) &&
70             ((path_len = strlen(path)) < (sizeof(newd->path) - PATH_SUFFIX_LEN)))
71         {
72                 newd = MEM_mallocN(sizeof(DIR), "opendir");
73                 newd->handle = INVALID_HANDLE_VALUE;
74                 memcpy(newd->path, path, path_len);
75                 memcpy(newd->path + path_len, PATH_SUFFIX, PATH_SUFFIX_LEN + 1);
76
77                 newd->direntry.d_ino = 0;
78                 newd->direntry.d_off = 0;
79                 newd->direntry.d_reclen = 0;
80                 newd->direntry.d_name = NULL;
81         }
82
83         free(path_16);
84         return newd;
85 }
86
87 static char *BLI_alloc_utf_8_from_16(wchar_t *in16, size_t add)
88 {
89         size_t bsize = count_utf_8_from_16(in16);
90         char *out8 = NULL;
91         if (!bsize) return NULL;
92         out8 = (char *)MEM_mallocN(sizeof(char) * (bsize + add), "UTF-8 String");
93         conv_utf_16_to_8(in16, out8, bsize);
94         return out8;
95 }
96
97 static wchar_t *UNUSED_FUNCTION(BLI_alloc_utf16_from_8) (char *in8, size_t add)
98 {
99         size_t bsize = count_utf_16_from_8(in8);
100         wchar_t *out16 = NULL;
101         if (!bsize) return NULL;
102         out16 = (wchar_t *) MEM_mallocN(sizeof(wchar_t) * (bsize + add), "UTF-16 String");
103         conv_utf_8_to_16(in8, out16, bsize);
104         return out16;
105 }
106
107
108
109 struct dirent *readdir(DIR *dp)
110 {
111         if (dp->direntry.d_name) {
112                 MEM_freeN(dp->direntry.d_name);
113                 dp->direntry.d_name = NULL;
114         }
115
116         if (dp->handle == INVALID_HANDLE_VALUE) {
117                 wchar_t *path_16 = alloc_utf16_from_8(dp->path, 0);
118                 dp->handle = FindFirstFileW(path_16, &(dp->data));
119                 free(path_16);
120                 if (dp->handle == INVALID_HANDLE_VALUE)
121                         return NULL;
122
123                 dp->direntry.d_name = BLI_alloc_utf_8_from_16(dp->data.cFileName, 0);
124
125                 return &dp->direntry;
126         }
127         else if (FindNextFileW(dp->handle, &(dp->data))) {
128                 dp->direntry.d_name = BLI_alloc_utf_8_from_16(dp->data.cFileName, 0);
129
130                 return &dp->direntry;
131         }
132         else {
133                 return NULL;
134         }
135 }
136
137 int closedir(DIR *dp)
138 {
139         if (dp->direntry.d_name) MEM_freeN(dp->direntry.d_name);
140         if (dp->handle != INVALID_HANDLE_VALUE) FindClose(dp->handle);
141
142         MEM_freeN(dp);
143
144         return 0;
145 }
146
147 /* End of copied part */
148
149 #else
150
151 /* intentionally empty for UNIX */
152
153 #endif