Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hackassin
GitHub Repository: hackassin/learnopencv
Path: blob/master/EigenFace/dirent.h
3119 views
1
/*
2
* Dirent interface for Microsoft Visual Studio
3
* Version 1.21
4
*
5
* Copyright (C) 2006-2012 Toni Ronkko
6
* This file is part of dirent. Dirent may be freely distributed
7
* under the MIT license. For all details and documentation, see
8
* https://github.com/tronkko/dirent
9
*/
10
#ifndef DIRENT_H
11
#define DIRENT_H
12
13
/*
14
* Define architecture flags so we don't need to include windows.h.
15
* Avoiding windows.h makes it simpler to use windows sockets in conjunction
16
* with dirent.h.
17
*/
18
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
19
# define _X86_
20
#endif
21
#if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
22
#define _AMD64_
23
#endif
24
25
#include <stdio.h>
26
#include <stdarg.h>
27
#include <windef.h>
28
#include <winbase.h>
29
#include <wchar.h>
30
#include <string.h>
31
#include <stdlib.h>
32
#include <malloc.h>
33
#include <sys/types.h>
34
#include <sys/stat.h>
35
#include <errno.h>
36
37
/* Indicates that d_type field is available in dirent structure */
38
#define _DIRENT_HAVE_D_TYPE
39
40
/* Indicates that d_namlen field is available in dirent structure */
41
#define _DIRENT_HAVE_D_NAMLEN
42
43
/* Entries missing from MSVC 6.0 */
44
#if !defined(FILE_ATTRIBUTE_DEVICE)
45
# define FILE_ATTRIBUTE_DEVICE 0x40
46
#endif
47
48
/* File type and permission flags for stat(), general mask */
49
#if !defined(S_IFMT)
50
# define S_IFMT _S_IFMT
51
#endif
52
53
/* Directory bit */
54
#if !defined(S_IFDIR)
55
# define S_IFDIR _S_IFDIR
56
#endif
57
58
/* Character device bit */
59
#if !defined(S_IFCHR)
60
# define S_IFCHR _S_IFCHR
61
#endif
62
63
/* Pipe bit */
64
#if !defined(S_IFFIFO)
65
# define S_IFFIFO _S_IFFIFO
66
#endif
67
68
/* Regular file bit */
69
#if !defined(S_IFREG)
70
# define S_IFREG _S_IFREG
71
#endif
72
73
/* Read permission */
74
#if !defined(S_IREAD)
75
# define S_IREAD _S_IREAD
76
#endif
77
78
/* Write permission */
79
#if !defined(S_IWRITE)
80
# define S_IWRITE _S_IWRITE
81
#endif
82
83
/* Execute permission */
84
#if !defined(S_IEXEC)
85
# define S_IEXEC _S_IEXEC
86
#endif
87
88
/* Pipe */
89
#if !defined(S_IFIFO)
90
# define S_IFIFO _S_IFIFO
91
#endif
92
93
/* Block device */
94
#if !defined(S_IFBLK)
95
# define S_IFBLK 0
96
#endif
97
98
/* Link */
99
#if !defined(S_IFLNK)
100
# define S_IFLNK 0
101
#endif
102
103
/* Socket */
104
#if !defined(S_IFSOCK)
105
# define S_IFSOCK 0
106
#endif
107
108
/* Read user permission */
109
#if !defined(S_IRUSR)
110
# define S_IRUSR S_IREAD
111
#endif
112
113
/* Write user permission */
114
#if !defined(S_IWUSR)
115
# define S_IWUSR S_IWRITE
116
#endif
117
118
/* Execute user permission */
119
#if !defined(S_IXUSR)
120
# define S_IXUSR 0
121
#endif
122
123
/* Read group permission */
124
#if !defined(S_IRGRP)
125
# define S_IRGRP 0
126
#endif
127
128
/* Write group permission */
129
#if !defined(S_IWGRP)
130
# define S_IWGRP 0
131
#endif
132
133
/* Execute group permission */
134
#if !defined(S_IXGRP)
135
# define S_IXGRP 0
136
#endif
137
138
/* Read others permission */
139
#if !defined(S_IROTH)
140
# define S_IROTH 0
141
#endif
142
143
/* Write others permission */
144
#if !defined(S_IWOTH)
145
# define S_IWOTH 0
146
#endif
147
148
/* Execute others permission */
149
#if !defined(S_IXOTH)
150
# define S_IXOTH 0
151
#endif
152
153
/* Maximum length of file name */
154
#if !defined(PATH_MAX)
155
# define PATH_MAX MAX_PATH
156
#endif
157
#if !defined(FILENAME_MAX)
158
# define FILENAME_MAX MAX_PATH
159
#endif
160
#if !defined(NAME_MAX)
161
# define NAME_MAX FILENAME_MAX
162
#endif
163
164
/* File type flags for d_type */
165
#define DT_UNKNOWN 0
166
#define DT_REG S_IFREG
167
#define DT_DIR S_IFDIR
168
#define DT_FIFO S_IFIFO
169
#define DT_SOCK S_IFSOCK
170
#define DT_CHR S_IFCHR
171
#define DT_BLK S_IFBLK
172
#define DT_LNK S_IFLNK
173
174
/* Macros for converting between st_mode and d_type */
175
#define IFTODT(mode) ((mode) & S_IFMT)
176
#define DTTOIF(type) (type)
177
178
/*
179
* File type macros. Note that block devices, sockets and links cannot be
180
* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
181
* only defined for compatibility. These macros should always return false
182
* on Windows.
183
*/
184
#if !defined(S_ISFIFO)
185
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
186
#endif
187
#if !defined(S_ISDIR)
188
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
189
#endif
190
#if !defined(S_ISREG)
191
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
192
#endif
193
#if !defined(S_ISLNK)
194
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
195
#endif
196
#if !defined(S_ISSOCK)
197
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
198
#endif
199
#if !defined(S_ISCHR)
200
# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
201
#endif
202
#if !defined(S_ISBLK)
203
# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
204
#endif
205
206
/* Return the exact length of d_namlen without zero terminator */
207
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
208
209
/* Return number of bytes needed to store d_namlen */
210
#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
211
212
213
#ifdef __cplusplus
214
extern "C" {
215
#endif
216
217
218
/* Wide-character version */
219
struct _wdirent {
220
/* Always zero */
221
long d_ino;
222
223
/* Structure size */
224
unsigned short d_reclen;
225
226
/* Length of name without \0 */
227
size_t d_namlen;
228
229
/* File type */
230
int d_type;
231
232
/* File name */
233
wchar_t d_name[PATH_MAX];
234
};
235
typedef struct _wdirent _wdirent;
236
237
struct _WDIR {
238
/* Current directory entry */
239
struct _wdirent ent;
240
241
/* Private file data */
242
WIN32_FIND_DATAW data;
243
244
/* True if data is valid */
245
int cached;
246
247
/* Win32 search handle */
248
HANDLE handle;
249
250
/* Initial directory name */
251
wchar_t *patt;
252
};
253
typedef struct _WDIR _WDIR;
254
255
static _WDIR *_wopendir (const wchar_t *dirname);
256
static struct _wdirent *_wreaddir (_WDIR *dirp);
257
static int _wclosedir (_WDIR *dirp);
258
static void _wrewinddir (_WDIR* dirp);
259
260
261
/* For compatibility with Symbian */
262
#define wdirent _wdirent
263
#define WDIR _WDIR
264
#define wopendir _wopendir
265
#define wreaddir _wreaddir
266
#define wclosedir _wclosedir
267
#define wrewinddir _wrewinddir
268
269
270
/* Multi-byte character versions */
271
struct dirent {
272
/* Always zero */
273
long d_ino;
274
275
/* Structure size */
276
unsigned short d_reclen;
277
278
/* Length of name without \0 */
279
size_t d_namlen;
280
281
/* File type */
282
int d_type;
283
284
/* File name */
285
char d_name[PATH_MAX];
286
};
287
typedef struct dirent dirent;
288
289
struct DIR {
290
struct dirent ent;
291
struct _WDIR *wdirp;
292
};
293
typedef struct DIR DIR;
294
295
static DIR *opendir (const char *dirname);
296
static struct dirent *readdir (DIR *dirp);
297
static int closedir (DIR *dirp);
298
static void rewinddir (DIR* dirp);
299
300
301
/* Internal utility functions */
302
static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
303
static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
304
305
static int dirent_mbstowcs_s(
306
size_t *pReturnValue,
307
wchar_t *wcstr,
308
size_t sizeInWords,
309
const char *mbstr,
310
size_t count);
311
312
static int dirent_wcstombs_s(
313
size_t *pReturnValue,
314
char *mbstr,
315
size_t sizeInBytes,
316
const wchar_t *wcstr,
317
size_t count);
318
319
static void dirent_set_errno (int error);
320
321
/*
322
* Open directory stream DIRNAME for read and return a pointer to the
323
* internal working area that is used to retrieve individual directory
324
* entries.
325
*/
326
static _WDIR*
327
_wopendir(
328
const wchar_t *dirname)
329
{
330
_WDIR *dirp = NULL;
331
int error;
332
333
/* Must have directory name */
334
if (dirname == NULL || dirname[0] == '\0') {
335
dirent_set_errno (ENOENT);
336
return NULL;
337
}
338
339
/* Allocate new _WDIR structure */
340
dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
341
if (dirp != NULL) {
342
DWORD n;
343
344
/* Reset _WDIR structure */
345
dirp->handle = INVALID_HANDLE_VALUE;
346
dirp->patt = NULL;
347
dirp->cached = 0;
348
349
/* Compute the length of full path plus zero terminator */
350
n = GetFullPathNameW (dirname, 0, NULL, NULL);
351
352
/* Allocate room for absolute directory name and search pattern */
353
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
354
if (dirp->patt) {
355
356
/*
357
* Convert relative directory name to an absolute one. This
358
* allows rewinddir() to function correctly even when current
359
* working directory is changed between opendir() and rewinddir().
360
*/
361
n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
362
if (n > 0) {
363
wchar_t *p;
364
365
/* Append search pattern \* to the directory name */
366
p = dirp->patt + n;
367
if (dirp->patt < p) {
368
switch (p[-1]) {
369
case '\\':
370
case '/':
371
case ':':
372
/* Directory ends in path separator, e.g. c:\temp\ */
373
/*NOP*/;
374
break;
375
376
default:
377
/* Directory name doesn't end in path separator */
378
*p++ = '\\';
379
}
380
}
381
*p++ = '*';
382
*p = '\0';
383
384
/* Open directory stream and retrieve the first entry */
385
if (dirent_first (dirp)) {
386
/* Directory stream opened successfully */
387
error = 0;
388
} else {
389
/* Cannot retrieve first entry */
390
error = 1;
391
dirent_set_errno (ENOENT);
392
}
393
394
} else {
395
/* Cannot retrieve full path name */
396
dirent_set_errno (ENOENT);
397
error = 1;
398
}
399
400
} else {
401
/* Cannot allocate memory for search pattern */
402
error = 1;
403
}
404
405
} else {
406
/* Cannot allocate _WDIR structure */
407
error = 1;
408
}
409
410
/* Clean up in case of error */
411
if (error && dirp) {
412
_wclosedir (dirp);
413
dirp = NULL;
414
}
415
416
return dirp;
417
}
418
419
/*
420
* Read next directory entry. The directory entry is returned in dirent
421
* structure in the d_name field. Individual directory entries returned by
422
* this function include regular files, sub-directories, pseudo-directories
423
* "." and ".." as well as volume labels, hidden files and system files.
424
*/
425
static struct _wdirent*
426
_wreaddir(
427
_WDIR *dirp)
428
{
429
WIN32_FIND_DATAW *datap;
430
struct _wdirent *entp;
431
432
/* Read next directory entry */
433
datap = dirent_next (dirp);
434
if (datap) {
435
size_t n;
436
DWORD attr;
437
438
/* Pointer to directory entry to return */
439
entp = &dirp->ent;
440
441
/*
442
* Copy file name as wide-character string. If the file name is too
443
* long to fit in to the destination buffer, then truncate file name
444
* to PATH_MAX characters and zero-terminate the buffer.
445
*/
446
n = 0;
447
while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
448
entp->d_name[n] = datap->cFileName[n];
449
n++;
450
}
451
dirp->ent.d_name[n] = 0;
452
453
/* Length of file name excluding zero terminator */
454
entp->d_namlen = n;
455
456
/* File type */
457
attr = datap->dwFileAttributes;
458
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
459
entp->d_type = DT_CHR;
460
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
461
entp->d_type = DT_DIR;
462
} else {
463
entp->d_type = DT_REG;
464
}
465
466
/* Reset dummy fields */
467
entp->d_ino = 0;
468
entp->d_reclen = sizeof (struct _wdirent);
469
470
} else {
471
472
/* Last directory entry read */
473
entp = NULL;
474
475
}
476
477
return entp;
478
}
479
480
/*
481
* Close directory stream opened by opendir() function. This invalidates the
482
* DIR structure as well as any directory entry read previously by
483
* _wreaddir().
484
*/
485
static int
486
_wclosedir(
487
_WDIR *dirp)
488
{
489
int ok;
490
if (dirp) {
491
492
/* Release search handle */
493
if (dirp->handle != INVALID_HANDLE_VALUE) {
494
FindClose (dirp->handle);
495
dirp->handle = INVALID_HANDLE_VALUE;
496
}
497
498
/* Release search pattern */
499
if (dirp->patt) {
500
free (dirp->patt);
501
dirp->patt = NULL;
502
}
503
504
/* Release directory structure */
505
free (dirp);
506
ok = /*success*/0;
507
508
} else {
509
/* Invalid directory stream */
510
dirent_set_errno (EBADF);
511
ok = /*failure*/-1;
512
}
513
return ok;
514
}
515
516
/*
517
* Rewind directory stream such that _wreaddir() returns the very first
518
* file name again.
519
*/
520
static void
521
_wrewinddir(
522
_WDIR* dirp)
523
{
524
if (dirp) {
525
/* Release existing search handle */
526
if (dirp->handle != INVALID_HANDLE_VALUE) {
527
FindClose (dirp->handle);
528
}
529
530
/* Open new search handle */
531
dirent_first (dirp);
532
}
533
}
534
535
/* Get first directory entry (internal) */
536
static WIN32_FIND_DATAW*
537
dirent_first(
538
_WDIR *dirp)
539
{
540
WIN32_FIND_DATAW *datap;
541
542
/* Open directory and retrieve the first entry */
543
dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
544
if (dirp->handle != INVALID_HANDLE_VALUE) {
545
546
/* a directory entry is now waiting in memory */
547
datap = &dirp->data;
548
dirp->cached = 1;
549
550
} else {
551
552
/* Failed to re-open directory: no directory entry in memory */
553
dirp->cached = 0;
554
datap = NULL;
555
556
}
557
return datap;
558
}
559
560
/* Get next directory entry (internal) */
561
static WIN32_FIND_DATAW*
562
dirent_next(
563
_WDIR *dirp)
564
{
565
WIN32_FIND_DATAW *p;
566
567
/* Get next directory entry */
568
if (dirp->cached != 0) {
569
570
/* A valid directory entry already in memory */
571
p = &dirp->data;
572
dirp->cached = 0;
573
574
} else if (dirp->handle != INVALID_HANDLE_VALUE) {
575
576
/* Get the next directory entry from stream */
577
if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
578
/* Got a file */
579
p = &dirp->data;
580
} else {
581
/* The very last entry has been processed or an error occured */
582
FindClose (dirp->handle);
583
dirp->handle = INVALID_HANDLE_VALUE;
584
p = NULL;
585
}
586
587
} else {
588
589
/* End of directory stream reached */
590
p = NULL;
591
592
}
593
594
return p;
595
}
596
597
/*
598
* Open directory stream using plain old C-string.
599
*/
600
static DIR*
601
opendir(
602
const char *dirname)
603
{
604
struct DIR *dirp;
605
int error;
606
607
/* Must have directory name */
608
if (dirname == NULL || dirname[0] == '\0') {
609
dirent_set_errno (ENOENT);
610
return NULL;
611
}
612
613
/* Allocate memory for DIR structure */
614
dirp = (DIR*) malloc (sizeof (struct DIR));
615
if (dirp) {
616
wchar_t wname[PATH_MAX];
617
size_t n;
618
619
/* Convert directory name to wide-character string */
620
error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
621
if (!error) {
622
623
/* Open directory stream using wide-character name */
624
dirp->wdirp = _wopendir (wname);
625
if (dirp->wdirp) {
626
/* Directory stream opened */
627
error = 0;
628
} else {
629
/* Failed to open directory stream */
630
error = 1;
631
}
632
633
} else {
634
/*
635
* Cannot convert file name to wide-character string. This
636
* occurs if the string contains invalid multi-byte sequences or
637
* the output buffer is too small to contain the resulting
638
* string.
639
*/
640
error = 1;
641
}
642
643
} else {
644
/* Cannot allocate DIR structure */
645
error = 1;
646
}
647
648
/* Clean up in case of error */
649
if (error && dirp) {
650
free (dirp);
651
dirp = NULL;
652
}
653
654
return dirp;
655
}
656
657
/*
658
* Read next directory entry.
659
*
660
* When working with text consoles, please note that file names returned by
661
* readdir() are represented in the default ANSI code page while any output to
662
* console is typically formatted on another code page. Thus, non-ASCII
663
* characters in file names will not usually display correctly on console. The
664
* problem can be fixed in two ways: (1) change the character set of console
665
* to 1252 using chcp utility and use Lucida Console font, or (2) use
666
* _cprintf function when writing to console. The _cprinf() will re-encode
667
* ANSI strings to the console code page so many non-ASCII characters will
668
* display correcly.
669
*/
670
static struct dirent*
671
readdir(
672
DIR *dirp)
673
{
674
WIN32_FIND_DATAW *datap;
675
struct dirent *entp;
676
677
/* Read next directory entry */
678
datap = dirent_next (dirp->wdirp);
679
if (datap) {
680
size_t n;
681
int error;
682
683
/* Attempt to convert file name to multi-byte string */
684
error = dirent_wcstombs_s(
685
&n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
686
687
/*
688
* If the file name cannot be represented by a multi-byte string,
689
* then attempt to use old 8+3 file name. This allows traditional
690
* Unix-code to access some file names despite of unicode
691
* characters, although file names may seem unfamiliar to the user.
692
*
693
* Be ware that the code below cannot come up with a short file
694
* name unless the file system provides one. At least
695
* VirtualBox shared folders fail to do this.
696
*/
697
if (error && datap->cAlternateFileName[0] != '\0') {
698
error = dirent_wcstombs_s(
699
&n, dirp->ent.d_name, PATH_MAX,
700
datap->cAlternateFileName, PATH_MAX);
701
}
702
703
if (!error) {
704
DWORD attr;
705
706
/* Initialize directory entry for return */
707
entp = &dirp->ent;
708
709
/* Length of file name excluding zero terminator */
710
entp->d_namlen = n - 1;
711
712
/* File attributes */
713
attr = datap->dwFileAttributes;
714
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
715
entp->d_type = DT_CHR;
716
} else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
717
entp->d_type = DT_DIR;
718
} else {
719
entp->d_type = DT_REG;
720
}
721
722
/* Reset dummy fields */
723
entp->d_ino = 0;
724
entp->d_reclen = sizeof (struct dirent);
725
726
} else {
727
/*
728
* Cannot convert file name to multi-byte string so construct
729
* an errornous directory entry and return that. Note that
730
* we cannot return NULL as that would stop the processing
731
* of directory entries completely.
732
*/
733
entp = &dirp->ent;
734
entp->d_name[0] = '?';
735
entp->d_name[1] = '\0';
736
entp->d_namlen = 1;
737
entp->d_type = DT_UNKNOWN;
738
entp->d_ino = 0;
739
entp->d_reclen = 0;
740
}
741
742
} else {
743
/* No more directory entries */
744
entp = NULL;
745
}
746
747
return entp;
748
}
749
750
/*
751
* Close directory stream.
752
*/
753
static int
754
closedir(
755
DIR *dirp)
756
{
757
int ok;
758
if (dirp) {
759
760
/* Close wide-character directory stream */
761
ok = _wclosedir (dirp->wdirp);
762
dirp->wdirp = NULL;
763
764
/* Release multi-byte character version */
765
free (dirp);
766
767
} else {
768
769
/* Invalid directory stream */
770
dirent_set_errno (EBADF);
771
ok = /*failure*/-1;
772
773
}
774
return ok;
775
}
776
777
/*
778
* Rewind directory stream to beginning.
779
*/
780
static void
781
rewinddir(
782
DIR* dirp)
783
{
784
/* Rewind wide-character string directory stream */
785
_wrewinddir (dirp->wdirp);
786
}
787
788
/* Convert multi-byte string to wide character string */
789
static int
790
dirent_mbstowcs_s(
791
size_t *pReturnValue,
792
wchar_t *wcstr,
793
size_t sizeInWords,
794
const char *mbstr,
795
size_t count)
796
{
797
int error;
798
799
#if defined(_MSC_VER) && _MSC_VER >= 1400
800
801
/* Microsoft Visual Studio 2005 or later */
802
error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
803
804
#else
805
806
/* Older Visual Studio or non-Microsoft compiler */
807
size_t n;
808
809
/* Convert to wide-character string (or count characters) */
810
n = mbstowcs (wcstr, mbstr, sizeInWords);
811
if (!wcstr || n < count) {
812
813
/* Zero-terminate output buffer */
814
if (wcstr && sizeInWords) {
815
if (n >= sizeInWords) {
816
n = sizeInWords - 1;
817
}
818
wcstr[n] = 0;
819
}
820
821
/* Length of resuting multi-byte string WITH zero terminator */
822
if (pReturnValue) {
823
*pReturnValue = n + 1;
824
}
825
826
/* Success */
827
error = 0;
828
829
} else {
830
831
/* Could not convert string */
832
error = 1;
833
834
}
835
836
#endif
837
838
return error;
839
}
840
841
/* Convert wide-character string to multi-byte string */
842
static int
843
dirent_wcstombs_s(
844
size_t *pReturnValue,
845
char *mbstr,
846
size_t sizeInBytes, /* max size of mbstr */
847
const wchar_t *wcstr,
848
size_t count)
849
{
850
int error;
851
852
#if defined(_MSC_VER) && _MSC_VER >= 1400
853
854
/* Microsoft Visual Studio 2005 or later */
855
error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
856
857
#else
858
859
/* Older Visual Studio or non-Microsoft compiler */
860
size_t n;
861
862
/* Convert to multi-byte string (or count the number of bytes needed) */
863
n = wcstombs (mbstr, wcstr, sizeInBytes);
864
if (!mbstr || n < count) {
865
866
/* Zero-terminate output buffer */
867
if (mbstr && sizeInBytes) {
868
if (n >= sizeInBytes) {
869
n = sizeInBytes - 1;
870
}
871
mbstr[n] = '\0';
872
}
873
874
/* Lenght of resulting multi-bytes string WITH zero-terminator */
875
if (pReturnValue) {
876
*pReturnValue = n + 1;
877
}
878
879
/* Success */
880
error = 0;
881
882
} else {
883
884
/* Cannot convert string */
885
error = 1;
886
887
}
888
889
#endif
890
891
return error;
892
}
893
894
/* Set errno variable */
895
static void
896
dirent_set_errno(
897
int error)
898
{
899
#if defined(_MSC_VER) && _MSC_VER >= 1400
900
901
/* Microsoft Visual Studio 2005 and later */
902
_set_errno (error);
903
904
#else
905
906
/* Non-Microsoft compiler or older Microsoft compiler */
907
errno = error;
908
909
#endif
910
}
911
912
913
#ifdef __cplusplus
914
}
915
#endif
916
#endif /*DIRENT_H*/
917
918
919