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