CASToR  1.0
Tomographic Reconstruction (PET/SPECT)
oDirentWin32.hh
Go to the documentation of this file.
00001 
00002 /*
00003  * Dirent interface for Microsoft Visual Studio
00004  * Version 1.21
00005  *
00006  * Copyright (C) 2006-2012 Toni Ronkko
00007  * This file is part of dirent.  Dirent may be freely distributed
00008  * under the MIT license.  For all details and documentation, see
00009  * https://github.com/tronkko/dirent
00010  */
00011 
00012 #ifndef DIRENT_H
00013 #define DIRENT_H
00014 
00015 /*
00016  * Define architecture flags so we don't need to include windows.h.
00017  * Avoiding windows.h makes it simpler to use windows sockets in conjunction
00018  * with dirent.h.
00019  */
00020 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
00021 #   define _X86_
00022 #endif
00023 #if !defined(_68K_) && !defined(_MPPC_) && !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
00024 #define _AMD64_
00025 #endif
00026 
00027 #include <stdio.h>
00028 #include <stdarg.h>
00029 #include <windef.h>
00030 #include <winbase.h>
00031 #include <wchar.h>
00032 #include <string.h>
00033 #include <stdlib.h>
00034 #include <malloc.h>
00035 #include <sys/types.h>
00036 #include <sys/stat.h>
00037 #include <errno.h>
00038 
00039 /* Indicates that d_type field is available in dirent structure */
00040 #define _DIRENT_HAVE_D_TYPE
00041 
00042 /* Indicates that d_namlen field is available in dirent structure */
00043 #define _DIRENT_HAVE_D_NAMLEN
00044 
00045 /* Entries missing from MSVC 6.0 */
00046 #if !defined(FILE_ATTRIBUTE_DEVICE)
00047 #   define FILE_ATTRIBUTE_DEVICE 0x40
00048 #endif
00049 
00050 /* File type and permission flags for stat(), general mask */
00051 #if !defined(S_IFMT)
00052 #   define S_IFMT _S_IFMT
00053 #endif
00054 
00055 /* Directory bit */
00056 #if !defined(S_IFDIR)
00057 #   define S_IFDIR _S_IFDIR
00058 #endif
00059 
00060 /* Character device bit */
00061 #if !defined(S_IFCHR)
00062 #   define S_IFCHR _S_IFCHR
00063 #endif
00064 
00065 /* Pipe bit */
00066 #if !defined(S_IFFIFO)
00067 #   define S_IFFIFO _S_IFFIFO
00068 #endif
00069 
00070 /* Regular file bit */
00071 #if !defined(S_IFREG)
00072 #   define S_IFREG _S_IFREG
00073 #endif
00074 
00075 /* Read permission */
00076 #if !defined(S_IREAD)
00077 #   define S_IREAD _S_IREAD
00078 #endif
00079 
00080 /* Write permission */
00081 #if !defined(S_IWRITE)
00082 #   define S_IWRITE _S_IWRITE
00083 #endif
00084 
00085 /* Execute permission */
00086 #if !defined(S_IEXEC)
00087 #   define S_IEXEC _S_IEXEC
00088 #endif
00089 
00090 /* Pipe */
00091 #if !defined(S_IFIFO)
00092 #   define S_IFIFO _S_IFIFO
00093 #endif
00094 
00095 /* Block device */
00096 #if !defined(S_IFBLK)
00097 #   define S_IFBLK 0
00098 #endif
00099 
00100 /* Link */
00101 #if !defined(S_IFLNK)
00102 #   define S_IFLNK 0
00103 #endif
00104 
00105 /* Socket */
00106 #if !defined(S_IFSOCK)
00107 #   define S_IFSOCK 0
00108 #endif
00109 
00110 /* Read user permission */
00111 #if !defined(S_IRUSR)
00112 #   define S_IRUSR S_IREAD
00113 #endif
00114 
00115 /* Write user permission */
00116 #if !defined(S_IWUSR)
00117 #   define S_IWUSR S_IWRITE
00118 #endif
00119 
00120 /* Execute user permission */
00121 #if !defined(S_IXUSR)
00122 #   define S_IXUSR 0
00123 #endif
00124 
00125 /* Read group permission */
00126 #if !defined(S_IRGRP)
00127 #   define S_IRGRP 0
00128 #endif
00129 
00130 /* Write group permission */
00131 #if !defined(S_IWGRP)
00132 #   define S_IWGRP 0
00133 #endif
00134 
00135 /* Execute group permission */
00136 #if !defined(S_IXGRP)
00137 #   define S_IXGRP 0
00138 #endif
00139 
00140 /* Read others permission */
00141 #if !defined(S_IROTH)
00142 #   define S_IROTH 0
00143 #endif
00144 
00145 /* Write others permission */
00146 #if !defined(S_IWOTH)
00147 #   define S_IWOTH 0
00148 #endif
00149 
00150 /* Execute others permission */
00151 #if !defined(S_IXOTH)
00152 #   define S_IXOTH 0
00153 #endif
00154 
00155 /* Maximum length of file name */
00156 #if !defined(PATH_MAX)
00157 #   define PATH_MAX MAX_PATH
00158 #endif
00159 #if !defined(FILENAME_MAX)
00160 #   define FILENAME_MAX MAX_PATH
00161 #endif
00162 #if !defined(NAME_MAX)
00163 #   define NAME_MAX FILENAME_MAX
00164 #endif
00165 
00166 /* File type flags for d_type */
00167 #define DT_UNKNOWN 0
00168 #define DT_REG S_IFREG
00169 #define DT_DIR S_IFDIR
00170 #define DT_FIFO S_IFIFO
00171 #define DT_SOCK S_IFSOCK
00172 #define DT_CHR S_IFCHR
00173 #define DT_BLK S_IFBLK
00174 #define DT_LNK S_IFLNK
00175 
00176 /* Macros for converting between st_mode and d_type */
00177 #define IFTODT(mode) ((mode) & S_IFMT)
00178 #define DTTOIF(type) (type)
00179 
00180 /*
00181  * File type macros.  Note that block devices, sockets and links cannot be
00182  * distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
00183  * only defined for compatibility.  These macros should always return false
00184  * on Windows.
00185  */
00186 #if !defined(S_ISFIFO)
00187 #   define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
00188 #endif
00189 #if !defined(S_ISDIR)
00190 #   define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
00191 #endif
00192 #if !defined(S_ISREG)
00193 #   define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
00194 #endif
00195 #if !defined(S_ISLNK)
00196 #   define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
00197 #endif
00198 #if !defined(S_ISSOCK)
00199 #   define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
00200 #endif
00201 #if !defined(S_ISCHR)
00202 #   define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
00203 #endif
00204 #if !defined(S_ISBLK)
00205 #   define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
00206 #endif
00207 
00208 /* Return the exact length of d_namlen without zero terminator */
00209 #define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
00210 
00211 /* Return number of bytes needed to store d_namlen */
00212 #define _D_ALLOC_NAMLEN(p) (PATH_MAX)
00213 
00214 
00215 #ifdef __cplusplus
00216 extern "C" {
00217 #endif
00218 
00219 
00220 /* Wide-character version */
00221 struct _wdirent {
00222     /* Always zero */
00223     long d_ino;
00224 
00225     /* Structure size */
00226     unsigned short d_reclen;
00227 
00228     /* Length of name without \0 */
00229     size_t d_namlen;
00230 
00231     /* File type */
00232     int d_type;
00233 
00234     /* File name */
00235     wchar_t d_name[PATH_MAX];
00236 };
00237 typedef struct _wdirent _wdirent;
00238 
00239 struct _WDIR {
00240     /* Current directory entry */
00241     struct _wdirent ent;
00242 
00243     /* Private file data */
00244     WIN32_FIND_DATAW data;
00245 
00246     /* True if data is valid */
00247     int cached;
00248 
00249     /* Win32 search handle */
00250     HANDLE handle;
00251 
00252     /* Initial directory name */
00253     wchar_t *patt;
00254 };
00255 typedef struct _WDIR _WDIR;
00256 
00257 static _WDIR *_wopendir (const wchar_t *dirname);
00258 static struct _wdirent *_wreaddir (_WDIR *dirp);
00259 static int _wclosedir (_WDIR *dirp);
00260 static void _wrewinddir (_WDIR* dirp);
00261 
00262 
00263 /* For compatibility with Symbian */
00264 #define wdirent _wdirent
00265 #define WDIR _WDIR
00266 #define wopendir _wopendir
00267 #define wreaddir _wreaddir
00268 #define wclosedir _wclosedir
00269 #define wrewinddir _wrewinddir
00270 
00271 
00272 /* Multi-byte character versions */
00273 struct dirent {
00274     /* Always zero */
00275     long d_ino;
00276 
00277     /* Structure size */
00278     unsigned short d_reclen;
00279 
00280     /* Length of name without \0 */
00281     size_t d_namlen;
00282 
00283     /* File type */
00284     int d_type;
00285 
00286     /* File name */
00287     char d_name[PATH_MAX];
00288 };
00289 typedef struct dirent dirent;
00290 
00291 struct DIR {
00292     struct dirent ent;
00293     struct _WDIR *wdirp;
00294 };
00295 typedef struct DIR DIR;
00296 
00297 static DIR *opendir (const char *dirname);
00298 static struct dirent *readdir (DIR *dirp);
00299 static int closedir (DIR *dirp);
00300 static void rewinddir (DIR* dirp);
00301 
00302 
00303 /* Internal utility functions */
00304 static WIN32_FIND_DATAW *dirent_first (_WDIR *dirp);
00305 static WIN32_FIND_DATAW *dirent_next (_WDIR *dirp);
00306 
00307 static int dirent_mbstowcs_s(
00308     size_t *pReturnValue,
00309     wchar_t *wcstr,
00310     size_t sizeInWords,
00311     const char *mbstr,
00312     size_t count);
00313 
00314 static int dirent_wcstombs_s(
00315     size_t *pReturnValue,
00316     char *mbstr,
00317     size_t sizeInBytes,
00318     const wchar_t *wcstr,
00319     size_t count);
00320 
00321 static void dirent_set_errno (int error);
00322 
00323 /*
00324  * Open directory stream DIRNAME for read and return a pointer to the
00325  * internal working area that is used to retrieve individual directory
00326  * entries.
00327  */
00328 static _WDIR*
00329 _wopendir(
00330     const wchar_t *dirname)
00331 {
00332     _WDIR *dirp = NULL;
00333     int error;
00334 
00335     /* Must have directory name */
00336     if (dirname == NULL  ||  dirname[0] == '\0') {
00337         dirent_set_errno (ENOENT);
00338         return NULL;
00339     }
00340 
00341     /* Allocate new _WDIR structure */
00342     dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
00343     if (dirp != NULL) {
00344         DWORD n;
00345 
00346         /* Reset _WDIR structure */
00347         dirp->handle = INVALID_HANDLE_VALUE;
00348         dirp->patt = NULL;
00349         dirp->cached = 0;
00350 
00351         /* Compute the length of full path plus zero terminator */
00352         n = GetFullPathNameW (dirname, 0, NULL, NULL);
00353 
00354         /* Allocate room for absolute directory name and search pattern */
00355         dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
00356         if (dirp->patt) {
00357 
00358             /*
00359              * Convert relative directory name to an absolute one.  This
00360              * allows rewinddir() to function correctly even when current
00361              * working directory is changed between opendir() and rewinddir().
00362              */
00363             n = GetFullPathNameW (dirname, n, dirp->patt, NULL);
00364             if (n > 0) {
00365                 wchar_t *p;
00366 
00367                 /* Append search pattern \* to the directory name */
00368                 p = dirp->patt + n;
00369                 if (dirp->patt < p) {
00370                     switch (p[-1]) {
00371                     case '\\':
00372                     case '/':
00373                     case ':':
00374                         /* Directory ends in path separator, e.g. c:\temp\ */
00375                         /*NOP*/;
00376                         break;
00377 
00378                     default:
00379                         /* Directory name doesn't end in path separator */
00380                         *p++ = '\\';
00381                     }
00382                 }
00383                 *p++ = '*';
00384                 *p = '\0';
00385 
00386                 /* Open directory stream and retrieve the first entry */
00387                 if (dirent_first (dirp)) {
00388                     /* Directory stream opened successfully */
00389                     error = 0;
00390                 } else {
00391                     /* Cannot retrieve first entry */
00392                     error = 1;
00393                     dirent_set_errno (ENOENT);
00394                 }
00395 
00396             } else {
00397                 /* Cannot retrieve full path name */
00398                 dirent_set_errno (ENOENT);
00399                 error = 1;
00400             }
00401 
00402         } else {
00403             /* Cannot allocate memory for search pattern */
00404             error = 1;
00405         }
00406 
00407     } else {
00408         /* Cannot allocate _WDIR structure */
00409         error = 1;
00410     }
00411 
00412     /* Clean up in case of error */
00413     if (error  &&  dirp) {
00414         _wclosedir (dirp);
00415         dirp = NULL;
00416     }
00417 
00418     return dirp;
00419 }
00420 
00421 /*
00422  * Read next directory entry.  The directory entry is returned in dirent
00423  * structure in the d_name field.  Individual directory entries returned by
00424  * this function include regular files, sub-directories, pseudo-directories
00425  * "." and ".." as well as volume labels, hidden files and system files.
00426  */
00427 static struct _wdirent*
00428 _wreaddir(
00429     _WDIR *dirp)
00430 {
00431     WIN32_FIND_DATAW *datap;
00432     struct _wdirent *entp;
00433 
00434     /* Read next directory entry */
00435     datap = dirent_next (dirp);
00436     if (datap) {
00437         size_t n;
00438         DWORD attr;
00439         
00440         /* Pointer to directory entry to return */
00441         entp = &dirp->ent;
00442 
00443         /* 
00444          * Copy file name as wide-character string.  If the file name is too
00445          * long to fit in to the destination buffer, then truncate file name
00446          * to PATH_MAX characters and zero-terminate the buffer.
00447          */
00448         n = 0;
00449         while (n + 1 < PATH_MAX  &&  datap->cFileName[n] != 0) {
00450             entp->d_name[n] = datap->cFileName[n];
00451             n++;
00452         }
00453         dirp->ent.d_name[n] = 0;
00454 
00455         /* Length of file name excluding zero terminator */
00456         entp->d_namlen = n;
00457 
00458         /* File type */
00459         attr = datap->dwFileAttributes;
00460         if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
00461             entp->d_type = DT_CHR;
00462         } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
00463             entp->d_type = DT_DIR;
00464         } else {
00465             entp->d_type = DT_REG;
00466         }
00467 
00468         /* Reset dummy fields */
00469         entp->d_ino = 0;
00470         entp->d_reclen = sizeof (struct _wdirent);
00471 
00472     } else {
00473 
00474         /* Last directory entry read */
00475         entp = NULL;
00476 
00477     }
00478 
00479     return entp;
00480 }
00481 
00482 /*
00483  * Close directory stream opened by opendir() function.  This invalidates the
00484  * DIR structure as well as any directory entry read previously by
00485  * _wreaddir().
00486  */
00487 static int
00488 _wclosedir(
00489     _WDIR *dirp)
00490 {
00491     int ok;
00492     if (dirp) {
00493 
00494         /* Release search handle */
00495         if (dirp->handle != INVALID_HANDLE_VALUE) {
00496             FindClose (dirp->handle);
00497             dirp->handle = INVALID_HANDLE_VALUE;
00498         }
00499 
00500         /* Release search pattern */
00501         if (dirp->patt) {
00502             free (dirp->patt);
00503             dirp->patt = NULL;
00504         }
00505 
00506         /* Release directory structure */
00507         free (dirp);
00508         ok = /*success*/0;
00509 
00510     } else {
00511         /* Invalid directory stream */
00512         dirent_set_errno (EBADF);
00513         ok = /*failure*/-1;
00514     }
00515     return ok;
00516 }
00517 
00518 /*
00519  * Rewind directory stream such that _wreaddir() returns the very first
00520  * file name again.
00521  */
00522 static void
00523 _wrewinddir(
00524     _WDIR* dirp)
00525 {
00526     if (dirp) {
00527         /* Release existing search handle */
00528         if (dirp->handle != INVALID_HANDLE_VALUE) {
00529             FindClose (dirp->handle);
00530         }
00531 
00532         /* Open new search handle */
00533         dirent_first (dirp);
00534     }
00535 }
00536 
00537 /* Get first directory entry (internal) */
00538 static WIN32_FIND_DATAW*
00539 dirent_first(
00540     _WDIR *dirp)
00541 {
00542     WIN32_FIND_DATAW *datap;
00543 
00544     /* Open directory and retrieve the first entry */
00545     dirp->handle = FindFirstFileW (dirp->patt, &dirp->data);
00546     if (dirp->handle != INVALID_HANDLE_VALUE) {
00547 
00548         /* a directory entry is now waiting in memory */
00549         datap = &dirp->data;
00550         dirp->cached = 1;
00551 
00552     } else {
00553 
00554         /* Failed to re-open directory: no directory entry in memory */
00555         dirp->cached = 0;
00556         datap = NULL;
00557 
00558     }
00559     return datap;
00560 }
00561 
00562 /* Get next directory entry (internal) */
00563 static WIN32_FIND_DATAW*
00564 dirent_next(
00565     _WDIR *dirp)
00566 {
00567     WIN32_FIND_DATAW *p;
00568 
00569     /* Get next directory entry */
00570     if (dirp->cached != 0) {
00571 
00572         /* A valid directory entry already in memory */
00573         p = &dirp->data;
00574         dirp->cached = 0;
00575 
00576     } else if (dirp->handle != INVALID_HANDLE_VALUE) {
00577 
00578         /* Get the next directory entry from stream */
00579         if (FindNextFileW (dirp->handle, &dirp->data) != FALSE) {
00580             /* Got a file */
00581             p = &dirp->data;
00582         } else {
00583             /* The very last entry has been processed or an error occured */
00584             FindClose (dirp->handle);
00585             dirp->handle = INVALID_HANDLE_VALUE;
00586             p = NULL;
00587         }
00588 
00589     } else {
00590 
00591         /* End of directory stream reached */
00592         p = NULL;
00593 
00594     }
00595 
00596     return p;
00597 }
00598 
00599 /* 
00600  * Open directory stream using plain old C-string.
00601  */
00602 static DIR*
00603 opendir(
00604     const char *dirname) 
00605 {
00606     struct DIR *dirp;
00607     int error;
00608 
00609     /* Must have directory name */
00610     if (dirname == NULL  ||  dirname[0] == '\0') {
00611         dirent_set_errno (ENOENT);
00612         return NULL;
00613     }
00614 
00615     /* Allocate memory for DIR structure */
00616     dirp = (DIR*) malloc (sizeof (struct DIR));
00617     if (dirp) {
00618         wchar_t wname[PATH_MAX];
00619         size_t n;
00620 
00621         /* Convert directory name to wide-character string */
00622         error = dirent_mbstowcs_s (&n, wname, PATH_MAX, dirname, PATH_MAX);
00623         if (!error) {
00624 
00625             /* Open directory stream using wide-character name */
00626             dirp->wdirp = _wopendir (wname);
00627             if (dirp->wdirp) {
00628                 /* Directory stream opened */
00629                 error = 0;
00630             } else {
00631                 /* Failed to open directory stream */
00632                 error = 1;
00633             }
00634 
00635         } else {
00636             /* 
00637              * Cannot convert file name to wide-character string.  This
00638              * occurs if the string contains invalid multi-byte sequences or
00639              * the output buffer is too small to contain the resulting
00640              * string.
00641              */
00642             error = 1;
00643         }
00644 
00645     } else {
00646         /* Cannot allocate DIR structure */
00647         error = 1;
00648     }
00649 
00650     /* Clean up in case of error */
00651     if (error  &&  dirp) {
00652         free (dirp);
00653         dirp = NULL;
00654     }
00655 
00656     return dirp;
00657 }
00658 
00659 /*
00660  * Read next directory entry.
00661  *
00662  * When working with text consoles, please note that file names returned by
00663  * readdir() are represented in the default ANSI code page while any output to
00664  * console is typically formatted on another code page.  Thus, non-ASCII
00665  * characters in file names will not usually display correctly on console.  The
00666  * problem can be fixed in two ways: (1) change the character set of console
00667  * to 1252 using chcp utility and use Lucida Console font, or (2) use
00668  * _cprintf function when writing to console.  The _cprinf() will re-encode
00669  * ANSI strings to the console code page so many non-ASCII characters will
00670  * display correcly.
00671  */
00672 static struct dirent*
00673 readdir(
00674     DIR *dirp) 
00675 {
00676     WIN32_FIND_DATAW *datap;
00677     struct dirent *entp;
00678 
00679     /* Read next directory entry */
00680     datap = dirent_next (dirp->wdirp);
00681     if (datap) {
00682         size_t n;
00683         int error;
00684 
00685         /* Attempt to convert file name to multi-byte string */
00686         error = dirent_wcstombs_s(
00687             &n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
00688 
00689         /* 
00690          * If the file name cannot be represented by a multi-byte string,
00691          * then attempt to use old 8+3 file name.  This allows traditional
00692          * Unix-code to access some file names despite of unicode
00693          * characters, although file names may seem unfamiliar to the user.
00694          *
00695          * Be ware that the code below cannot come up with a short file
00696          * name unless the file system provides one.  At least
00697          * VirtualBox shared folders fail to do this.
00698          */
00699         if (error  &&  datap->cAlternateFileName[0] != '\0') {
00700             error = dirent_wcstombs_s(
00701                 &n, dirp->ent.d_name, PATH_MAX, 
00702                 datap->cAlternateFileName, PATH_MAX);
00703         }
00704 
00705         if (!error) {
00706             DWORD attr;
00707 
00708             /* Initialize directory entry for return */
00709             entp = &dirp->ent;
00710 
00711             /* Length of file name excluding zero terminator */
00712             entp->d_namlen = n - 1;
00713 
00714             /* File attributes */
00715             attr = datap->dwFileAttributes;
00716             if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
00717                 entp->d_type = DT_CHR;
00718             } else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
00719                 entp->d_type = DT_DIR;
00720             } else {
00721                 entp->d_type = DT_REG;
00722             }
00723 
00724             /* Reset dummy fields */
00725             entp->d_ino = 0;
00726             entp->d_reclen = sizeof (struct dirent);
00727 
00728         } else {
00729             /* 
00730              * Cannot convert file name to multi-byte string so construct
00731              * an errornous directory entry and return that.  Note that
00732              * we cannot return NULL as that would stop the processing
00733              * of directory entries completely.
00734              */
00735             entp = &dirp->ent;
00736             entp->d_name[0] = '?';
00737             entp->d_name[1] = '\0';
00738             entp->d_namlen = 1;
00739             entp->d_type = DT_UNKNOWN;
00740             entp->d_ino = 0;
00741             entp->d_reclen = 0;
00742         }
00743 
00744     } else {
00745         /* No more directory entries */
00746         entp = NULL;
00747     }
00748 
00749     return entp;
00750 }
00751 
00752 /*
00753  * Close directory stream.
00754  */
00755 static int
00756 closedir(
00757     DIR *dirp) 
00758 {
00759     int ok;
00760     if (dirp) {
00761 
00762         /* Close wide-character directory stream */
00763         ok = _wclosedir (dirp->wdirp);
00764         dirp->wdirp = NULL;
00765 
00766         /* Release multi-byte character version */
00767         free (dirp);
00768 
00769     } else {
00770 
00771         /* Invalid directory stream */
00772         dirent_set_errno (EBADF);
00773         ok = /*failure*/-1;
00774 
00775     }
00776     return ok;
00777 }
00778 
00779 /*
00780  * Rewind directory stream to beginning.
00781  */
00782 static void
00783 rewinddir(
00784     DIR* dirp) 
00785 {
00786     /* Rewind wide-character string directory stream */
00787     _wrewinddir (dirp->wdirp);
00788 }
00789 
00790 /* Convert multi-byte string to wide character string */
00791 static int
00792 dirent_mbstowcs_s(
00793     size_t *pReturnValue,
00794     wchar_t *wcstr,
00795     size_t sizeInWords,
00796     const char *mbstr,
00797     size_t count)
00798 {
00799     int error;
00800 
00801 #if defined(_MSC_VER)  &&  _MSC_VER >= 1400
00802 
00803     /* Microsoft Visual Studio 2005 or later */
00804     error = mbstowcs_s (pReturnValue, wcstr, sizeInWords, mbstr, count);
00805 
00806 #else
00807 
00808     /* Older Visual Studio or non-Microsoft compiler */
00809     size_t n;
00810 
00811     /* Convert to wide-character string (or count characters) */
00812     n = mbstowcs (wcstr, mbstr, sizeInWords);
00813     if (!wcstr  ||  n < count) {
00814 
00815         /* Zero-terminate output buffer */
00816         if (wcstr  &&  sizeInWords) {
00817             if (n >= sizeInWords) {
00818                 n = sizeInWords - 1;
00819             }
00820             wcstr[n] = 0;
00821         }
00822 
00823         /* Length of resuting multi-byte string WITH zero terminator */
00824         if (pReturnValue) {
00825             *pReturnValue = n + 1;
00826         }
00827 
00828         /* Success */
00829         error = 0;
00830 
00831     } else {
00832 
00833         /* Could not convert string */
00834         error = 1;
00835 
00836     }
00837 
00838 #endif
00839 
00840     return error;
00841 }
00842 
00843 /* Convert wide-character string to multi-byte string */
00844 static int
00845 dirent_wcstombs_s(
00846     size_t *pReturnValue,
00847     char *mbstr,
00848     size_t sizeInBytes, /* max size of mbstr */
00849     const wchar_t *wcstr,
00850     size_t count)
00851 {
00852     int error;
00853 
00854 #if defined(_MSC_VER)  &&  _MSC_VER >= 1400
00855 
00856     /* Microsoft Visual Studio 2005 or later */
00857     error = wcstombs_s (pReturnValue, mbstr, sizeInBytes, wcstr, count);
00858 
00859 #else
00860 
00861     /* Older Visual Studio or non-Microsoft compiler */
00862     size_t n;
00863 
00864     /* Convert to multi-byte string (or count the number of bytes needed) */
00865     n = wcstombs (mbstr, wcstr, sizeInBytes);
00866     if (!mbstr  ||  n < count) {
00867 
00868         /* Zero-terminate output buffer */
00869         if (mbstr  &&  sizeInBytes) {
00870             if (n >= sizeInBytes) {
00871                 n = sizeInBytes - 1;
00872             }
00873             mbstr[n] = '\0';
00874         }
00875 
00876         /* Lenght of resulting multi-bytes string WITH zero-terminator */
00877         if (pReturnValue) {
00878             *pReturnValue = n + 1;
00879         }
00880 
00881         /* Success */
00882         error = 0;
00883 
00884     } else {
00885 
00886         /* Cannot convert string */
00887         error = 1;
00888 
00889     }
00890 
00891 #endif
00892 
00893     return error;
00894 }
00895 
00896 /* Set errno variable */
00897 static void
00898 dirent_set_errno(
00899     int error)
00900 {
00901 #if defined(_MSC_VER)  &&  _MSC_VER >= 1400
00902 
00903     /* Microsoft Visual Studio 2005 and later */
00904     _set_errno (error);
00905 
00906 #else
00907 
00908     /* Non-Microsoft compiler or older Microsoft compiler */
00909     errno = error;
00910 
00911 #endif
00912 }
00913 
00914 
00915 #ifdef __cplusplus
00916 }
00917 #endif
00918 #endif /*DIRENT_H*/
00919 
 All Classes Files Functions Variables Typedefs Defines