cstdio.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // boost/filesystem/cstdio.hpp ------------------------------------------------------//
  2. // Copyright Andrey Semashev 2023
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // See http://www.boost.org/LICENSE_1_0.txt
  5. // Library home page: http://www.boost.org/libs/filesystem
  6. //--------------------------------------------------------------------------------------//
  7. #ifndef BOOST_FILESYSTEM_CSTDIO_HPP
  8. #define BOOST_FILESYSTEM_CSTDIO_HPP
  9. #include <boost/filesystem/config.hpp>
  10. #include <boost/filesystem/path.hpp>
  11. #include <cstdio>
  12. #if defined(BOOST_WINDOWS_API)
  13. #include <wchar.h>
  14. #include <cstddef>
  15. #include <cstring>
  16. #include <cstdlib>
  17. #endif
  18. #include <boost/filesystem/detail/header.hpp> // must be the last #include
  19. namespace boost {
  20. namespace filesystem {
  21. #if defined(BOOST_WINDOWS_API)
  22. inline std::FILE* fopen(filesystem::path const& p, const char* mode)
  23. {
  24. #if defined(__CYGWIN__) || (defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) && defined(__STRICT_ANSI__))
  25. // Cygwin and MinGW32 in strict ANSI mode do not declare _wfopen
  26. return std::fopen(p.string().c_str(), mode);
  27. #else
  28. // mode should only contain ASCII characters and is likely short
  29. struct small_array
  30. {
  31. wchar_t buf[128u];
  32. wchar_t* p;
  33. small_array() noexcept : p(buf) {}
  34. ~small_array() noexcept
  35. {
  36. if (BOOST_UNLIKELY(p != buf))
  37. std::free(p);
  38. }
  39. }
  40. wmode;
  41. std::size_t wmode_len = std::mbstowcs(wmode.p, mode, sizeof(wmode.buf) / sizeof(wchar_t));
  42. if (BOOST_UNLIKELY(wmode_len >= (sizeof(wmode.buf) / sizeof(wchar_t))))
  43. {
  44. wmode_len = std::mbstowcs(nullptr, mode, 0u);
  45. // Check for size overflow, including (size_t)-1, which indicates mbstowcs error
  46. if (BOOST_UNLIKELY(wmode_len >= (static_cast< std::size_t >(-1) / sizeof(wchar_t))))
  47. return nullptr;
  48. wmode.p = static_cast< wchar_t* >(std::malloc((wmode_len + 1u) * sizeof(wchar_t)));
  49. if (BOOST_UNLIKELY(!wmode.p))
  50. return nullptr;
  51. std::size_t wmode_len2 = std::mbstowcs(wmode.p, mode, wmode_len + 1u);
  52. if (BOOST_UNLIKELY(wmode_len2 > wmode_len))
  53. return nullptr;
  54. }
  55. return ::_wfopen(p.c_str(), wmode.p);
  56. #endif
  57. }
  58. #else // defined(BOOST_WINDOWS_API)
  59. inline std::FILE* fopen(filesystem::path const& p, const char* mode)
  60. {
  61. return std::fopen(p.c_str(), mode);
  62. }
  63. #endif // defined(BOOST_WINDOWS_API)
  64. } // namespace filesystem
  65. } // namespace boost
  66. #include <boost/filesystem/detail/footer.hpp>
  67. #endif // BOOST_FILESYSTEM_CSTDIO_HPP