summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/libs/filesystem/src')
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp84
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/filesystem_utf8_codecvt_facet.cpp27
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/operations.cpp2228
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/path.cpp929
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/path_traits.cpp200
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/portability.cpp119
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/unique_path.cpp142
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.cpp75
-rw-r--r--3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.hpp56
9 files changed, 3860 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp b/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp
new file mode 100644
index 0000000..245c3f3
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/codecvt_error_category.cpp
@@ -0,0 +1,84 @@
+// codecvt_error_category implementation file ----------------------------------------//
+
+// Copyright Beman Dawes 2009
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt)
+
+// Library home page at http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+#include <boost/config/warning_disable.hpp>
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+# define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/path_traits.hpp>
+#include <boost/system/error_code.hpp>
+#include <locale>
+#include <vector>
+#include <cstdlib>
+#include <cassert>
+
+//--------------------------------------------------------------------------------------//
+
+namespace
+{
+ class codecvt_error_cat : public boost::system::error_category
+ {
+ public:
+ codecvt_error_cat(){}
+ const char* name() const;
+ std::string message(int ev) const;
+ };
+
+ const char* codecvt_error_cat::name() const
+ {
+ return "codecvt";
+ }
+
+ std::string codecvt_error_cat::message(int ev) const
+ {
+ std::string str;
+ switch (ev)
+ {
+ case std::codecvt_base::ok:
+ str = "ok";
+ break;
+ case std::codecvt_base::partial:
+ str = "partial";
+ break;
+ case std::codecvt_base::error:
+ str = "error";
+ break;
+ case std::codecvt_base::noconv:
+ str = "noconv";
+ break;
+ default:
+ str = "unknown error";
+ }
+ return str;
+ }
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+ BOOST_FILESYSTEM_DECL const boost::system::error_category& codecvt_error_category()
+ {
+ static const codecvt_error_cat codecvt_error_cat_const;
+ return codecvt_error_cat_const;
+ }
+
+ } // namespace filesystem
+} // namespace boost
diff --git a/3rdParty/Boost/src/libs/filesystem/src/filesystem_utf8_codecvt_facet.cpp b/3rdParty/Boost/src/libs/filesystem/src/filesystem_utf8_codecvt_facet.cpp
new file mode 100644
index 0000000..8a5af1e
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/filesystem_utf8_codecvt_facet.cpp
@@ -0,0 +1,27 @@
+// Copyright Vladimir Prus 2004.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// For HP-UX, request that WCHAR_MAX and WCHAR_MIN be defined as macros,
+// not casts. See ticket 5048
+#define _INCLUDE_STDCSOURCE_199901
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+# define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#define BOOST_FILESYSTEM_SOURCE
+#include <boost/filesystem/config.hpp>
+
+#define BOOST_UTF8_BEGIN_NAMESPACE \
+ namespace boost { namespace filesystem { namespace detail {
+
+#define BOOST_UTF8_END_NAMESPACE }}}
+#define BOOST_UTF8_DECL BOOST_FILESYSTEM_DECL
+
+#include <boost/detail/utf8_codecvt_facet.ipp>
+
+#undef BOOST_UTF8_BEGIN_NAMESPACE
+#undef BOOST_UTF8_END_NAMESPACE
+#undef BOOST_UTF8_DECL
diff --git a/3rdParty/Boost/src/libs/filesystem/src/operations.cpp b/3rdParty/Boost/src/libs/filesystem/src/operations.cpp
new file mode 100644
index 0000000..16a336f
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/operations.cpp
@@ -0,0 +1,2228 @@
+// operations.cpp --------------------------------------------------------------------//
+
+// Copyright 2002-2009 Beman Dawes
+// Copyright 2001 Dietmar Kuehl
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+// define 64-bit offset macros BEFORE including boost/config.hpp (see ticket #5355)
+#if !(defined(__HP_aCC) && defined(_ILP32) && !defined(_STATVFS_ACPP_PROBLEMS_FIXED))
+#define _FILE_OFFSET_BITS 64 // at worst, these defines may have no effect,
+#endif
+#if !defined(__PGI)
+#define __USE_FILE_OFFSET64 // but that is harmless on Windows and on POSIX
+ // 64-bit systems or on 32-bit systems which don't have files larger
+ // than can be represented by a traditional POSIX/UNIX off_t type.
+ // OTOH, defining them should kick in 64-bit off_t's (and thus
+ // st_size)on 32-bit systems that provide the Large File
+ // Support (LFS)interface, such as Linux, Solaris, and IRIX.
+ // The defines are given before any headers are included to
+ // ensure that they are available to all included headers.
+ // That is required at least on Solaris, and possibly on other
+ // systems as well.
+#else
+#define _FILE_OFFSET_BITS 64
+#endif
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+# define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS // Sun readdir_r()needs this
+#endif
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/detail/workaround.hpp>
+#include <vector>
+#include <cstdlib> // for malloc, free
+#include <cstring>
+#include <cstdio> // for remove, rename
+#if defined(__QNXNTO__) // see ticket #5355
+# include <stdio.h>
+#endif
+#include <cerrno>
+
+#ifdef BOOST_FILEYSTEM_INCLUDE_IOSTREAM
+# include <iostream>
+#endif
+
+namespace fs = boost::filesystem;
+using boost::filesystem::path;
+using boost::filesystem::filesystem_error;
+using boost::filesystem::perms;
+using boost::system::error_code;
+using boost::system::error_category;
+using boost::system::system_category;
+using std::string;
+using std::wstring;
+
+# ifdef BOOST_POSIX_API
+
+ const fs::path dot_path(".");
+ const fs::path dot_dot_path("..");
+# include <sys/types.h>
+# include <sys/stat.h>
+# if !defined(__APPLE__) && !defined(__OpenBSD__)
+# include <sys/statvfs.h>
+# define BOOST_STATVFS statvfs
+# define BOOST_STATVFS_F_FRSIZE vfs.f_frsize
+# else
+# ifdef __OpenBSD__
+# include <sys/param.h>
+# endif
+# include <sys/mount.h>
+# define BOOST_STATVFS statfs
+# define BOOST_STATVFS_F_FRSIZE static_cast<boost::uintmax_t>(vfs.f_bsize)
+# endif
+# include <dirent.h>
+# include <unistd.h>
+# include <fcntl.h>
+# include <utime.h>
+# include "limits.h"
+
+# else // BOOST_WINDOW_API
+
+ const fs::path dot_path(L".");
+ const fs::path dot_dot_path(L"..");
+# if (defined(__MINGW32__) || defined(__CYGWIN__)) && !defined(WINVER)
+ // Versions of MinGW or Cygwin that support Filesystem V3 support at least WINVER 0x501.
+ // See MinGW's windef.h
+# define WINVER 0x501
+# endif
+# include <io.h>
+# include <windows.h>
+# include <winnt.h>
+# if !defined(_WIN32_WINNT)
+# define _WIN32_WINNT 0x0500
+# endif
+# if defined(__BORLANDC__) || defined(__MWERKS__)
+# if defined(__BORLANDC__)
+ using std::time_t;
+# endif
+# include <utime.h>
+# else
+# include <sys/utime.h>
+# endif
+
+// REPARSE_DATA_BUFFER related definitions are found in ntifs.h, which is part of the
+// Windows Device Driver Kit. Since that's inconvenient, the definitions are provided
+// here. See http://msdn.microsoft.com/en-us/library/ms791514.aspx
+
+#if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) // mingw winnt.h does provide the defs
+
+#define SYMLINK_FLAG_RELATIVE 1
+
+typedef struct _REPARSE_DATA_BUFFER {
+ ULONG ReparseTag;
+ USHORT ReparseDataLength;
+ USHORT Reserved;
+ union {
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ ULONG Flags;
+ WCHAR PathBuffer[1];
+ /* Example of distinction between substitute and print names:
+ mklink /d ldrive c:\
+ SubstituteName: c:\\??\
+ PrintName: c:\
+ */
+ } SymbolicLinkReparseBuffer;
+ struct {
+ USHORT SubstituteNameOffset;
+ USHORT SubstituteNameLength;
+ USHORT PrintNameOffset;
+ USHORT PrintNameLength;
+ WCHAR PathBuffer[1];
+ } MountPointReparseBuffer;
+ struct {
+ UCHAR DataBuffer[1];
+ } GenericReparseBuffer;
+ };
+} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
+
+#define REPARSE_DATA_BUFFER_HEADER_SIZE \
+ FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
+
+#endif
+
+#ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE
+#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE ( 16 * 1024 )
+#endif
+
+# ifndef FSCTL_GET_REPARSE_POINT
+# define FSCTL_GET_REPARSE_POINT 0x900a8
+# endif
+
+# ifndef IO_REPARSE_TAG_SYMLINK
+# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
+# endif
+
+# endif // BOOST_WINDOWS_API
+
+// BOOST_FILESYSTEM_STATUS_CACHE enables file_status cache in
+// dir_itr_increment. The config tests are placed here because some of the
+// macros being tested come from dirent.h.
+//
+// TODO: find out what macros indicate dirent::d_type present in more libraries
+# if defined(BOOST_WINDOWS_API)\
+ || defined(_DIRENT_HAVE_D_TYPE)// defined by GNU C library if d_type present
+# define BOOST_FILESYSTEM_STATUS_CACHE
+# endif
+
+// POSIX/Windows macros ----------------------------------------------------//
+
+// Portions of the POSIX and Windows API's are very similar, except for name,
+// order of arguments, and meaning of zero/non-zero returns. The macros below
+// abstract away those differences. They follow Windows naming and order of
+// arguments, and return true to indicate no error occurred. [POSIX naming,
+// order of arguments, and meaning of return were followed initially, but
+// found to be less clear and cause more coding errors.]
+
+# if defined(BOOST_POSIX_API)
+
+// POSIX uses a 0 return to indicate success
+# define BOOST_ERRNO errno
+# define BOOST_SET_CURRENT_DIRECTORY(P)(::chdir(P)== 0)
+# define BOOST_CREATE_DIRECTORY(P)(::mkdir(P, S_IRWXU|S_IRWXG|S_IRWXO)== 0)
+# define BOOST_CREATE_HARD_LINK(F,T)(::link(T, F)== 0)
+# define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag)(::symlink(T, F)== 0)
+# define BOOST_REMOVE_DIRECTORY(P)(::rmdir(P)== 0)
+# define BOOST_DELETE_FILE(P)(::unlink(P)== 0)
+# define BOOST_COPY_DIRECTORY(F,T)(!(::stat(from.c_str(), &from_stat)!= 0\
+ || ::mkdir(to.c_str(),from_stat.st_mode)!= 0))
+# define BOOST_COPY_FILE(F,T,FailIfExistsBool)copy_file_api(F, T, FailIfExistsBool)
+# define BOOST_MOVE_FILE(OLD,NEW)(::rename(OLD, NEW)== 0)
+# define BOOST_RESIZE_FILE(P,SZ)(::truncate(P, SZ)== 0)
+
+# define BOOST_ERROR_NOT_SUPPORTED ENOSYS
+# define BOOST_ERROR_ALREADY_EXISTS EEXIST
+
+# else // BOOST_WINDOWS_API
+
+// Windows uses a non-0 return to indicate success
+# define BOOST_ERRNO ::GetLastError()
+# define BOOST_SET_CURRENT_DIRECTORY(P)(::SetCurrentDirectoryW(P)!= 0)
+# define BOOST_CREATE_DIRECTORY(P)(::CreateDirectoryW(P, 0)!= 0)
+# define BOOST_CREATE_HARD_LINK(F,T)(create_hard_link_api(F, T, 0)!= 0)
+# define BOOST_CREATE_SYMBOLIC_LINK(F,T,Flag)(create_symbolic_link_api(F, T, Flag)!= 0)
+# define BOOST_REMOVE_DIRECTORY(P)(::RemoveDirectoryW(P)!= 0)
+# define BOOST_DELETE_FILE(P)(::DeleteFileW(P)!= 0)
+# define BOOST_COPY_DIRECTORY(F,T)(::CreateDirectoryExW(F, T, 0)!= 0)
+# define BOOST_COPY_FILE(F,T,FailIfExistsBool)(::CopyFileW(F, T, FailIfExistsBool)!= 0)
+# define BOOST_MOVE_FILE(OLD,NEW)(::MoveFileExW(OLD, NEW, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED)!= 0)
+# define BOOST_RESIZE_FILE(P,SZ)(resize_file_api(P, SZ)!= 0)
+# define BOOST_READ_SYMLINK(P,T)
+
+# define BOOST_ERROR_ALREADY_EXISTS ERROR_ALREADY_EXISTS
+# define BOOST_ERROR_NOT_SUPPORTED ERROR_NOT_SUPPORTED
+
+# endif
+
+//--------------------------------------------------------------------------------------//
+// //
+// helpers (all operating systems) //
+// //
+//--------------------------------------------------------------------------------------//
+
+namespace
+{
+
+ fs::file_type query_file_type(const path& p, error_code* ec);
+
+ boost::filesystem::directory_iterator end_dir_itr;
+
+ const std::size_t buf_size(128);
+ const error_code ok;
+
+ bool error(bool was_error, error_code* ec, const string& message)
+ {
+ if (!was_error)
+ {
+ if (ec != 0) ec->clear();
+ }
+ else
+ { // error
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(message,
+ error_code(BOOST_ERRNO, system_category())));
+ else
+ ec->assign(BOOST_ERRNO, system_category());
+ }
+ return was_error;
+ }
+
+ bool error(bool was_error, const path& p, error_code* ec, const string& message)
+ {
+ if (!was_error)
+ {
+ if (ec != 0) ec->clear();
+ }
+ else
+ { // error
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(message,
+ p, error_code(BOOST_ERRNO, system_category())));
+ else
+ ec->assign(BOOST_ERRNO, system_category());
+ }
+ return was_error;
+ }
+
+ bool error(bool was_error, const path& p1, const path& p2, error_code* ec,
+ const string& message)
+ {
+ if (!was_error)
+ {
+ if (ec != 0) ec->clear();
+ }
+ else
+ { // error
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(message,
+ p1, p2, error_code(BOOST_ERRNO, system_category())));
+ else
+ ec->assign(BOOST_ERRNO, system_category());
+ }
+ return was_error;
+ }
+
+ bool error(bool was_error, const error_code& result,
+ const path& p, error_code* ec, const string& message)
+ // Overwrites ec if there has already been an error
+ {
+ if (!was_error)
+ {
+ if (ec != 0) ec->clear();
+ }
+ else
+ { // error
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(message, p, result));
+ else
+ *ec = result;
+ }
+ return was_error;
+ }
+
+ bool error(bool was_error, const error_code& result,
+ const path& p1, const path& p2, error_code* ec, const string& message)
+ // Overwrites ec if there has already been an error
+ {
+ if (!was_error)
+ {
+ if (ec != 0) ec->clear();
+ }
+ else
+ { // error
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(message, p1, p2, result));
+ else
+ *ec = result;
+ }
+ return was_error;
+ }
+
+ bool is_empty_directory(const path& p)
+ {
+ return fs::directory_iterator(p)== end_dir_itr;
+ }
+
+ bool remove_directory(const path& p) // true if succeeds
+ { return BOOST_REMOVE_DIRECTORY(p.c_str()); }
+
+ bool remove_file(const path& p) // true if succeeds
+ { return BOOST_DELETE_FILE(p.c_str()); }
+
+ // called by remove and remove_all_aux
+ bool remove_file_or_directory(const path& p, fs::file_type type, error_code* ec)
+ // return true if file removed, false if not removed
+ {
+ if (type == fs::file_not_found)
+ {
+ if (ec != 0) ec->clear();
+ return false;
+ }
+
+ if (type == fs::directory_file
+# ifdef BOOST_WINDOWS_API
+ || type == fs::_detail_directory_symlink
+# endif
+ )
+ {
+ if (error(!remove_directory(p), p, ec, "boost::filesystem::remove"))
+ return false;
+ }
+ else
+ {
+ if (error(!remove_file(p), p, ec, "boost::filesystem::remove"))
+ return false;
+ }
+ return true;
+ }
+
+ boost::uintmax_t remove_all_aux(const path& p, fs::file_type type,
+ error_code* ec)
+ {
+ boost::uintmax_t count = 1;
+
+ if (type == fs::directory_file) // but not a directory symlink
+ {
+ for (fs::directory_iterator itr(p);
+ itr != end_dir_itr; ++itr)
+ {
+ fs::file_type tmp_type = query_file_type(itr->path(), ec);
+ if (ec != 0 && *ec)
+ return count;
+ count += remove_all_aux(itr->path(), tmp_type, ec);
+ }
+ }
+ remove_file_or_directory(p, type, ec);
+ return count;
+ }
+
+#ifdef BOOST_POSIX_API
+
+//--------------------------------------------------------------------------------------//
+// //
+// POSIX-specific helpers //
+// //
+//--------------------------------------------------------------------------------------//
+
+ const char dot = '.';
+
+ bool not_found_error(int errval)
+ {
+ return errno == ENOENT || errno == ENOTDIR;
+ }
+
+ bool // true if ok
+ copy_file_api(const std::string& from_p,
+ const std::string& to_p, bool fail_if_exists)
+ {
+ const std::size_t buf_sz = 32768;
+ boost::scoped_array<char> buf(new char [buf_sz]);
+ int infile=-1, outfile=-1; // -1 means not open
+
+ // bug fixed: code previously did a stat()on the from_file first, but that
+ // introduced a gratuitous race condition; the stat()is now done after the open()
+
+ if ((infile = ::open(from_p.c_str(), O_RDONLY))< 0)
+ { return false; }
+
+ struct stat from_stat;
+ if (::stat(from_p.c_str(), &from_stat)!= 0)
+ {
+ ::close(infile);
+ return false;
+ }
+
+ int oflag = O_CREAT | O_WRONLY | O_TRUNC;
+ if (fail_if_exists)
+ oflag |= O_EXCL;
+ if ((outfile = ::open(to_p.c_str(), oflag, from_stat.st_mode))< 0)
+ {
+ int open_errno = errno;
+ BOOST_ASSERT(infile >= 0);
+ ::close(infile);
+ errno = open_errno;
+ return false;
+ }
+
+ ssize_t sz, sz_read=1, sz_write;
+ while (sz_read > 0
+ && (sz_read = ::read(infile, buf.get(), buf_sz))> 0)
+ {
+ // Allow for partial writes - see Advanced Unix Programming (2nd Ed.),
+ // Marc Rochkind, Addison-Wesley, 2004, page 94
+ sz_write = 0;
+ do
+ {
+ if ((sz = ::write(outfile, buf.get() + sz_write,
+ sz_read - sz_write))< 0)
+ {
+ sz_read = sz; // cause read loop termination
+ break; // and error to be thrown after closes
+ }
+ sz_write += sz;
+ } while (sz_write < sz_read);
+ }
+
+ if (::close(infile)< 0)sz_read = -1;
+ if (::close(outfile)< 0)sz_read = -1;
+
+ return sz_read >= 0;
+ }
+
+ inline fs::file_type query_file_type(const path& p, error_code* ec)
+ {
+ return fs::detail::symlink_status(p, ec).type();
+ }
+
+# else
+
+//--------------------------------------------------------------------------------------//
+// //
+// Windows-specific helpers //
+// //
+//--------------------------------------------------------------------------------------//
+
+ const wchar_t dot = L'.';
+
+ bool not_found_error(int errval)
+ {
+ return errval == ERROR_FILE_NOT_FOUND
+ || errval == ERROR_PATH_NOT_FOUND
+ || errval == ERROR_INVALID_NAME // "tools/jam/src/:sys:stat.h", "//foo"
+ || errval == ERROR_INVALID_DRIVE // USB card reader with no card inserted
+ || errval == ERROR_NOT_READY // CD/DVD drive with no disc inserted
+ || errval == ERROR_INVALID_PARAMETER // ":sys:stat.h"
+ || errval == ERROR_BAD_PATHNAME // "//nosuch" on Win64
+ || errval == ERROR_BAD_NETPATH; // "//nosuch" on Win32
+ }
+
+// some distributions of mingw as early as GLIBCXX__ 20110325 have _stricmp, but the
+// offical 4.6.2 release with __GLIBCXX__ 20111026 doesn't. Play it safe for now, and
+// only use _stricmp if _MSC_VER is defined
+#if defined(_MSC_VER) // || (defined(__GLIBCXX__) && __GLIBCXX__ >= 20110325)
+# define BOOST_FILESYSTEM_STRICMP _stricmp
+#else
+# define BOOST_FILESYSTEM_STRICMP strcmp
+#endif
+
+ perms make_permissions(const path& p, DWORD attr)
+ {
+ perms prms = fs::owner_read | fs::group_read | fs::others_read;
+ if ((attr & FILE_ATTRIBUTE_READONLY) == 0)
+ prms |= fs::owner_write | fs::group_write | fs::others_write;
+ if (BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".exe") == 0
+ || BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".com") == 0
+ || BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".bat") == 0
+ || BOOST_FILESYSTEM_STRICMP(p.extension().string().c_str(), ".cmd") == 0)
+ prms |= fs::owner_exe | fs::group_exe | fs::others_exe;
+ return prms;
+ }
+
+ // these constants come from inspecting some Microsoft sample code
+ std::time_t to_time_t(const FILETIME & ft)
+ {
+ __int64 t = (static_cast<__int64>(ft.dwHighDateTime)<< 32)
+ + ft.dwLowDateTime;
+# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // > VC++ 7.0
+ t -= 116444736000000000LL;
+# else
+ t -= 116444736000000000;
+# endif
+ t /= 10000000;
+ return static_cast<std::time_t>(t);
+ }
+
+ void to_FILETIME(std::time_t t, FILETIME & ft)
+ {
+ __int64 temp = t;
+ temp *= 10000000;
+# if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // > VC++ 7.0
+ temp += 116444736000000000LL;
+# else
+ temp += 116444736000000000;
+# endif
+ ft.dwLowDateTime = static_cast<DWORD>(temp);
+ ft.dwHighDateTime = static_cast<DWORD>(temp >> 32);
+ }
+
+ // Thanks to Jeremy Maitin-Shepard for much help and for permission to
+ // base the equivalent()implementation on portions of his
+ // file-equivalence-win32.cpp experimental code.
+
+ struct handle_wrapper
+ {
+ HANDLE handle;
+ handle_wrapper(HANDLE h)
+ : handle(h){}
+ ~handle_wrapper()
+ {
+ if (handle != INVALID_HANDLE_VALUE)
+ ::CloseHandle(handle);
+ }
+ };
+
+ HANDLE create_file_handle(const path& p, DWORD dwDesiredAccess,
+ DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+ DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
+ HANDLE hTemplateFile)
+ {
+ return ::CreateFileW(p.c_str(), dwDesiredAccess, dwShareMode,
+ lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+ hTemplateFile);
+ }
+
+ bool is_reparse_point_a_symlink(const path& p)
+ {
+ handle_wrapper h(create_file_handle(p, FILE_READ_EA,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL));
+ if (h.handle == INVALID_HANDLE_VALUE)
+ return false;
+
+ boost::scoped_array<char> buf(new char [MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
+
+ // Query the reparse data
+ DWORD dwRetLen;
+ BOOL result = ::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT, NULL, 0, buf.get(),
+ MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &dwRetLen, NULL);
+ if (!result) return false;
+
+ return reinterpret_cast<const REPARSE_DATA_BUFFER*>(buf.get())
+ ->ReparseTag == IO_REPARSE_TAG_SYMLINK;
+ }
+
+ inline std::size_t get_full_path_name(
+ const path& src, std::size_t len, wchar_t* buf, wchar_t** p)
+ {
+ return static_cast<std::size_t>(
+ ::GetFullPathNameW(src.c_str(), static_cast<DWORD>(len), buf, p));
+ }
+
+ fs::file_status process_status_failure(const path& p, error_code* ec)
+ {
+ int errval(::GetLastError());
+ if (ec != 0) // always report errval, even though some
+ ec->assign(errval, system_category()); // errval values are not status_errors
+
+ if (not_found_error(errval))
+ {
+ return fs::file_status(fs::file_not_found, fs::no_perms);
+ }
+ else if ((errval == ERROR_SHARING_VIOLATION))
+ {
+ return fs::file_status(fs::type_unknown);
+ }
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
+ p, error_code(errval, system_category())));
+ return fs::file_status(fs::status_error);
+ }
+
+ // differs from symlink_status() in that directory symlinks are reported as
+ // _detail_directory_symlink, as required on Windows by remove() and its helpers.
+ fs::file_type query_file_type(const path& p, error_code* ec)
+ {
+ DWORD attr(::GetFileAttributesW(p.c_str()));
+ if (attr == 0xFFFFFFFF)
+ {
+ return process_status_failure(p, ec).type();
+ }
+
+ if (ec != 0) ec->clear();
+
+ if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ if (is_reparse_point_a_symlink(p))
+ return (attr & FILE_ATTRIBUTE_DIRECTORY)
+ ? fs::_detail_directory_symlink
+ : fs::symlink_file;
+ return fs::reparse_file;
+ }
+
+ return (attr & FILE_ATTRIBUTE_DIRECTORY)
+ ? fs::directory_file
+ : fs::regular_file;
+ }
+
+ BOOL resize_file_api(const wchar_t* p, boost::uintmax_t size)
+ {
+ HANDLE handle = CreateFileW(p, GENERIC_WRITE, 0, 0, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL, 0);
+ LARGE_INTEGER sz;
+ sz.QuadPart = size;
+ return handle != INVALID_HANDLE_VALUE
+ && ::SetFilePointerEx(handle, sz, 0, FILE_BEGIN)
+ && ::SetEndOfFile(handle)
+ && ::CloseHandle(handle);
+ }
+
+ // Windows kernel32.dll functions that may or may not be present
+ // must be accessed through pointers
+
+ typedef BOOL (WINAPI *PtrCreateHardLinkW)(
+ /*__in*/ LPCWSTR lpFileName,
+ /*__in*/ LPCWSTR lpExistingFileName,
+ /*__reserved*/ LPSECURITY_ATTRIBUTES lpSecurityAttributes
+ );
+
+ PtrCreateHardLinkW create_hard_link_api = PtrCreateHardLinkW(
+ ::GetProcAddress(
+ ::GetModuleHandle(TEXT("kernel32.dll")), "CreateHardLinkW"));
+
+ typedef BOOLEAN (WINAPI *PtrCreateSymbolicLinkW)(
+ /*__in*/ LPCWSTR lpSymlinkFileName,
+ /*__in*/ LPCWSTR lpTargetFileName,
+ /*__in*/ DWORD dwFlags
+ );
+
+ PtrCreateSymbolicLinkW create_symbolic_link_api = PtrCreateSymbolicLinkW(
+ ::GetProcAddress(
+ ::GetModuleHandle(TEXT("kernel32.dll")), "CreateSymbolicLinkW"));
+
+#endif
+
+//#ifdef BOOST_WINDOWS_API
+//
+//
+// inline bool get_free_disk_space(const std::wstring& ph,
+// PULARGE_INTEGER avail, PULARGE_INTEGER total, PULARGE_INTEGER free)
+// { return ::GetDiskFreeSpaceExW(ph.c_str(), avail, total, free)!= 0; }
+//
+//#endif
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+// //
+// operations functions declared in operations.hpp //
+// in alphabetic order //
+// //
+//--------------------------------------------------------------------------------------//
+
+namespace boost
+{
+namespace filesystem
+{
+
+ BOOST_FILESYSTEM_DECL
+ path absolute(const path& p, const path& base)
+ {
+// if ( p.empty() || p.is_absolute() )
+// return p;
+// // recursively calling absolute is sub-optimal, but is simple
+// path abs_base(base.is_absolute() ? base : absolute(base));
+//# ifdef BOOST_WINDOWS_API
+// if (p.has_root_directory())
+// return abs_base.root_name() / p;
+// // !p.has_root_directory
+// if (p.has_root_name())
+// return p.root_name()
+// / abs_base.root_directory() / abs_base.relative_path() / p.relative_path();
+// // !p.has_root_name()
+//# endif
+// return abs_base / p;
+
+ // recursively calling absolute is sub-optimal, but is sure and simple
+ path abs_base(base.is_absolute() ? base : absolute(base));
+
+ // store expensive to compute values that are needed multiple times
+ path p_root_name (p.root_name());
+ path base_root_name (abs_base.root_name());
+ path p_root_directory (p.root_directory());
+
+ if (p.empty())
+ return abs_base;
+
+ if (!p_root_name.empty()) // p.has_root_name()
+ {
+ if (p_root_directory.empty()) // !p.has_root_directory()
+ return p_root_name / abs_base.root_directory()
+ / abs_base.relative_path() / p.relative_path();
+ // p is absolute, so fall through to return p at end of block
+ }
+
+ else if (!p_root_directory.empty()) // p.has_root_directory()
+ {
+# ifdef BOOST_POSIX_API
+ // POSIX can have root name it it is a network path
+ if (base_root_name.empty()) // !abs_base.has_root_name()
+ return p;
+# endif
+ return base_root_name / p;
+ }
+
+ else
+ {
+ return abs_base / p;
+ }
+
+ return p; // p.is_absolute() is true
+ }
+
+namespace detail
+{
+ BOOST_FILESYSTEM_DECL bool possible_large_file_size_support()
+ {
+# ifdef BOOST_POSIX_API
+ struct stat lcl_stat;
+ return sizeof(lcl_stat.st_size)> 4;
+# else
+ return true;
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ path canonical(const path& p, const path& base, system::error_code* ec)
+ {
+ path source (p.is_absolute() ? p : absolute(p, base));
+ path result;
+
+ system::error_code local_ec;
+ file_status stat (status(source, local_ec));
+
+ if (stat.type() == fs::file_not_found)
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(
+ "boost::filesystem::canonical", source,
+ error_code(system::errc::no_such_file_or_directory, system::generic_category())));
+ ec->assign(system::errc::no_such_file_or_directory, system::generic_category());
+ return result;
+ }
+ else if (local_ec)
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(
+ "boost::filesystem::canonical", source, local_ec));
+ *ec = local_ec;
+ return result;
+ }
+
+ bool scan (true);
+ while (scan)
+ {
+ scan = false;
+ result.clear();
+ for (path::iterator itr = source.begin(); itr != source.end(); ++itr)
+ {
+ if (*itr == dot_path)
+ continue;
+ if (*itr == dot_dot_path)
+ {
+ result.remove_filename();
+ continue;
+ }
+
+ result /= *itr;
+
+ bool is_sym (is_symlink(detail::symlink_status(result, ec)));
+ if (ec && *ec)
+ return path();
+
+ if (is_sym)
+ {
+ path link(detail::read_symlink(result, ec));
+ if (ec && *ec)
+ return path();
+ result.remove_filename();
+
+ if (link.is_absolute())
+ {
+ for (++itr; itr != source.end(); ++itr)
+ link /= *itr;
+ source = link;
+ }
+ else // link is relative
+ {
+ path new_source(result);
+ new_source /= link;
+ for (++itr; itr != source.end(); ++itr)
+ new_source /= *itr;
+ source = new_source;
+ }
+ scan = true; // symlink causes scan to be restarted
+ break;
+ }
+ }
+ }
+ if (ec != 0)
+ ec->clear();
+ BOOST_ASSERT_MSG(result.is_absolute(), "canonical() implementation error; please report");
+ return result;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void copy(const path& from, const path& to, system::error_code* ec)
+ {
+ file_status s(symlink_status(from, *ec));
+ if (ec != 0 && *ec) return;
+
+ if(is_symlink(s))
+ {
+ copy_symlink(from, to, *ec);
+ }
+ else if(is_directory(s))
+ {
+ copy_directory(from, to, *ec);
+ }
+ else if(is_regular_file(s))
+ {
+ copy_file(from, to, copy_option::fail_if_exists, *ec);
+ }
+ else
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::copy",
+ from, to, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category())));
+ ec->assign(BOOST_ERROR_NOT_SUPPORTED, system_category());
+ }
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void copy_directory(const path& from, const path& to, system::error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+ struct stat from_stat;
+# endif
+ error(!BOOST_COPY_DIRECTORY(from.c_str(), to.c_str()),
+ from, to, ec, "boost::filesystem::copy_directory");
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void copy_file(const path& from, const path& to,
+ BOOST_SCOPED_ENUM(copy_option)option,
+ error_code* ec)
+ {
+ error(!BOOST_COPY_FILE(from.c_str(), to.c_str(),
+ option == copy_option::fail_if_exists),
+ from, to, ec, "boost::filesystem::copy_file");
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void copy_symlink(const path& existing_symlink, const path& new_symlink,
+ system::error_code* ec)
+ {
+# if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0600
+ error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()),
+ new_symlink, existing_symlink, ec,
+ "boost::filesystem::copy_symlink");
+
+# else // modern Windows or BOOST_POSIX_API
+ path p(read_symlink(existing_symlink, ec));
+ if (ec != 0 && *ec) return;
+ create_symlink(p, new_symlink, ec);
+
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool create_directories(const path& p, system::error_code* ec)
+ {
+ error_code local_ec;
+ file_status p_status = status(p, local_ec);
+
+ if (p_status.type() == directory_file)
+ {
+ if (ec != 0)
+ ec->clear();
+ return false;
+ }
+
+ path parent = p.parent_path();
+ if (!parent.empty())
+ {
+ // determine if the parent exists
+ file_status parent_status = status(parent, local_ec);
+
+ // if the parent does not exist, create the parent
+ if (parent_status.type() == file_not_found)
+ {
+ create_directories(parent, local_ec);
+ if (local_ec)
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(
+ "boost::filesystem::create_directories", parent, local_ec));
+ else
+ *ec = local_ec;
+ return false;
+ }
+ }
+ }
+
+ // create the directory
+ return create_directory(p, ec);
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool create_directory(const path& p, error_code* ec)
+ {
+ if (BOOST_CREATE_DIRECTORY(p.c_str()))
+ {
+ if (ec != 0)
+ ec->clear();
+ return true;
+ }
+
+ // attempt to create directory failed
+ int errval(BOOST_ERRNO); // save reason for failure
+ error_code dummy;
+ if (errval == BOOST_ERROR_ALREADY_EXISTS && is_directory(p, dummy))
+ {
+ if (ec != 0)
+ ec->clear();
+ return false;
+ }
+
+ // attempt to create directory failed && it doesn't already exist
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::create_directory",
+ p, error_code(errval, system_category())));
+ else
+ ec->assign(errval, system_category());
+ return false;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void create_directory_symlink(const path& to, const path& from,
+ system::error_code* ec)
+ {
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008
+
+ error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec,
+ "boost::filesystem::create_directory_symlink");
+# else
+
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0600
+ // see if actually supported by Windows runtime dll
+ if (error(!create_symbolic_link_api,
+ error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()),
+ to, from, ec,
+ "boost::filesystem::create_directory_symlink"))
+ return;
+# endif
+
+ error(!BOOST_CREATE_SYMBOLIC_LINK(from.c_str(), to.c_str(), SYMBOLIC_LINK_FLAG_DIRECTORY),
+ to, from, ec, "boost::filesystem::create_directory_symlink");
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void create_hard_link(const path& to, const path& from, error_code* ec)
+ {
+
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0500 // SDK earlier than Win 2K
+
+ error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec,
+ "boost::filesystem::create_hard_link");
+# else
+
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0500
+ // see if actually supported by Windows runtime dll
+ if (error(!create_hard_link_api,
+ error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()),
+ to, from, ec,
+ "boost::filesystem::create_hard_link"))
+ return;
+# endif
+
+ error(!BOOST_CREATE_HARD_LINK(from.c_str(), to.c_str()), to, from, ec,
+ "boost::filesystem::create_hard_link");
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void create_symlink(const path& to, const path& from, error_code* ec)
+ {
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008
+ error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), to, from, ec,
+ "boost::filesystem::create_directory_symlink");
+# else
+
+# if defined(BOOST_WINDOWS_API) && _WIN32_WINNT >= 0x0600
+ // see if actually supported by Windows runtime dll
+ if (error(!create_symbolic_link_api,
+ error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()),
+ to, from, ec,
+ "boost::filesystem::create_symlink"))
+ return;
+# endif
+
+ error(!BOOST_CREATE_SYMBOLIC_LINK(from.c_str(), to.c_str(), 0),
+ to, from, ec, "boost::filesystem::create_symlink");
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ path current_path(error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+ path cur;
+ for (long path_max = 128;; path_max *=2)// loop 'til buffer large enough
+ {
+ boost::scoped_array<char>
+ buf(new char[static_cast<std::size_t>(path_max)]);
+ if (::getcwd(buf.get(), static_cast<std::size_t>(path_max))== 0)
+ {
+ if (error(errno != ERANGE
+ // bug in some versions of the Metrowerks C lib on the Mac: wrong errno set
+# if defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+ && errno != 0
+# endif
+ , ec, "boost::filesystem::current_path"))
+ {
+ break;
+ }
+ }
+ else
+ {
+ cur = buf.get();
+ if (ec != 0) ec->clear();
+ break;
+ }
+ }
+ return cur;
+
+# else
+ DWORD sz;
+ if ((sz = ::GetCurrentDirectoryW(0, NULL))== 0)sz = 1;
+ boost::scoped_array<path::value_type> buf(new path::value_type[sz]);
+ error(::GetCurrentDirectoryW(sz, buf.get())== 0, ec,
+ "boost::filesystem::current_path");
+ return path(buf.get());
+# endif
+ }
+
+
+ BOOST_FILESYSTEM_DECL
+ void current_path(const path& p, system::error_code* ec)
+ {
+ error(!BOOST_SET_CURRENT_DIRECTORY(p.c_str()),
+ p, ec, "boost::filesystem::current_path");
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool equivalent(const path& p1, const path& p2, system::error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+ struct stat s2;
+ int e2(::stat(p2.c_str(), &s2));
+ struct stat s1;
+ int e1(::stat(p1.c_str(), &s1));
+
+ if (e1 != 0 || e2 != 0)
+ {
+ // if one is invalid and the other isn't then they aren't equivalent,
+ // but if both are invalid then it is an error
+ error (e1 != 0 && e2 != 0, p1, p2, ec, "boost::filesystem::equivalent");
+ return false;
+ }
+
+ // both stats now known to be valid
+ return s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino
+ // According to the POSIX stat specs, "The st_ino and st_dev fields
+ // taken together uniquely identify the file within the system."
+ // Just to be sure, size and mod time are also checked.
+ && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime;
+
+# else // Windows
+
+ // Note well: Physical location on external media is part of the
+ // equivalence criteria. If there are no open handles, physical location
+ // can change due to defragmentation or other relocations. Thus handles
+ // must be held open until location information for both paths has
+ // been retrieved.
+
+ // p2 is done first, so any error reported is for p1
+ handle_wrapper h2(
+ create_file_handle(
+ p2.c_str(),
+ 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0));
+
+ handle_wrapper h1(
+ create_file_handle(
+ p1.c_str(),
+ 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0));
+
+ if (h1.handle == INVALID_HANDLE_VALUE
+ || h2.handle == INVALID_HANDLE_VALUE)
+ {
+ // if one is invalid and the other isn't, then they aren't equivalent,
+ // but if both are invalid then it is an error
+ error(h1.handle == INVALID_HANDLE_VALUE
+ && h2.handle == INVALID_HANDLE_VALUE, p1, p2, ec,
+ "boost::filesystem::equivalent");
+ return false;
+ }
+
+ // at this point, both handles are known to be valid
+
+ BY_HANDLE_FILE_INFORMATION info1, info2;
+
+ if (error(!::GetFileInformationByHandle(h1.handle, &info1),
+ p1, p2, ec, "boost::filesystem::equivalent"))
+ return false;
+
+ if (error(!::GetFileInformationByHandle(h2.handle, &info2),
+ p1, p2, ec, "boost::filesystem::equivalent"))
+ return false;
+
+ // In theory, volume serial numbers are sufficient to distinguish between
+ // devices, but in practice VSN's are sometimes duplicated, so last write
+ // time and file size are also checked.
+ return
+ info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber
+ && info1.nFileIndexHigh == info2.nFileIndexHigh
+ && info1.nFileIndexLow == info2.nFileIndexLow
+ && info1.nFileSizeHigh == info2.nFileSizeHigh
+ && info1.nFileSizeLow == info2.nFileSizeLow
+ && info1.ftLastWriteTime.dwLowDateTime
+ == info2.ftLastWriteTime.dwLowDateTime
+ && info1.ftLastWriteTime.dwHighDateTime
+ == info2.ftLastWriteTime.dwHighDateTime;
+
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ boost::uintmax_t file_size(const path& p, error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+
+ struct stat path_stat;
+ if (error(::stat(p.c_str(), &path_stat)!= 0,
+ p, ec, "boost::filesystem::file_size"))
+ return static_cast<boost::uintmax_t>(-1);
+ if (error(!S_ISREG(path_stat.st_mode),
+ error_code(EPERM, system_category()),
+ p, ec, "boost::filesystem::file_size"))
+ return static_cast<boost::uintmax_t>(-1);
+
+ return static_cast<boost::uintmax_t>(path_stat.st_size);
+
+# else // Windows
+
+ // assume uintmax_t is 64-bits on all Windows compilers
+
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+
+ if (error(::GetFileAttributesExW(p.c_str(), ::GetFileExInfoStandard, &fad)== 0,
+ p, ec, "boost::filesystem::file_size"))
+ return static_cast<boost::uintmax_t>(-1);
+
+ if (error((fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)!= 0,
+ error_code(ERROR_NOT_SUPPORTED, system_category()),
+ p, ec, "boost::filesystem::file_size"))
+ return static_cast<boost::uintmax_t>(-1);
+
+ return (static_cast<boost::uintmax_t>(fad.nFileSizeHigh)
+ << (sizeof(fad.nFileSizeLow)*8)) + fad.nFileSizeLow;
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ boost::uintmax_t hard_link_count(const path& p, system::error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+
+ struct stat path_stat;
+ return error(::stat(p.c_str(), &path_stat)!= 0,
+ p, ec, "boost::filesystem::hard_link_count")
+ ? 0
+ : static_cast<boost::uintmax_t>(path_stat.st_nlink);
+
+# else // Windows
+
+ // Link count info is only available through GetFileInformationByHandle
+ BY_HANDLE_FILE_INFORMATION info;
+ handle_wrapper h(
+ create_file_handle(p.c_str(), 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
+ return
+ !error(h.handle == INVALID_HANDLE_VALUE,
+ p, ec, "boost::filesystem::hard_link_count")
+ && !error(::GetFileInformationByHandle(h.handle, &info)== 0,
+ p, ec, "boost::filesystem::hard_link_count")
+ ? info.nNumberOfLinks
+ : 0;
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ path initial_path(error_code* ec)
+ {
+ static path init_path;
+ if (init_path.empty())
+ init_path = current_path(ec);
+ else if (ec != 0) ec->clear();
+ return init_path;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool is_empty(const path& p, system::error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+
+ struct stat path_stat;
+ if (error(::stat(p.c_str(), &path_stat)!= 0,
+ p, ec, "boost::filesystem::is_empty"))
+ return false;
+ return S_ISDIR(path_stat.st_mode)
+ ? is_empty_directory(p)
+ : path_stat.st_size == 0;
+# else
+
+ WIN32_FILE_ATTRIBUTE_DATA fad;
+ if (error(::GetFileAttributesExW(p.c_str(), ::GetFileExInfoStandard, &fad)== 0,
+ p, ec, "boost::filesystem::is_empty"))
+ return false;
+
+ if (ec != 0) ec->clear();
+ return
+ (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ ? is_empty_directory(p)
+ : (!fad.nFileSizeHigh && !fad.nFileSizeLow);
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ std::time_t last_write_time(const path& p, system::error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+
+ struct stat path_stat;
+ if (error(::stat(p.c_str(), &path_stat)!= 0,
+ p, ec, "boost::filesystem::last_write_time"))
+ return std::time_t(-1);
+ return path_stat.st_mtime;
+
+# else
+
+ handle_wrapper hw(
+ create_file_handle(p.c_str(), 0,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
+
+ if (error(hw.handle == INVALID_HANDLE_VALUE,
+ p, ec, "boost::filesystem::last_write_time"))
+ return std::time_t(-1);
+
+ FILETIME lwt;
+
+ if (error(::GetFileTime(hw.handle, 0, 0, &lwt)== 0,
+ p, ec, "boost::filesystem::last_write_time"))
+ return std::time_t(-1);
+
+ return to_time_t(lwt);
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void last_write_time(const path& p, const std::time_t new_time,
+ system::error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+
+ struct stat path_stat;
+ if (error(::stat(p.c_str(), &path_stat)!= 0,
+ p, ec, "boost::filesystem::last_write_time"))
+ return;
+ ::utimbuf buf;
+ buf.actime = path_stat.st_atime; // utime()updates access time too:-(
+ buf.modtime = new_time;
+ error(::utime(p.c_str(), &buf)!= 0,
+ p, ec, "boost::filesystem::last_write_time");
+
+# else
+
+ handle_wrapper hw(
+ create_file_handle(p.c_str(), FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0));
+
+ if (error(hw.handle == INVALID_HANDLE_VALUE,
+ p, ec, "boost::filesystem::last_write_time"))
+ return;
+
+ FILETIME lwt;
+ to_FILETIME(new_time, lwt);
+
+ error(::SetFileTime(hw.handle, 0, 0, &lwt)== 0,
+ p, ec, "boost::filesystem::last_write_time");
+# endif
+ }
+
+# ifdef BOOST_POSIX_API
+ const perms active_bits(all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit);
+ inline mode_t mode_cast(perms prms) { return prms & active_bits; }
+# endif
+
+ BOOST_FILESYSTEM_DECL
+ void permissions(const path& p, perms prms, system::error_code* ec)
+ {
+ BOOST_ASSERT_MSG(!((prms & add_perms) && (prms & remove_perms)),
+ "add_perms and remove_perms are mutually exclusive");
+
+ if ((prms & add_perms) && (prms & remove_perms)) // precondition failed
+ return;
+
+# ifdef BOOST_POSIX_API
+ error_code local_ec;
+ file_status current_status((prms & symlink_perms)
+ ? fs::symlink_status(p, local_ec)
+ : fs::status(p, local_ec));
+ if (local_ec)
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(
+ "boost::filesystem::permissions", p, local_ec));
+ else
+ *ec = local_ec;
+ return;
+ }
+
+ if (prms & add_perms)
+ prms |= current_status.permissions();
+ else if (prms & remove_perms)
+ prms = current_status.permissions() & ~prms;
+
+ // Mac OS X Lion and some other platforms don't support fchmodat().
+ // Solaris (SunPro and gcc) only support fchmodat() on Solaris 11 and higher,
+ // and a runtime check is too much trouble.
+ // Linux does not support permissions on symbolic links and has no plans to
+ // support them in the future. The chmod() code is thus more practical,
+ // rather than always hitting ENOTSUP when sending in AT_SYMLINK_NO_FOLLOW.
+ // - See the 3rd paragraph of
+ // "Symbolic link ownership, permissions, and timestamps" at:
+ // "http://man7.org/linux/man-pages/man7/symlink.7.html"
+ // - See the fchmodat() Linux man page:
+ // "http://man7.org/linux/man-pages/man2/fchmodat.2.html"
+# if defined(AT_FDCWD) && defined(AT_SYMLINK_NOFOLLOW) \
+ && !(defined(__SUNPRO_CC) || defined(sun)) \
+ && !(defined(linux) || defined(__linux) || defined(__linux__))
+ if (::fchmodat(AT_FDCWD, p.c_str(), mode_cast(prms),
+ !(prms & symlink_perms) ? 0 : AT_SYMLINK_NOFOLLOW))
+# else // fallback if fchmodat() not supported
+ if (::chmod(p.c_str(), mode_cast(prms)))
+# endif
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error(
+ "boost::filesystem::permissions", p,
+ error_code(errno, system::generic_category())));
+ else
+ ec->assign(errno, system::generic_category());
+ }
+
+# else // Windows
+
+ // if not going to alter FILE_ATTRIBUTE_READONLY, just return
+ if (!(!((prms & (add_perms | remove_perms)))
+ || (prms & (owner_write|group_write|others_write))))
+ return;
+
+ DWORD attr = ::GetFileAttributesW(p.c_str());
+
+ if (error(attr == 0, p, ec, "boost::filesystem::permissions"))
+ return;
+
+ if (prms & add_perms)
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else if (prms & remove_perms)
+ attr |= FILE_ATTRIBUTE_READONLY;
+ else if (prms & (owner_write|group_write|others_write))
+ attr &= ~FILE_ATTRIBUTE_READONLY;
+ else
+ attr |= FILE_ATTRIBUTE_READONLY;
+
+ error(::SetFileAttributesW(p.c_str(), attr) == 0,
+ p, ec, "boost::filesystem::permissions");
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ path read_symlink(const path& p, system::error_code* ec)
+ {
+ path symlink_path;
+
+# ifdef BOOST_POSIX_API
+
+ for (std::size_t path_max = 64;; path_max *= 2)// loop 'til buffer large enough
+ {
+ boost::scoped_array<char> buf(new char[path_max]);
+ ssize_t result;
+ if ((result=::readlink(p.c_str(), buf.get(), path_max))== -1)
+ {
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::read_symlink",
+ p, error_code(errno, system_category())));
+ else ec->assign(errno, system_category());
+ break;
+ }
+ else
+ {
+ if(result != static_cast<ssize_t>(path_max))
+ {
+ symlink_path.assign(buf.get(), buf.get() + result);
+ if (ec != 0) ec->clear();
+ break;
+ }
+ }
+ }
+
+# elif _WIN32_WINNT < 0x0600 // SDK earlier than Vista and Server 2008
+ error(true, error_code(BOOST_ERROR_NOT_SUPPORTED, system_category()), p, ec,
+ "boost::filesystem::read_symlink");
+# else // Vista and Server 2008 SDK, or later
+
+ union info_t
+ {
+ char buf[REPARSE_DATA_BUFFER_HEADER_SIZE+MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
+ REPARSE_DATA_BUFFER rdb;
+ } info;
+
+ handle_wrapper h(
+ create_file_handle(p.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, 0));
+
+ if (error(h.handle == INVALID_HANDLE_VALUE, p, ec, "boost::filesystem::read_symlink"))
+ return symlink_path;
+
+ DWORD sz;
+
+ if (!error(::DeviceIoControl(h.handle, FSCTL_GET_REPARSE_POINT,
+ 0, 0, info.buf, sizeof(info), &sz, 0) == 0, p, ec,
+ "boost::filesystem::read_symlink" ))
+ symlink_path.assign(
+ static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer)
+ + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t),
+ static_cast<wchar_t*>(info.rdb.SymbolicLinkReparseBuffer.PathBuffer)
+ + info.rdb.SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(wchar_t)
+ + info.rdb.SymbolicLinkReparseBuffer.PrintNameLength/sizeof(wchar_t));
+# endif
+ return symlink_path;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ bool remove(const path& p, error_code* ec)
+ {
+ error_code tmp_ec;
+ file_type type = query_file_type(p, &tmp_ec);
+ if (error(type == status_error, tmp_ec, p, ec,
+ "boost::filesystem::remove"))
+ return false;
+
+ // Since POSIX remove() is specified to work with either files or directories, in a
+ // perfect world it could just be called. But some important real-world operating
+ // systems (Windows, Mac OS X, for example) don't implement the POSIX spec. So
+ // remove_file_or_directory() is always called to kep it simple.
+ return remove_file_or_directory(p, type, ec);
+ }
+
+ BOOST_FILESYSTEM_DECL
+ boost::uintmax_t remove_all(const path& p, error_code* ec)
+ {
+ error_code tmp_ec;
+ file_type type = query_file_type(p, &tmp_ec);
+ if (error(type == status_error, tmp_ec, p, ec,
+ "boost::filesystem::remove_all"))
+ return 0;
+
+ return (type != status_error && type != file_not_found) // exists
+ ? remove_all_aux(p, type, ec)
+ : 0;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void rename(const path& old_p, const path& new_p, error_code* ec)
+ {
+ error(!BOOST_MOVE_FILE(old_p.c_str(), new_p.c_str()), old_p, new_p, ec,
+ "boost::filesystem::rename");
+ }
+
+ BOOST_FILESYSTEM_DECL
+ void resize_file(const path& p, uintmax_t size, system::error_code* ec)
+ {
+ error(!BOOST_RESIZE_FILE(p.c_str(), size), p, ec, "boost::filesystem::resize_file");
+ }
+
+ BOOST_FILESYSTEM_DECL
+ space_info space(const path& p, error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+ struct BOOST_STATVFS vfs;
+ space_info info;
+ if (!error(::BOOST_STATVFS(p.c_str(), &vfs)!= 0,
+ p, ec, "boost::filesystem::space"))
+ {
+ info.capacity
+ = static_cast<boost::uintmax_t>(vfs.f_blocks)* BOOST_STATVFS_F_FRSIZE;
+ info.free
+ = static_cast<boost::uintmax_t>(vfs.f_bfree)* BOOST_STATVFS_F_FRSIZE;
+ info.available
+ = static_cast<boost::uintmax_t>(vfs.f_bavail)* BOOST_STATVFS_F_FRSIZE;
+ }
+
+# else
+ ULARGE_INTEGER avail, total, free;
+ space_info info;
+
+ if (!error(::GetDiskFreeSpaceExW(p.c_str(), &avail, &total, &free)== 0,
+ p, ec, "boost::filesystem::space"))
+ {
+ info.capacity
+ = (static_cast<boost::uintmax_t>(total.HighPart)<< 32)
+ + total.LowPart;
+ info.free
+ = (static_cast<boost::uintmax_t>(free.HighPart)<< 32)
+ + free.LowPart;
+ info.available
+ = (static_cast<boost::uintmax_t>(avail.HighPart)<< 32)
+ + avail.LowPart;
+ }
+
+# endif
+
+ else
+ {
+ info.capacity = info.free = info.available = 0;
+ }
+ return info;
+ }
+
+ BOOST_FILESYSTEM_DECL
+ file_status status(const path& p, error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+
+ struct stat path_stat;
+ if (::stat(p.c_str(), &path_stat)!= 0)
+ {
+ if (ec != 0) // always report errno, even though some
+ ec->assign(errno, system_category()); // errno values are not status_errors
+
+ if (not_found_error(errno))
+ {
+ return fs::file_status(fs::file_not_found, fs::no_perms);
+ }
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
+ p, error_code(errno, system_category())));
+ return fs::file_status(fs::status_error);
+ }
+ if (ec != 0) ec->clear();;
+ if (S_ISDIR(path_stat.st_mode))
+ return fs::file_status(fs::directory_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISREG(path_stat.st_mode))
+ return fs::file_status(fs::regular_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISBLK(path_stat.st_mode))
+ return fs::file_status(fs::block_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISCHR(path_stat.st_mode))
+ return fs::file_status(fs::character_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISFIFO(path_stat.st_mode))
+ return fs::file_status(fs::fifo_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISSOCK(path_stat.st_mode))
+ return fs::file_status(fs::socket_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ return fs::file_status(fs::type_unknown);
+
+# else // Windows
+
+ DWORD attr(::GetFileAttributesW(p.c_str()));
+ if (attr == 0xFFFFFFFF)
+ {
+ return process_status_failure(p, ec);
+ }
+
+ // reparse point handling;
+ // since GetFileAttributesW does not resolve symlinks, try to open a file
+ // handle to discover if the file exists
+ if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ handle_wrapper h(
+ create_file_handle(
+ p.c_str(),
+ 0, // dwDesiredAccess; attributes only
+ FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
+ 0, // lpSecurityAttributes
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0)); // hTemplateFile
+ if (h.handle == INVALID_HANDLE_VALUE)
+ {
+ return process_status_failure(p, ec);
+ }
+
+ if (!is_reparse_point_a_symlink(p))
+ return file_status(reparse_file, make_permissions(p, attr));
+ }
+
+ if (ec != 0) ec->clear();
+ return (attr & FILE_ATTRIBUTE_DIRECTORY)
+ ? file_status(directory_file, make_permissions(p, attr))
+ : file_status(regular_file, make_permissions(p, attr));
+
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ file_status symlink_status(const path& p, error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+
+ struct stat path_stat;
+ if (::lstat(p.c_str(), &path_stat)!= 0)
+ {
+ if (ec != 0) // always report errno, even though some
+ ec->assign(errno, system_category()); // errno values are not status_errors
+
+ if (errno == ENOENT || errno == ENOTDIR) // these are not errors
+ {
+ return fs::file_status(fs::file_not_found, fs::no_perms);
+ }
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(filesystem_error("boost::filesystem::status",
+ p, error_code(errno, system_category())));
+ return fs::file_status(fs::status_error);
+ }
+ if (ec != 0) ec->clear();
+ if (S_ISREG(path_stat.st_mode))
+ return fs::file_status(fs::regular_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISDIR(path_stat.st_mode))
+ return fs::file_status(fs::directory_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISLNK(path_stat.st_mode))
+ return fs::file_status(fs::symlink_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISBLK(path_stat.st_mode))
+ return fs::file_status(fs::block_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISCHR(path_stat.st_mode))
+ return fs::file_status(fs::character_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISFIFO(path_stat.st_mode))
+ return fs::file_status(fs::fifo_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ if (S_ISSOCK(path_stat.st_mode))
+ return fs::file_status(fs::socket_file,
+ static_cast<perms>(path_stat.st_mode) & fs::perms_mask);
+ return fs::file_status(fs::type_unknown);
+
+# else // Windows
+
+ DWORD attr(::GetFileAttributesW(p.c_str()));
+ if (attr == 0xFFFFFFFF)
+ {
+ return process_status_failure(p, ec);
+ }
+
+ if (ec != 0) ec->clear();
+
+ if (attr & FILE_ATTRIBUTE_REPARSE_POINT)
+ return is_reparse_point_a_symlink(p)
+ ? file_status(symlink_file, make_permissions(p, attr))
+ : file_status(reparse_file, make_permissions(p, attr));
+
+ return (attr & FILE_ATTRIBUTE_DIRECTORY)
+ ? file_status(directory_file, make_permissions(p, attr))
+ : file_status(regular_file, make_permissions(p, attr));
+
+# endif
+ }
+
+ // contributed by Jeff Flinn
+ BOOST_FILESYSTEM_DECL
+ path temp_directory_path(system::error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+ const char* val = 0;
+
+ (val = std::getenv("TMPDIR" )) ||
+ (val = std::getenv("TMP" )) ||
+ (val = std::getenv("TEMP" )) ||
+ (val = std::getenv("TEMPDIR"));
+
+ path p((val!=0) ? val : "/tmp");
+
+ if (p.empty() || (ec&&!is_directory(p, *ec))||(!ec&&!is_directory(p)))
+ {
+ errno = ENOTDIR;
+ error(true, p, ec, "boost::filesystem::temp_directory_path");
+ return p;
+ }
+
+ return p;
+
+# else // Windows
+
+ std::vector<path::value_type> buf(GetTempPathW(0, NULL));
+
+ if (buf.empty() || GetTempPathW(buf.size(), &buf[0])==0)
+ {
+ if(!buf.empty()) ::SetLastError(ENOTDIR);
+ error(true, ec, "boost::filesystem::temp_directory_path");
+ return path();
+ }
+
+ buf.pop_back();
+
+ path p(buf.begin(), buf.end());
+
+ if ((ec&&!is_directory(p, *ec))||(!ec&&!is_directory(p)))
+ {
+ ::SetLastError(ENOTDIR);
+ error(true, p, ec, "boost::filesystem::temp_directory_path");
+ return path();
+ }
+
+ return p;
+# endif
+ }
+
+ BOOST_FILESYSTEM_DECL
+ path system_complete(const path& p, system::error_code* ec)
+ {
+# ifdef BOOST_POSIX_API
+ return (p.empty() || p.is_absolute())
+ ? p : current_path()/ p;
+
+# else
+ if (p.empty())
+ {
+ if (ec != 0) ec->clear();
+ return p;
+ }
+ wchar_t buf[buf_size];
+ wchar_t* pfn;
+ std::size_t len = get_full_path_name(p, buf_size, buf, &pfn);
+
+ if (error(len == 0, p, ec, "boost::filesystem::system_complete"))
+ return path();
+
+ if (len < buf_size)// len does not include null termination character
+ return path(&buf[0]);
+
+ boost::scoped_array<wchar_t> big_buf(new wchar_t[len]);
+
+ return error(get_full_path_name(p, len , big_buf.get(), &pfn)== 0,
+ p, ec, "boost::filesystem::system_complete")
+ ? path()
+ : path(big_buf.get());
+# endif
+ }
+
+} // namespace detail
+
+//--------------------------------------------------------------------------------------//
+// //
+// directory_entry //
+// //
+//--------------------------------------------------------------------------------------//
+
+ file_status
+ directory_entry::m_get_status(system::error_code* ec) const
+ {
+ if (!status_known(m_status))
+ {
+ // optimization: if the symlink status is known, and it isn't a symlink,
+ // then status and symlink_status are identical so just copy the
+ // symlink status to the regular status.
+ if (status_known(m_symlink_status)
+ && !is_symlink(m_symlink_status))
+ {
+ m_status = m_symlink_status;
+ if (ec != 0) ec->clear();
+ }
+ else m_status = detail::status(m_path, ec);
+ }
+ else if (ec != 0) ec->clear();
+ return m_status;
+ }
+
+ file_status
+ directory_entry::m_get_symlink_status(system::error_code* ec) const
+ {
+ if (!status_known(m_symlink_status))
+ m_symlink_status = detail::symlink_status(m_path, ec);
+ else if (ec != 0) ec->clear();
+ return m_symlink_status;
+ }
+
+// dispatch directory_entry supplied here rather than in
+// <boost/filesystem/path_traits.hpp>, thus avoiding header circularity.
+// test cases are in operations_unit_test.cpp
+
+namespace path_traits
+{
+ void dispatch(const directory_entry & de,
+# ifdef BOOST_WINDOWS_API
+ std::wstring& to,
+# else
+ std::string& to,
+# endif
+ const codecvt_type &)
+ {
+ to = de.path().native();
+ }
+
+} // namespace path_traits
+} // namespace filesystem
+} // namespace boost
+
+//--------------------------------------------------------------------------------------//
+// //
+// directory_iterator //
+// //
+//--------------------------------------------------------------------------------------//
+
+namespace
+{
+# ifdef BOOST_POSIX_API
+
+ error_code path_max(std::size_t & result)
+ // this code is based on Stevens and Rago, Advanced Programming in the
+ // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49
+ {
+# ifdef PATH_MAX
+ static std::size_t max = PATH_MAX;
+# else
+ static std::size_t max = 0;
+# endif
+ if (max == 0)
+ {
+ errno = 0;
+ long tmp = ::pathconf("/", _PC_NAME_MAX);
+ if (tmp < 0)
+ {
+ if (errno == 0)// indeterminate
+ max = 4096; // guess
+ else return error_code(errno, system_category());
+ }
+ else max = static_cast<std::size_t>(tmp + 1); // relative root
+ }
+ result = max;
+ return ok;
+ }
+
+#if defined(__PGI) && defined(__USE_FILE_OFFSET64)
+#define dirent dirent64
+#endif
+
+ error_code dir_itr_first(void *& handle, void *& buffer,
+ const char* dir, string& target,
+ fs::file_status &, fs::file_status &)
+ {
+ if ((handle = ::opendir(dir))== 0)
+ return error_code(errno, system_category());
+ target = string("."); // string was static but caused trouble
+ // when iteration called from dtor, after
+ // static had already been destroyed
+ std::size_t path_size (0); // initialization quiets gcc warning (ticket #3509)
+ error_code ec = path_max(path_size);
+ if (ec)return ec;
+ dirent de;
+ buffer = std::malloc((sizeof(dirent) - sizeof(de.d_name))
+ + path_size + 1); // + 1 for "/0"
+ return ok;
+ }
+
+ // warning: the only dirent member updated is d_name
+ inline int readdir_r_simulator(DIR * dirp, struct dirent * entry,
+ struct dirent ** result)// *result set to 0 on end of directory
+ {
+ errno = 0;
+
+# if !defined(__CYGWIN__)\
+ && defined(_POSIX_THREAD_SAFE_FUNCTIONS)\
+ && defined(_SC_THREAD_SAFE_FUNCTIONS)\
+ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0)\
+ && (!defined(__hpux) || defined(_REENTRANT)) \
+ && (!defined(_AIX) || defined(__THREAD_SAFE))
+ if (::sysconf(_SC_THREAD_SAFE_FUNCTIONS)>= 0)
+ { return ::readdir_r(dirp, entry, result); }
+# endif
+
+ struct dirent * p;
+ *result = 0;
+ if ((p = ::readdir(dirp))== 0)
+ return errno;
+ std::strcpy(entry->d_name, p->d_name);
+ *result = entry;
+ return 0;
+ }
+
+ error_code dir_itr_increment(void *& handle, void *& buffer,
+ string& target, fs::file_status & sf, fs::file_status & symlink_sf)
+ {
+ BOOST_ASSERT(buffer != 0);
+ dirent * entry(static_cast<dirent *>(buffer));
+ dirent * result;
+ int return_code;
+ if ((return_code = readdir_r_simulator(static_cast<DIR*>(handle), entry, &result))!= 0)
+ return error_code(errno, system_category());
+ if (result == 0)
+ return fs::detail::dir_itr_close(handle, buffer);
+ target = entry->d_name;
+# ifdef BOOST_FILESYSTEM_STATUS_CACHE
+ if (entry->d_type == DT_UNKNOWN) // filesystem does not supply d_type value
+ {
+ sf = symlink_sf = fs::file_status(fs::status_error);
+ }
+ else // filesystem supplies d_type value
+ {
+ if (entry->d_type == DT_DIR)
+ sf = symlink_sf = fs::file_status(fs::directory_file);
+ else if (entry->d_type == DT_REG)
+ sf = symlink_sf = fs::file_status(fs::regular_file);
+ else if (entry->d_type == DT_LNK)
+ {
+ sf = fs::file_status(fs::status_error);
+ symlink_sf = fs::file_status(fs::symlink_file);
+ }
+ else sf = symlink_sf = fs::file_status(fs::status_error);
+ }
+# else
+ sf = symlink_sf = fs::file_status(fs::status_error);
+# endif
+ return ok;
+ }
+
+# else // BOOST_WINDOWS_API
+
+ error_code dir_itr_first(void *& handle, const fs::path& dir,
+ wstring& target, fs::file_status & sf, fs::file_status & symlink_sf)
+ // Note: an empty root directory has no "." or ".." entries, so this
+ // causes a ERROR_FILE_NOT_FOUND error which we do not considered an
+ // error. It is treated as eof instead.
+ {
+ // use a form of search Sebastian Martel reports will work with Win98
+ wstring dirpath(dir.wstring());
+ dirpath += (dirpath.empty()
+ || (dirpath[dirpath.size()-1] != L'\\'
+ && dirpath[dirpath.size()-1] != L'/'
+ && dirpath[dirpath.size()-1] != L':'))? L"\\*" : L"*";
+
+ WIN32_FIND_DATAW data;
+ if ((handle = ::FindFirstFileW(dirpath.c_str(), &data))
+ == INVALID_HANDLE_VALUE)
+ {
+ handle = 0; // signal eof
+ return error_code( (::GetLastError() == ERROR_FILE_NOT_FOUND
+ // Windows Mobile returns ERROR_NO_MORE_FILES; see ticket #3551
+ || ::GetLastError() == ERROR_NO_MORE_FILES)
+ ? 0 : ::GetLastError(), system_category() );
+ }
+ target = data.cFileName;
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+ // reparse points are complex, so don't try to handle them here; instead just mark
+ // them as status_error which causes directory_entry caching to call status()
+ // and symlink_status() which do handle reparse points fully
+ {
+ sf.type(fs::status_error);
+ symlink_sf.type(fs::status_error);
+ }
+ else
+ {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ sf.type(fs::directory_file);
+ symlink_sf.type(fs::directory_file);
+ }
+ else
+ {
+ sf.type(fs::regular_file);
+ symlink_sf.type(fs::regular_file);
+ }
+ sf.permissions(make_permissions(data.cFileName, data.dwFileAttributes));
+ symlink_sf.permissions(sf.permissions());
+ }
+ return error_code();
+ }
+
+ error_code dir_itr_increment(void *& handle, wstring& target,
+ fs::file_status & sf, fs::file_status & symlink_sf)
+ {
+ WIN32_FIND_DATAW data;
+ if (::FindNextFileW(handle, &data)== 0)// fails
+ {
+ int error = ::GetLastError();
+ fs::detail::dir_itr_close(handle);
+ return error_code(error == ERROR_NO_MORE_FILES ? 0 : error, system_category());
+ }
+ target = data.cFileName;
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+ // reparse points are complex, so don't try to handle them here; instead just mark
+ // them as status_error which causes directory_entry caching to call status()
+ // and symlink_status() which do handle reparse points fully
+ {
+ sf.type(fs::status_error);
+ symlink_sf.type(fs::status_error);
+ }
+ else
+ {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ sf.type(fs::directory_file);
+ symlink_sf.type(fs::directory_file);
+ }
+ else
+ {
+ sf.type(fs::regular_file);
+ symlink_sf.type(fs::regular_file);
+ }
+ sf.permissions(make_permissions(data.cFileName, data.dwFileAttributes));
+ symlink_sf.permissions(sf.permissions());
+ }
+ return error_code();
+ }
+#endif
+
+ const error_code not_found_error_code (
+# ifdef BOOST_WINDOWS_API
+ ERROR_PATH_NOT_FOUND
+# else
+ ENOENT
+# endif
+ , system_category());
+
+} // unnamed namespace
+
+namespace boost
+{
+namespace filesystem
+{
+
+namespace detail
+{
+ // dir_itr_close is called both from the ~dir_itr_imp()destructor
+ // and dir_itr_increment()
+ BOOST_FILESYSTEM_DECL
+ system::error_code dir_itr_close( // never throws
+ void *& handle
+# if defined(BOOST_POSIX_API)
+ , void *& buffer
+# endif
+ )
+ {
+# ifdef BOOST_POSIX_API
+ std::free(buffer);
+ buffer = 0;
+ if (handle == 0)return ok;
+ DIR * h(static_cast<DIR*>(handle));
+ handle = 0;
+ return error_code(::closedir(h)== 0 ? 0 : errno, system_category());
+
+# else
+ if (handle != 0)
+ {
+ ::FindClose(handle);
+ handle = 0;
+ }
+ return ok;
+
+# endif
+ }
+
+ void directory_iterator_construct(directory_iterator& it,
+ const path& p, system::error_code* ec)
+ {
+ if (error(p.empty(), not_found_error_code, p, ec,
+ "boost::filesystem::directory_iterator::construct"))
+ return;
+
+ path::string_type filename;
+ file_status file_stat, symlink_file_stat;
+ error_code result = dir_itr_first(it.m_imp->handle,
+# if defined(BOOST_POSIX_API)
+ it.m_imp->buffer,
+# endif
+ p.c_str(), filename, file_stat, symlink_file_stat);
+
+ if (result)
+ {
+ it.m_imp.reset();
+ error(true, result, p,
+ ec, "boost::filesystem::directory_iterator::construct");
+ return;
+ }
+
+ if (it.m_imp->handle == 0)
+ it.m_imp.reset(); // eof, so make end iterator
+ else // not eof
+ {
+ it.m_imp->dir_entry.assign(p / filename, file_stat, symlink_file_stat);
+ if (filename[0] == dot // dot or dot-dot
+ && (filename.size()== 1
+ || (filename[1] == dot
+ && filename.size()== 2)))
+ { it.increment(*ec); }
+ }
+ }
+
+ void directory_iterator_increment(directory_iterator& it,
+ system::error_code* ec)
+ {
+ BOOST_ASSERT_MSG(it.m_imp.get(), "attempt to increment end iterator");
+ BOOST_ASSERT_MSG(it.m_imp->handle != 0, "internal program error");
+
+ path::string_type filename;
+ file_status file_stat, symlink_file_stat;
+ system::error_code temp_ec;
+
+ for (;;)
+ {
+ temp_ec = dir_itr_increment(it.m_imp->handle,
+# if defined(BOOST_POSIX_API)
+ it.m_imp->buffer,
+# endif
+ filename, file_stat, symlink_file_stat);
+
+ if (temp_ec) // happens if filesystem is corrupt, such as on a damaged optical disc
+ {
+ path error_path(it.m_imp->dir_entry.path().parent_path()); // fix ticket #5900
+ it.m_imp.reset();
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW(
+ filesystem_error("boost::filesystem::directory_iterator::operator++",
+ error_path,
+ error_code(BOOST_ERRNO, system_category())));
+ ec->assign(BOOST_ERRNO, system_category());
+ return;
+ }
+ else if (ec != 0) ec->clear();
+
+ if (it.m_imp->handle == 0) // eof, make end
+ {
+ it.m_imp.reset();
+ return;
+ }
+
+ if (!(filename[0] == dot // !(dot or dot-dot)
+ && (filename.size()== 1
+ || (filename[1] == dot
+ && filename.size()== 2))))
+ {
+ it.m_imp->dir_entry.replace_filename(
+ filename, file_stat, symlink_file_stat);
+ return;
+ }
+ }
+ }
+} // namespace detail
+} // namespace filesystem
+} // namespace boost
diff --git a/3rdParty/Boost/src/libs/filesystem/src/path.cpp b/3rdParty/Boost/src/libs/filesystem/src/path.cpp
new file mode 100644
index 0000000..c740dec
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/path.cpp
@@ -0,0 +1,929 @@
+// filesystem path.cpp ------------------------------------------------------------- //
+
+// Copyright Beman Dawes 2008
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+// Old standard library configurations, particularly MingGW, don't support wide strings.
+// Report this with an explicit error message.
+#include <boost/config.hpp>
+# if defined( BOOST_NO_STD_WSTRING )
+# error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
+# endif
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/system/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+# define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/scoped_array.hpp>
+#include <boost/system/error_code.hpp>
+#include <boost/assert.hpp>
+#include <algorithm>
+#include <cstddef>
+#include <cstring>
+#include <cassert>
+
+#ifdef BOOST_WINDOWS_API
+# include "windows_file_codecvt.hpp"
+# include <windows.h>
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+# include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
+#endif
+
+#ifdef BOOST_FILESYSTEM_DEBUG
+# include <iostream>
+# include <iomanip>
+#endif
+
+namespace fs = boost::filesystem;
+
+using boost::filesystem::path;
+
+using std::string;
+using std::wstring;
+
+using boost::system::error_code;
+
+#ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE
+# define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256
+#endif
+
+//--------------------------------------------------------------------------------------//
+// //
+// class path helpers //
+// //
+//--------------------------------------------------------------------------------------//
+
+namespace
+{
+ //------------------------------------------------------------------------------------//
+ // miscellaneous class path helpers //
+ //------------------------------------------------------------------------------------//
+
+ typedef path::value_type value_type;
+ typedef path::string_type string_type;
+ typedef string_type::size_type size_type;
+
+ const std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE;
+
+# ifdef BOOST_WINDOWS_API
+
+ const wchar_t separator = L'/';
+ const wchar_t* const separators = L"/\\";
+ const wchar_t* separator_string = L"/";
+ const wchar_t* preferred_separator_string = L"\\";
+ const wchar_t colon = L':';
+ const wchar_t dot = L'.';
+ const wchar_t questionmark = L'?';
+ const fs::path dot_path(L".");
+ const fs::path dot_dot_path(L"..");
+
+ inline bool is_letter(wchar_t c)
+ {
+ return (c >= L'a' && c <=L'z') || (c >= L'A' && c <=L'Z');
+ }
+
+# else
+
+ const char separator = '/';
+ const char* const separators = "/";
+ const char* separator_string = "/";
+ const char* preferred_separator_string = "/";
+ const char colon = ':';
+ const char dot = '.';
+ const fs::path dot_path(".");
+ const fs::path dot_dot_path("..");
+
+# endif
+
+ inline bool is_separator(fs::path::value_type c)
+ {
+ return c == separator
+# ifdef BOOST_WINDOWS_API
+ || c == path::preferred_separator
+# endif
+ ;
+ }
+
+ bool is_root_separator(const string_type& str, size_type pos);
+ // pos is position of the separator
+
+ size_type filename_pos(const string_type& str,
+ size_type end_pos); // end_pos is past-the-end position
+ // Returns: 0 if str itself is filename (or empty)
+
+ size_type root_directory_start(const string_type& path, size_type size);
+ // Returns: npos if no root_directory found
+
+ void first_element(
+ const string_type& src,
+ size_type& element_pos,
+ size_type& element_size,
+# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) // VC++ 7.1
+ size_type size = string_type::npos
+# else
+ size_type size = -1
+# endif
+ );
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+// //
+// class path implementation //
+// //
+//--------------------------------------------------------------------------------------//
+
+namespace boost
+{
+namespace filesystem
+{
+ path& path::operator/=(const path& p)
+ {
+ if (p.empty())
+ return *this;
+ if (this == &p) // self-append
+ {
+ path rhs(p);
+ if (!is_separator(rhs.m_pathname[0]))
+ m_append_separator_if_needed();
+ m_pathname += rhs.m_pathname;
+ }
+ else
+ {
+ if (!is_separator(*p.m_pathname.begin()))
+ m_append_separator_if_needed();
+ m_pathname += p.m_pathname;
+ }
+ return *this;
+ }
+
+ path& path::operator/=(const value_type* ptr)
+ {
+ if (!*ptr)
+ return *this;
+ if (ptr >= m_pathname.data()
+ && ptr < m_pathname.data() + m_pathname.size()) // overlapping source
+ {
+ path rhs(ptr);
+ if (!is_separator(rhs.m_pathname[0]))
+ m_append_separator_if_needed();
+ m_pathname += rhs.m_pathname;
+ }
+ else
+ {
+ if (!is_separator(*ptr))
+ m_append_separator_if_needed();
+ m_pathname += ptr;
+ }
+ return *this;
+ }
+
+ int path::compare(const path& p) const BOOST_NOEXCEPT
+ {
+ return detail::lex_compare(begin(), end(), p.begin(), p.end());
+ }
+
+# ifdef BOOST_WINDOWS_API
+
+ const std::string path::generic_string(const codecvt_type& cvt) const
+ {
+ path tmp(*this);
+ std::replace(tmp.m_pathname.begin(), tmp.m_pathname.end(), L'\\', L'/');
+ return tmp.string(cvt);
+ }
+
+ const std::wstring path::generic_wstring() const
+ {
+ path tmp(*this);
+ std::replace(tmp.m_pathname.begin(), tmp.m_pathname.end(), L'\\', L'/');
+ return tmp.wstring();
+ }
+
+# endif // BOOST_WINDOWS_API
+
+ // m_append_separator_if_needed ----------------------------------------------------//
+
+ path::string_type::size_type path::m_append_separator_if_needed()
+ {
+ if (!m_pathname.empty() &&
+# ifdef BOOST_WINDOWS_API
+ *(m_pathname.end()-1) != colon &&
+# endif
+ !is_separator(*(m_pathname.end()-1)))
+ {
+ string_type::size_type tmp(m_pathname.size());
+ m_pathname += preferred_separator;
+ return tmp;
+ }
+ return 0;
+ }
+
+ // m_erase_redundant_separator -----------------------------------------------------//
+
+ void path::m_erase_redundant_separator(string_type::size_type sep_pos)
+ {
+ if (sep_pos // a separator was added
+ && sep_pos < m_pathname.size() // and something was appended
+ && (m_pathname[sep_pos+1] == separator // and it was also separator
+# ifdef BOOST_WINDOWS_API
+ || m_pathname[sep_pos+1] == preferred_separator // or preferred_separator
+# endif
+)) { m_pathname.erase(sep_pos, 1); } // erase the added separator
+ }
+
+ // modifiers -----------------------------------------------------------------------//
+
+# ifdef BOOST_WINDOWS_API
+ path & path::make_preferred()
+ {
+ std::replace(m_pathname.begin(), m_pathname.end(), L'/', L'\\');
+ return *this;
+ }
+# endif
+
+ path& path::remove_filename()
+ {
+ m_pathname.erase(m_parent_path_end());
+ return *this;
+ }
+
+ path& path::replace_extension(const path& new_extension)
+ {
+ // erase existing extension, including the dot, if any
+ m_pathname.erase(m_pathname.size()-extension().m_pathname.size());
+
+ if (!new_extension.empty())
+ {
+ // append new_extension, adding the dot if necessary
+ if (new_extension.m_pathname[0] != dot)
+ m_pathname.push_back(dot);
+ m_pathname.append(new_extension.m_pathname);
+ }
+
+ return *this;
+ }
+
+ // decomposition -------------------------------------------------------------------//
+
+ path path::root_path() const
+ {
+ path temp(root_name());
+ if (!root_directory().empty()) temp.m_pathname += root_directory().c_str();
+ return temp;
+ }
+
+ path path::root_name() const
+ {
+ iterator itr(begin());
+
+ return (itr.m_pos != m_pathname.size()
+ && (
+ (itr.m_element.m_pathname.size() > 1
+ && is_separator(itr.m_element.m_pathname[0])
+ && is_separator(itr.m_element.m_pathname[1])
+ )
+# ifdef BOOST_WINDOWS_API
+ || itr.m_element.m_pathname[itr.m_element.m_pathname.size()-1] == colon
+# endif
+ ))
+ ? itr.m_element
+ : path();
+ }
+
+ path path::root_directory() const
+ {
+ size_type pos(root_directory_start(m_pathname, m_pathname.size()));
+
+ return pos == string_type::npos
+ ? path()
+ : path(m_pathname.c_str() + pos, m_pathname.c_str() + pos + 1);
+ }
+
+ path path::relative_path() const
+ {
+ iterator itr(begin());
+
+ for (; itr.m_pos != m_pathname.size()
+ && (is_separator(itr.m_element.m_pathname[0])
+# ifdef BOOST_WINDOWS_API
+ || itr.m_element.m_pathname[itr.m_element.m_pathname.size()-1] == colon
+# endif
+ ); ++itr) {}
+
+ return path(m_pathname.c_str() + itr.m_pos);
+ }
+
+ string_type::size_type path::m_parent_path_end() const
+ {
+ size_type end_pos(filename_pos(m_pathname, m_pathname.size()));
+
+ bool filename_was_separator(m_pathname.size()
+ && is_separator(m_pathname[end_pos]));
+
+ // skip separators unless root directory
+ size_type root_dir_pos(root_directory_start(m_pathname, end_pos));
+ for (;
+ end_pos > 0
+ && (end_pos-1) != root_dir_pos
+ && is_separator(m_pathname[end_pos-1])
+ ;
+ --end_pos) {}
+
+ return (end_pos == 1 && root_dir_pos == 0 && filename_was_separator)
+ ? string_type::npos
+ : end_pos;
+ }
+
+ path path::parent_path() const
+ {
+ size_type end_pos(m_parent_path_end());
+ return end_pos == string_type::npos
+ ? path()
+ : path(m_pathname.c_str(), m_pathname.c_str() + end_pos);
+ }
+
+ path path::filename() const
+ {
+ size_type pos(filename_pos(m_pathname, m_pathname.size()));
+ return (m_pathname.size()
+ && pos
+ && is_separator(m_pathname[pos])
+ && !is_root_separator(m_pathname, pos))
+ ? dot_path
+ : path(m_pathname.c_str() + pos);
+ }
+
+ path path::stem() const
+ {
+ path name(filename());
+ if (name == dot_path || name == dot_dot_path) return name;
+ size_type pos(name.m_pathname.rfind(dot));
+ return pos == string_type::npos
+ ? name
+ : path(name.m_pathname.c_str(), name.m_pathname.c_str() + pos);
+ }
+
+ path path::extension() const
+ {
+ path name(filename());
+ if (name == dot_path || name == dot_dot_path) return path();
+ size_type pos(name.m_pathname.rfind(dot));
+ return pos == string_type::npos
+ ? path()
+ : path(name.m_pathname.c_str() + pos);
+ }
+
+ // m_normalize ----------------------------------------------------------------------//
+
+ path& path::m_normalize()
+ {
+ if (m_pathname.empty()) return *this;
+
+ path temp;
+ iterator start(begin());
+ iterator last(end());
+ iterator stop(last--);
+ for (iterator itr(start); itr != stop; ++itr)
+ {
+ // ignore "." except at start and last
+ if (itr->native().size() == 1
+ && (itr->native())[0] == dot
+ && itr != start
+ && itr != last) continue;
+
+ // ignore a name and following ".."
+ if (!temp.empty()
+ && itr->native().size() == 2
+ && (itr->native())[0] == dot
+ && (itr->native())[1] == dot) // dot dot
+ {
+ string_type lf(temp.filename().native());
+ if (lf.size() > 0
+ && (lf.size() != 1
+ || (lf[0] != dot
+ && lf[0] != separator))
+ && (lf.size() != 2
+ || (lf[0] != dot
+ && lf[1] != dot
+# ifdef BOOST_WINDOWS_API
+ && lf[1] != colon
+# endif
+ )
+ )
+ )
+ {
+ temp.remove_filename();
+ // if not root directory, must also remove "/" if any
+ if (temp.m_pathname.size() > 0
+ && temp.m_pathname[temp.m_pathname.size()-1]
+ == separator)
+ {
+ string_type::size_type rds(
+ root_directory_start(temp.m_pathname, temp.m_pathname.size()));
+ if (rds == string_type::npos
+ || rds != temp.m_pathname.size()-1)
+ { temp.m_pathname.erase(temp.m_pathname.size()-1); }
+ }
+
+ iterator next(itr);
+ if (temp.empty() && ++next != stop
+ && next == last && *last == dot_path) temp /= dot_path;
+ continue;
+ }
+ }
+
+ temp /= *itr;
+ };
+
+ if (temp.empty()) temp /= dot_path;
+ m_pathname = temp.m_pathname;
+ return *this;
+ }
+
+} // namespace filesystem
+} // namespace boost
+
+//--------------------------------------------------------------------------------------//
+// //
+// class path helpers implementation //
+// //
+//--------------------------------------------------------------------------------------//
+
+namespace
+{
+
+ // is_root_separator ---------------------------------------------------------------//
+
+ bool is_root_separator(const string_type & str, size_type pos)
+ // pos is position of the separator
+ {
+ BOOST_ASSERT_MSG(!str.empty() && is_separator(str[pos]),
+ "precondition violation");
+
+ // subsequent logic expects pos to be for leftmost slash of a set
+ while (pos > 0 && is_separator(str[pos-1]))
+ --pos;
+
+ // "/" [...]
+ if (pos == 0)
+ return true;
+
+# ifdef BOOST_WINDOWS_API
+ // "c:/" [...]
+ if (pos == 2 && is_letter(str[0]) && str[1] == colon)
+ return true;
+# endif
+
+ // "//" name "/"
+ if (pos < 3 || !is_separator(str[0]) || !is_separator(str[1]))
+ return false;
+
+ return str.find_first_of(separators, 2) == pos;
+ }
+
+ // filename_pos --------------------------------------------------------------------//
+
+ size_type filename_pos(const string_type & str,
+ size_type end_pos) // end_pos is past-the-end position
+ // return 0 if str itself is filename (or empty)
+ {
+ // case: "//"
+ if (end_pos == 2
+ && is_separator(str[0])
+ && is_separator(str[1])) return 0;
+
+ // case: ends in "/"
+ if (end_pos && is_separator(str[end_pos-1]))
+ return end_pos-1;
+
+ // set pos to start of last element
+ size_type pos(str.find_last_of(separators, end_pos-1));
+
+# ifdef BOOST_WINDOWS_API
+ if (pos == string_type::npos)
+ pos = str.find_last_of(colon, end_pos-2);
+# endif
+
+ return (pos == string_type::npos // path itself must be a filename (or empty)
+ || (pos == 1 && is_separator(str[0]))) // or net
+ ? 0 // so filename is entire string
+ : pos + 1; // or starts after delimiter
+ }
+
+ // root_directory_start ------------------------------------------------------------//
+
+ size_type root_directory_start(const string_type & path, size_type size)
+ // return npos if no root_directory found
+ {
+
+# ifdef BOOST_WINDOWS_API
+ // case "c:/"
+ if (size > 2
+ && path[1] == colon
+ && is_separator(path[2])) return 2;
+# endif
+
+ // case "//"
+ if (size == 2
+ && is_separator(path[0])
+ && is_separator(path[1])) return string_type::npos;
+
+# ifdef BOOST_WINDOWS_API
+ // case "\\?\"
+ if (size > 4
+ && is_separator(path[0])
+ && is_separator(path[1])
+ && path[2] == questionmark
+ && is_separator(path[3]))
+ {
+ string_type::size_type pos(path.find_first_of(separators, 4));
+ return pos < size ? pos : string_type::npos;
+ }
+# endif
+
+ // case "//net {/}"
+ if (size > 3
+ && is_separator(path[0])
+ && is_separator(path[1])
+ && !is_separator(path[2]))
+ {
+ string_type::size_type pos(path.find_first_of(separators, 2));
+ return pos < size ? pos : string_type::npos;
+ }
+
+ // case "/"
+ if (size > 0 && is_separator(path[0])) return 0;
+
+ return string_type::npos;
+ }
+
+ // first_element --------------------------------------------------------------------//
+ // sets pos and len of first element, excluding extra separators
+ // if src.empty(), sets pos,len, to 0,0.
+
+ void first_element(
+ const string_type & src,
+ size_type & element_pos,
+ size_type & element_size,
+ size_type size
+)
+ {
+ if (size == string_type::npos) size = src.size();
+ element_pos = 0;
+ element_size = 0;
+ if (src.empty()) return;
+
+ string_type::size_type cur(0);
+
+ // deal with // [network]
+ if (size >= 2 && is_separator(src[0])
+ && is_separator(src[1])
+ && (size == 2
+ || !is_separator(src[2])))
+ {
+ cur += 2;
+ element_size += 2;
+ }
+
+ // leading (not non-network) separator
+ else if (is_separator(src[0]))
+ {
+ ++element_size;
+ // bypass extra leading separators
+ while (cur+1 < size
+ && is_separator(src[cur+1]))
+ {
+ ++cur;
+ ++element_pos;
+ }
+ return;
+ }
+
+ // at this point, we have either a plain name, a network name,
+ // or (on Windows only) a device name
+
+ // find the end
+ while (cur < size
+# ifdef BOOST_WINDOWS_API
+ && src[cur] != colon
+# endif
+ && !is_separator(src[cur]))
+ {
+ ++cur;
+ ++element_size;
+ }
+
+# ifdef BOOST_WINDOWS_API
+ if (cur == size) return;
+ // include device delimiter
+ if (src[cur] == colon)
+ { ++element_size; }
+# endif
+
+ return;
+ }
+
+} // unnamed namespace
+
+
+namespace boost
+{
+namespace filesystem
+{
+ namespace detail
+ {
+ BOOST_FILESYSTEM_DECL
+ int lex_compare(path::iterator first1, path::iterator last1,
+ path::iterator first2, path::iterator last2)
+ {
+ for (; first1 != last1 && first2 != last2;)
+ {
+ if (first1->native() < first2->native()) return -1;
+ if (first2->native() < first1->native()) return 1;
+ BOOST_ASSERT(first2->native() == first1->native());
+ ++first1;
+ ++first2;
+ }
+ if (first1 == last1 && first2 == last2)
+ return 0;
+ return first1 == last1 ? -1 : 1;
+ }
+ }
+
+//--------------------------------------------------------------------------------------//
+// //
+// class path::iterator implementation //
+// //
+//--------------------------------------------------------------------------------------//
+
+ path::iterator path::begin() const
+ {
+ iterator itr;
+ itr.m_path_ptr = this;
+ size_type element_size;
+ first_element(m_pathname, itr.m_pos, element_size);
+ itr.m_element = m_pathname.substr(itr.m_pos, element_size);
+ if (itr.m_element.m_pathname == preferred_separator_string)
+ itr.m_element.m_pathname = separator_string; // needed for Windows, harmless on POSIX
+ return itr;
+ }
+
+ path::iterator path::end() const
+ {
+ iterator itr;
+ itr.m_path_ptr = this;
+ itr.m_pos = m_pathname.size();
+ return itr;
+ }
+
+ void path::m_path_iterator_increment(path::iterator & it)
+ {
+ BOOST_ASSERT_MSG(it.m_pos < it.m_path_ptr->m_pathname.size(),
+ "path::basic_iterator increment past end()");
+
+ // increment to position past current element; if current element is implicit dot,
+ // this will cause it.m_pos to represent the end iterator
+ it.m_pos += it.m_element.m_pathname.size();
+
+ // if the end is reached, we are done
+ if (it.m_pos == it.m_path_ptr->m_pathname.size())
+ {
+ it.m_element.clear(); // aids debugging, may release unneeded memory
+ return;
+ }
+
+ // both POSIX and Windows treat paths that begin with exactly two separators specially
+ bool was_net(it.m_element.m_pathname.size() > 2
+ && is_separator(it.m_element.m_pathname[0])
+ && is_separator(it.m_element.m_pathname[1])
+ && !is_separator(it.m_element.m_pathname[2]));
+
+ // process separator (Windows drive spec is only case not a separator)
+ if (is_separator(it.m_path_ptr->m_pathname[it.m_pos]))
+ {
+ // detect root directory
+ if (was_net
+# ifdef BOOST_WINDOWS_API
+ // case "c:/"
+ || it.m_element.m_pathname[it.m_element.m_pathname.size()-1] == colon
+# endif
+ )
+ {
+ it.m_element.m_pathname = separator; // generic format; see docs
+ return;
+ }
+
+ // skip separators until it.m_pos points to the start of the next element
+ while (it.m_pos != it.m_path_ptr->m_pathname.size()
+ && is_separator(it.m_path_ptr->m_pathname[it.m_pos]))
+ { ++it.m_pos; }
+
+ // detect trailing separator, and treat it as ".", per POSIX spec
+ if (it.m_pos == it.m_path_ptr->m_pathname.size()
+ && !is_root_separator(it.m_path_ptr->m_pathname, it.m_pos-1))
+ {
+ --it.m_pos;
+ it.m_element = dot_path;
+ return;
+ }
+ }
+
+ // get m_element
+ size_type end_pos(it.m_path_ptr->m_pathname.find_first_of(separators, it.m_pos));
+ if (end_pos == string_type::npos)
+ end_pos = it.m_path_ptr->m_pathname.size();
+ it.m_element = it.m_path_ptr->m_pathname.substr(it.m_pos, end_pos - it.m_pos);
+ }
+
+ void path::m_path_iterator_decrement(path::iterator & it)
+ {
+ BOOST_ASSERT_MSG(it.m_pos, "path::iterator decrement past begin()");
+
+ size_type end_pos(it.m_pos);
+
+ // if at end and there was a trailing non-root '/', return "."
+ if (it.m_pos == it.m_path_ptr->m_pathname.size()
+ && it.m_path_ptr->m_pathname.size() > 1
+ && is_separator(it.m_path_ptr->m_pathname[it.m_pos-1])
+ && !is_root_separator(it.m_path_ptr->m_pathname, it.m_pos-1)
+ )
+ {
+ --it.m_pos;
+ it.m_element = dot_path;
+ return;
+ }
+
+ size_type root_dir_pos(root_directory_start(it.m_path_ptr->m_pathname, end_pos));
+
+ // skip separators unless root directory
+ for (
+ ;
+ end_pos > 0
+ && (end_pos-1) != root_dir_pos
+ && is_separator(it.m_path_ptr->m_pathname[end_pos-1])
+ ;
+ --end_pos) {}
+
+ it.m_pos = filename_pos(it.m_path_ptr->m_pathname, end_pos);
+ it.m_element = it.m_path_ptr->m_pathname.substr(it.m_pos, end_pos - it.m_pos);
+ if (it.m_element.m_pathname == preferred_separator_string) // needed for Windows, harmless on POSIX
+ it.m_element.m_pathname = separator_string; // generic format; see docs
+ }
+
+} // namespace filesystem
+} // namespace boost
+
+//--------------------------------------------------------------------------------------//
+// //
+// detail helpers //
+// //
+//--------------------------------------------------------------------------------------//
+
+namespace
+{
+
+ //------------------------------------------------------------------------------------//
+ // locale helpers //
+ //------------------------------------------------------------------------------------//
+
+#if defined(BOOST_WINDOWS_API) && defined(BOOST_FILESYSTEM_STATIC_LINK)
+
+ inline std::locale default_locale()
+ {
+ std::locale global_loc = std::locale();
+ std::locale loc(global_loc, new windows_file_codecvt);
+ return loc;
+ }
+
+ inline std::locale& path_locale()
+ {
+ static std::locale loc(default_locale());
+ return loc;
+ }
+
+ inline const path::codecvt_type*& codecvt_facet_ptr()
+ {
+ static const std::codecvt<wchar_t, char, std::mbstate_t>*
+ facet(
+ &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
+ (path_locale()));
+ return facet;
+ }
+
+#elif defined(BOOST_WINDOWS_API) && !defined(BOOST_FILESYSTEM_STATIC_LINK)
+
+ std::locale path_locale(std::locale(), new windows_file_codecvt);
+
+ const std::codecvt<wchar_t, char, std::mbstate_t>*
+ codecvt_facet_ptr(&std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
+ (path_locale));
+
+#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)
+
+ // "All BSD system functions expect their string parameters to be in UTF-8 encoding
+ // and nothing else." See
+ // http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPInternational/Articles/FileEncodings.html
+ //
+ // "The kernel will reject any filename that is not a valid UTF-8 string, and it will
+ // even be normalized (to Unicode NFD) before stored on disk, at least when using HFS.
+ // The right way to deal with it would be to always convert the filename to UTF-8
+ // before trying to open/create a file." See
+ // http://lists.apple.com/archives/unix-porting/2007/Sep/msg00023.html
+ //
+ // "How a file name looks at the API level depends on the API. Current Carbon APIs
+ // handle file names as an array of UTF-16 characters; POSIX ones handle them as an
+ // array of UTF-8, which is why UTF-8 works well in Terminal. How it's stored on disk
+ // depends on the disk format; HFS+ uses UTF-16, but that's not important in most
+ // cases." See
+ // http://lists.apple.com/archives/applescript-users/2002/Sep/msg00319.html
+ //
+ // Many thanks to Peter Dimov for digging out the above references!
+
+ std::locale path_locale(std::locale(),
+ new boost::filesystem::detail::utf8_codecvt_facet);
+
+ const std::codecvt<wchar_t, char, std::mbstate_t>*
+ codecvt_facet_ptr(&std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >
+ (path_locale));
+
+#else // Other POSIX
+
+ // ISO C calls std::locale("") "the locale-specific native environment", and this
+ // locale is the default for many POSIX-based operating systems such as Linux.
+
+ // std::locale("") construction can throw (if environmental variables LC_MESSAGES or
+ // or LANG are wrong, for example), so lazy initialization is used to ensure
+ // that exceptions occur after main() starts and so can be caught.
+
+ std::locale path_locale; // initialized by path::codecvt() below
+ const std::codecvt<wchar_t, char, std::mbstate_t>* codecvt_facet_ptr; // ditto
+
+# endif
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+// path::imbue implementation //
+//--------------------------------------------------------------------------------------//
+
+namespace boost
+{
+namespace filesystem
+{
+
+#if defined(BOOST_WINDOWS_API) && defined(BOOST_FILESYSTEM_STATIC_LINK)
+
+ const path::codecvt_type& path::codecvt()
+ {
+ BOOST_ASSERT_MSG(codecvt_facet_ptr(), "codecvt_facet_ptr() facet hasn't been properly initialized");
+ return *codecvt_facet_ptr();
+ }
+
+ std::locale path::imbue(const std::locale & loc)
+ {
+ std::locale temp(path_locale());
+ path_locale() = loc;
+ codecvt_facet_ptr() =
+ &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale());
+ return temp;
+ }
+
+#else
+
+ const path::codecvt_type& path::codecvt()
+ {
+# if defined(BOOST_POSIX_API) && \
+ !(defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__))
+ // A local static initialized by calling path::imbue ensures that std::locale(""),
+ // which may throw, is called only if path_locale and condecvt_facet will actually
+ // be used. Thus misconfigured environmental variables will only cause an
+ // exception if a valid std::locale("") is actually needed.
+ static std::locale posix_lazy_initialization(path::imbue(std::locale("")));
+# endif
+ return *codecvt_facet_ptr;
+ }
+
+ std::locale path::imbue(const std::locale& loc)
+ {
+ std::locale temp(path_locale);
+ path_locale = loc;
+ codecvt_facet_ptr =
+ &std::use_facet<std::codecvt<wchar_t, char, std::mbstate_t> >(path_locale);
+ return temp;
+ }
+
+
+#endif
+
+} // namespace filesystem
+} // namespace boost
diff --git a/3rdParty/Boost/src/libs/filesystem/src/path_traits.cpp b/3rdParty/Boost/src/libs/filesystem/src/path_traits.cpp
new file mode 100644
index 0000000..06ac798
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/path_traits.cpp
@@ -0,0 +1,200 @@
+// filesystem path_traits.cpp --------------------------------------------------------//
+
+// Copyright Beman Dawes 2008, 2009
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/system/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+# define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/path_traits.hpp>
+#include <boost/system/system_error.hpp>
+#include <boost/scoped_array.hpp>
+#include <locale> // for codecvt_base::result
+#include <cstring> // for strlen
+#include <cwchar> // for wcslen
+
+namespace pt = boost::filesystem::path_traits;
+namespace fs = boost::filesystem;
+namespace bs = boost::system;
+
+//--------------------------------------------------------------------------------------//
+// configuration //
+//--------------------------------------------------------------------------------------//
+
+#ifndef BOOST_FILESYSTEM_CODECVT_BUF_SIZE
+# define BOOST_FILESYSTEM_CODECVT_BUF_SIZE 256
+#endif
+
+namespace {
+
+ const std::size_t default_codecvt_buf_size = BOOST_FILESYSTEM_CODECVT_BUF_SIZE;
+
+
+//--------------------------------------------------------------------------------------//
+// //
+// The public convert() functions do buffer management, and then forward to the //
+// convert_aux() functions for the actual call to the codecvt facet. //
+// //
+//--------------------------------------------------------------------------------------//
+
+//--------------------------------------------------------------------------------------//
+// convert_aux const char* to wstring //
+//--------------------------------------------------------------------------------------//
+
+ void convert_aux(
+ const char* from,
+ const char* from_end,
+ wchar_t* to, wchar_t* to_end,
+ std::wstring & target,
+ const pt::codecvt_type & cvt)
+ {
+ //std::cout << std::hex
+ // << " from=" << std::size_t(from)
+ // << " from_end=" << std::size_t(from_end)
+ // << " to=" << std::size_t(to)
+ // << " to_end=" << std::size_t(to_end)
+ // << std::endl;
+
+ std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
+ const char* from_next;
+ wchar_t* to_next;
+
+ std::codecvt_base::result res;
+
+ if ((res=cvt.in(state, from, from_end, from_next,
+ to, to_end, to_next)) != std::codecvt_base::ok)
+ {
+ //std::cout << " result is " << static_cast<int>(res) << std::endl;
+ BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(),
+ "boost::filesystem::path codecvt to wstring"));
+ }
+ target.append(to, to_next);
+ }
+
+//--------------------------------------------------------------------------------------//
+// convert_aux const wchar_t* to string //
+//--------------------------------------------------------------------------------------//
+
+ void convert_aux(
+ const wchar_t* from,
+ const wchar_t* from_end,
+ char* to, char* to_end,
+ std::string & target,
+ const pt::codecvt_type & cvt)
+ {
+ //std::cout << std::hex
+ // << " from=" << std::size_t(from)
+ // << " from_end=" << std::size_t(from_end)
+ // << " to=" << std::size_t(to)
+ // << " to_end=" << std::size_t(to_end)
+ // << std::endl;
+
+ std::mbstate_t state = std::mbstate_t(); // perhaps unneeded, but cuts bug reports
+ const wchar_t* from_next;
+ char* to_next;
+
+ std::codecvt_base::result res;
+
+ if ((res=cvt.out(state, from, from_end, from_next,
+ to, to_end, to_next)) != std::codecvt_base::ok)
+ {
+ //std::cout << " result is " << static_cast<int>(res) << std::endl;
+ BOOST_FILESYSTEM_THROW(bs::system_error(res, fs::codecvt_error_category(),
+ "boost::filesystem::path codecvt to string"));
+ }
+ target.append(to, to_next);
+ }
+
+} // unnamed namespace
+
+//--------------------------------------------------------------------------------------//
+// path_traits //
+//--------------------------------------------------------------------------------------//
+
+namespace boost { namespace filesystem { namespace path_traits {
+
+//--------------------------------------------------------------------------------------//
+// convert const char* to wstring //
+//--------------------------------------------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ void convert(const char* from,
+ const char* from_end, // 0 for null terminated MBCS
+ std::wstring & to,
+ const codecvt_type & cvt)
+ {
+ BOOST_ASSERT(from);
+
+ if (!from_end) // null terminated
+ {
+ from_end = from + std::strlen(from);
+ }
+
+ if (from == from_end) return;
+
+ std::size_t buf_size = (from_end - from) * 3; // perhaps too large, but that's OK
+
+ // dynamically allocate a buffer only if source is unusually large
+ if (buf_size > default_codecvt_buf_size)
+ {
+ boost::scoped_array< wchar_t > buf(new wchar_t [buf_size]);
+ convert_aux(from, from_end, buf.get(), buf.get()+buf_size, to, cvt);
+ }
+ else
+ {
+ wchar_t buf[default_codecvt_buf_size];
+ convert_aux(from, from_end, buf, buf+default_codecvt_buf_size, to, cvt);
+ }
+ }
+
+//--------------------------------------------------------------------------------------//
+// convert const wchar_t* to string //
+//--------------------------------------------------------------------------------------//
+
+ BOOST_FILESYSTEM_DECL
+ void convert(const wchar_t* from,
+ const wchar_t* from_end, // 0 for null terminated MBCS
+ std::string & to,
+ const codecvt_type & cvt)
+ {
+ BOOST_ASSERT(from);
+
+ if (!from_end) // null terminated
+ {
+ from_end = from + std::wcslen(from);
+ }
+
+ if (from == from_end) return;
+
+ // The codecvt length functions may not be implemented, and I don't really
+ // understand them either. Thus this code is just a guess; if it turns
+ // out the buffer is too small then an error will be reported and the code
+ // will have to be fixed.
+ std::size_t buf_size = (from_end - from) * 4; // perhaps too large, but that's OK
+ buf_size += 4; // encodings like shift-JIS need some prefix space
+
+ // dynamically allocate a buffer only if source is unusually large
+ if (buf_size > default_codecvt_buf_size)
+ {
+ boost::scoped_array< char > buf(new char [buf_size]);
+ convert_aux(from, from_end, buf.get(), buf.get()+buf_size, to, cvt);
+ }
+ else
+ {
+ char buf[default_codecvt_buf_size];
+ convert_aux(from, from_end, buf, buf+default_codecvt_buf_size, to, cvt);
+ }
+ }
+}}} // namespace boost::filesystem::path_traits
diff --git a/3rdParty/Boost/src/libs/filesystem/src/portability.cpp b/3rdParty/Boost/src/libs/filesystem/src/portability.cpp
new file mode 100644
index 0000000..b1a1352
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/portability.cpp
@@ -0,0 +1,119 @@
+// portability.cpp -------------------------------------------------------------------//
+
+// Copyright 2002-2005 Beman Dawes
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
+// at http://www.boost.org/LICENSE_1_0.txt)
+
+// See library home page at http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+# define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/config.hpp>
+#include <boost/filesystem/path.hpp>
+
+namespace fs = boost::filesystem;
+
+#include <cstring> // SGI MIPSpro compilers need this
+
+# ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::strerror; }
+# endif
+
+//--------------------------------------------------------------------------------------//
+
+namespace
+{
+ const char invalid_chars[] =
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F"
+ "<>:\"/\\|";
+ // note that the terminating '\0' is part of the string - thus the size below
+ // is sizeof(invalid_chars) rather than sizeof(invalid_chars)-1. I
+ const std::string windows_invalid_chars(invalid_chars, sizeof(invalid_chars));
+
+ const std::string valid_posix(
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-");
+
+} // unnamed namespace
+
+namespace boost
+{
+ namespace filesystem
+ {
+
+ // name_check functions ----------------------------------------------//
+
+# ifdef BOOST_WINDOWS
+ BOOST_FILESYSTEM_DECL bool native(const std::string & name)
+ {
+ return windows_name(name);
+ }
+# else
+ BOOST_FILESYSTEM_DECL bool native(const std::string & name)
+ {
+ return name.size() != 0
+ && name[0] != ' '
+ && name.find('/') == std::string::npos;
+ }
+# endif
+
+ BOOST_FILESYSTEM_DECL bool portable_posix_name(const std::string & name)
+ {
+ return name.size() != 0
+ && name.find_first_not_of(valid_posix) == std::string::npos;
+ }
+
+ BOOST_FILESYSTEM_DECL bool windows_name(const std::string & name)
+ {
+ return name.size() != 0
+ && name[0] != ' '
+ && name.find_first_of(windows_invalid_chars) == std::string::npos
+ && *(name.end()-1) != ' '
+ && (*(name.end()-1) != '.'
+ || name.length() == 1 || name == "..");
+ }
+
+ BOOST_FILESYSTEM_DECL bool portable_name(const std::string & name)
+ {
+ return
+ name.size() != 0
+ && (name == "."
+ || name == ".."
+ || (windows_name(name)
+ && portable_posix_name(name)
+ && name[0] != '.' && name[0] != '-'));
+ }
+
+ BOOST_FILESYSTEM_DECL bool portable_directory_name(const std::string & name)
+ {
+ return
+ name == "."
+ || name == ".."
+ || (portable_name(name)
+ && name.find('.') == std::string::npos);
+ }
+
+ BOOST_FILESYSTEM_DECL bool portable_file_name(const std::string & name)
+ {
+ std::string::size_type pos;
+ return
+ portable_name(name)
+ && name != "."
+ && name != ".."
+ && ((pos = name.find('.')) == std::string::npos
+ || (name.find('.', pos+1) == std::string::npos
+ && (pos + 5) > name.length()))
+ ;
+ }
+
+ } // namespace filesystem
+} // namespace boost
diff --git a/3rdParty/Boost/src/libs/filesystem/src/unique_path.cpp b/3rdParty/Boost/src/libs/filesystem/src/unique_path.cpp
new file mode 100644
index 0000000..c25c315
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/unique_path.cpp
@@ -0,0 +1,142 @@
+// filesystem unique_path.cpp --------------------------------------------------------//
+
+// Copyright Beman Dawes 2010
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+# define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/operations.hpp>
+
+# ifdef BOOST_POSIX_API
+# include <fcntl.h>
+# else // BOOST_WINDOWS_API
+# include <windows.h>
+# include <wincrypt.h>
+# pragma comment(lib, "Advapi32.lib")
+# endif
+
+namespace {
+
+void fail(int err, boost::system::error_code* ec)
+{
+ if (ec == 0)
+ BOOST_FILESYSTEM_THROW( boost::system::system_error(err,
+ boost::system::system_category(),
+ "boost::filesystem::unique_path"));
+
+ ec->assign(err, boost::system::system_category());
+ return;
+}
+
+void system_crypt_random(void* buf, std::size_t len, boost::system::error_code* ec)
+{
+# ifdef BOOST_POSIX_API
+
+ int file = open("/dev/urandom", O_RDONLY);
+ if (file == -1)
+ {
+ file = open("/dev/random", O_RDONLY);
+ if (file == -1)
+ {
+ fail(errno, ec);
+ return;
+ }
+ }
+
+ size_t bytes_read = 0;
+ while (bytes_read < len)
+ {
+ ssize_t n = read(file, buf, len - bytes_read);
+ if (n == -1)
+ {
+ close(file);
+ fail(errno, ec);
+ return;
+ }
+ bytes_read += n;
+ buf = static_cast<char*>(buf) + n;
+ }
+
+ close(file);
+
+# else // BOOST_WINDOWS_API
+
+ HCRYPTPROV handle;
+ int errval = 0;
+
+ if (!::CryptAcquireContextW(&handle, 0, 0, PROV_RSA_FULL, 0))
+ {
+ errval = ::GetLastError();
+ if (errval == NTE_BAD_KEYSET)
+ {
+ if (!::CryptAcquireContextW(&handle, 0, 0, PROV_RSA_FULL, CRYPT_NEWKEYSET))
+ {
+ errval = ::GetLastError();
+ }
+ else errval = 0;
+ }
+ }
+
+ if (!errval)
+ {
+ BOOL gen_ok = ::CryptGenRandom(handle, len, static_cast<unsigned char*>(buf));
+ if (!gen_ok)
+ errval = ::GetLastError();
+ ::CryptReleaseContext(handle, 0);
+ }
+
+ if (!errval) return;
+
+ fail(errval, ec);
+# endif
+}
+
+} // unnamed namespace
+
+namespace boost { namespace filesystem { namespace detail {
+
+BOOST_FILESYSTEM_DECL
+path unique_path(const path& model, system::error_code* ec)
+{
+ std::wstring s (model.wstring()); // std::string ng for MBCS encoded POSIX
+ const wchar_t hex[] = L"0123456789abcdef";
+ const int n_ran = 16;
+ const int max_nibbles = 2 * n_ran; // 4-bits per nibble
+ char ran[n_ran];
+
+ int nibbles_used = max_nibbles;
+ for(std::wstring::size_type i=0; i < s.size(); ++i)
+ {
+ if (s[i] == L'%') // digit request
+ {
+ if (nibbles_used == max_nibbles)
+ {
+ system_crypt_random(ran, sizeof(ran), ec);
+ if (ec != 0 && *ec)
+ return "";
+ nibbles_used = 0;
+ }
+ int c = ran[nibbles_used/2];
+ c >>= 4 * (nibbles_used++ & 1); // if odd, shift right 1 nibble
+ s[i] = hex[c & 0xf]; // convert to hex digit and replace
+ }
+ }
+
+ if (ec != 0) ec->clear();
+
+ return s;
+}
+
+}}}
diff --git a/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.cpp b/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.cpp
new file mode 100644
index 0000000..998db60
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.cpp
@@ -0,0 +1,75 @@
+// filesystem windows_file_codecvt.cpp -----------------------------------------//
+
+// Copyright Beman Dawes 2009
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+//--------------------------------------------------------------------------------------//
+
+// define BOOST_FILESYSTEM_SOURCE so that <boost/system/config.hpp> knows
+// the library is being built (possibly exporting rather than importing code)
+#define BOOST_FILESYSTEM_SOURCE
+
+#ifndef BOOST_SYSTEM_NO_DEPRECATED
+# define BOOST_SYSTEM_NO_DEPRECATED
+#endif
+
+#include <boost/filesystem/config.hpp>
+#include <cwchar> // for mbstate_t
+
+#ifdef BOOST_WINDOWS_API
+
+#include "windows_file_codecvt.hpp"
+
+// Versions of MinGW prior to GCC 4.6 requires this
+#ifndef WINVER
+# define WINVER 0x0500
+#endif
+
+#include <windows.h>
+
+ std::codecvt_base::result windows_file_codecvt::do_in(
+ std::mbstate_t &,
+ const char* from, const char* from_end, const char*& from_next,
+ wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const
+ {
+ UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+
+ int count;
+ if ((count = ::MultiByteToWideChar(codepage, MB_PRECOMPOSED, from,
+ from_end - from, to, to_end - to)) == 0)
+ {
+ return error; // conversion failed
+ }
+
+ from_next = from_end;
+ to_next = to + count;
+ *to_next = L'\0';
+ return ok;
+ }
+
+ std::codecvt_base::result windows_file_codecvt::do_out(
+ std::mbstate_t &,
+ const wchar_t* from, const wchar_t* from_end, const wchar_t* & from_next,
+ char* to, char* to_end, char* & to_next) const
+ {
+ UINT codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
+
+ int count;
+ if ((count = ::WideCharToMultiByte(codepage, WC_NO_BEST_FIT_CHARS, from,
+ from_end - from, to, to_end - to, 0, 0)) == 0)
+ {
+ return error; // conversion failed
+ }
+
+ from_next = from_end;
+ to_next = to + count;
+ *to_next = '\0';
+ return ok;
+ }
+
+ # endif // BOOST_WINDOWS_API
+
diff --git a/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.hpp b/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.hpp
new file mode 100644
index 0000000..52deab1
--- /dev/null
+++ b/3rdParty/Boost/src/libs/filesystem/src/windows_file_codecvt.hpp
@@ -0,0 +1,56 @@
+// filesystem windows_file_codecvt.hpp -----------------------------------------------//
+
+// Copyright Beman Dawes 2009
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+// Library home page: http://www.boost.org/libs/filesystem
+
+#ifndef BOOST_FILESYSTEM3_WIN_FILE_CODECVT_HPP
+#define BOOST_FILESYSTEM3_WIN_FILE_CODECVT_HPP
+
+#include <boost/filesystem/config.hpp>
+#include <locale>
+
+ //------------------------------------------------------------------------------------//
+ // //
+ // class windows_file_codecvt //
+ // //
+ // Warning: partial implementation; even do_in and do_out only partially meet the //
+ // standard library specifications as the "to" buffer must hold the entire result. //
+ // //
+ //------------------------------------------------------------------------------------//
+
+ class BOOST_FILESYSTEM_DECL windows_file_codecvt
+ : public std::codecvt< wchar_t, char, std::mbstate_t >
+ {
+ public:
+ explicit windows_file_codecvt()
+ : std::codecvt<wchar_t, char, std::mbstate_t>() {}
+ protected:
+
+ virtual bool do_always_noconv() const throw() { return false; }
+
+ // seems safest to assume variable number of characters since we don't
+ // actually know what codepage is active
+ virtual int do_encoding() const throw() { return 0; }
+
+ virtual std::codecvt_base::result do_in(std::mbstate_t& state,
+ const char* from, const char* from_end, const char*& from_next,
+ wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const;
+
+ virtual std::codecvt_base::result do_out(std::mbstate_t & state,
+ const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next,
+ char* to, char* to_end, char*& to_next) const;
+
+ virtual std::codecvt_base::result do_unshift(std::mbstate_t&,
+ char* /*from*/, char* /*to*/, char* & /*next*/) const { return ok; }
+
+ virtual int do_length(std::mbstate_t&,
+ const char* /*from*/, const char* /*from_end*/, std::size_t /*max*/) const { return 0; }
+
+ virtual int do_max_length() const throw () { return 0; }
+ };
+
+#endif // BOOST_FILESYSTEM3_WIN_FILE_CODECVT_HPP