libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

dirent.cc (4625B)


      1 // Copyright (c) the JPEG XL Project
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //      http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #if defined(_WIN32) || defined(_WIN64)
     16 #include "third_party/dirent.h"
     17 
     18 #include "lib/jxl/base/status.h"
     19 
     20 #ifndef NOMINMAX
     21 #define NOMINMAX
     22 #endif  // NOMINMAX
     23 
     24 #include <errno.h>
     25 #include <windows.h>
     26 
     27 #include <memory>
     28 #include <string>
     29 
     30 int mkdir(const char* path, mode_t /*mode*/) {
     31   const LPSECURITY_ATTRIBUTES sec = nullptr;
     32   if (!CreateDirectory(path, sec)) {
     33     JXL_NOTIFY_ERROR("Failed to create directory %s", path);
     34     return -1;
     35   }
     36   return 0;
     37 }
     38 
     39 // Modified from code bearing the following notice:
     40 // https://trac.wildfiregames.com/browser/ps/trunk/source/lib/sysdep/os/
     41 /* Copyright (C) 2010 Wildfire Games.
     42  *
     43  * Permission is hereby granted, free of charge, to any person obtaining
     44  * a copy of this software and associated documentation files (the
     45  * "Software"), to deal in the Software without restriction, including
     46  * without limitation the rights to use, copy, modify, merge, publish,
     47  * distribute, sublicense, and/or sell copies of the Software, and to
     48  * permit persons to whom the Software is furnished to do so, subject to
     49  * the following conditions:
     50  *
     51  * The above copyright notice and this permission notice shall be included
     52  * in all copies or substantial portions of the Software.
     53  *
     54  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
     55  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     56  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
     57  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
     58  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     59  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     60  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     61  */
     62 
     63 struct DIR {
     64   HANDLE hFind;
     65 
     66   WIN32_FIND_DATA findData;  // indeterminate if hFind == INVALID_HANDLE_VALUE
     67 
     68   // readdir will return the address of this member.
     69   // (must be stored in DIR to allow multiple independent
     70   // opendir/readdir sequences).
     71   dirent ent;
     72 
     73   // used by readdir to skip the first FindNextFile.
     74   size_t numCalls = 0;
     75 };
     76 
     77 static bool IsValidDirectory(const char* path) {
     78   const DWORD fileAttributes = GetFileAttributes(path);
     79 
     80   // path not found
     81   if (fileAttributes == INVALID_FILE_ATTRIBUTES) return false;
     82 
     83   // not a directory
     84   if ((fileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) return false;
     85 
     86   return true;
     87 }
     88 
     89 DIR* opendir(const char* path) {
     90   if (!IsValidDirectory(path)) {
     91     errno = ENOENT;
     92     return nullptr;
     93   }
     94 
     95   std::unique_ptr<DIR> d(new DIR);
     96 
     97   // NB: "c:\\path" only returns information about that directory;
     98   // trailing slashes aren't allowed. append "\\*" to retrieve its entries.
     99   std::string searchPath(path);
    100   if (searchPath.back() != '/' && searchPath.back() != '\\') {
    101     searchPath += '\\';
    102   }
    103   searchPath += '*';
    104 
    105   // (we don't defer FindFirstFile until readdir because callers
    106   // expect us to return 0 if directory reading will/did fail.)
    107   d->hFind = FindFirstFile(searchPath.c_str(), &d->findData);
    108   if (d->hFind != INVALID_HANDLE_VALUE) return d.release();
    109   if (GetLastError() == ERROR_NO_MORE_FILES) return d.release();  // empty
    110 
    111   JXL_NOTIFY_ERROR("Failed to open directory %s", searchPath.c_str());
    112   return nullptr;
    113 }
    114 
    115 int closedir(DIR* dir) {
    116   delete dir;
    117   return 0;
    118 }
    119 
    120 dirent* readdir(DIR* d) {
    121   // "empty" case from opendir
    122   if (d->hFind == INVALID_HANDLE_VALUE) return nullptr;
    123 
    124   // until end of directory or a valid entry was found:
    125   for (;;) {
    126     if (d->numCalls++ != 0)  // (skip first call to FindNextFile - see opendir)
    127     {
    128       if (!FindNextFile(d->hFind, &d->findData)) {
    129         JXL_ASSERT(GetLastError() == ERROR_NO_MORE_FILES);
    130         SetLastError(0);
    131         return nullptr;  // end of directory or error
    132       }
    133     }
    134 
    135     // only return non-hidden and non-system entries
    136     if ((d->findData.dwFileAttributes &
    137          (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == 0) {
    138       d->ent.d_name = d->findData.cFileName;
    139       return &d->ent;
    140     }
    141   }
    142 }
    143 
    144 #endif  // #if defined(_WIN32) || defined(_WIN64)