![]() |
CASToR
1.0
Tomographic Reconstruction (PET/SPECT)
|
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