Commit 62b9eb5b authored by Kitware Robot's avatar Kitware Robot Committed by Brad King
Browse files

KWSys 2016-11-03 (37306a1c)

Code extracted from:

    http://public.kitware.com/KWSys.git

at commit 37306a1c73e991e239f32bfc8eda98ba2d1c149a (master).

Upstream Shortlog
-----------------

Ben Boeckel (1):
      6d23dd7e SystemTools: add a PathExists method

Brad King (13):
      e43689db SystemTools: Factor out environment storage class
      2aa7dd82 SystemTools: Do not free buffer passed to putenv("A=") on Windows
      560bcdbb SystemTools: Factor out common `const char* GetEnv()` private implementation
      8e643b9b SystemTools: Fix crash in GetShortPath
      e736efa1 ConsoleBuf: Always compile test source for host Windows version
      0504dcaf SystemTools: Fix path comparison in test case
      c4049689 SystemTools: Teach GetActualCaseForPath to convert as much as possible
      66cd1138 ConsoleBuf: Avoid unnecessary initializations in test code
      4e6c9410 ConsoleBuf: Remove extra flush operations from test code
      80f820fc ConsoleBuf: Avoid use of __FUNCTION__ in tests
      6cfcbede SystemTools: Include strings.h on MinGW for strcasecmp
      dfe9b386 SystemTools: Re-implement Strucmp
      37306a1c FStream: Quiet unused argument warning

Dāvis Mosāns (15):
      19c31914 SystemTools: Abstract environment storage character type
      61301786 SystemTools: Tweak GetEnv/PutEnv implementation layout
      85920d53 SystemTools: Teach GetEnv/PutEnv to use correct encoding on Windows
      f396bf43 SystemTools: Add HasEnv function
      19732229 SystemTools: User better GetEnv and HasEnv signatures
      d2cdfc6d FStream: Use common base for basic_ifstream and basic_ofstream
      9d1dbd95 FStream: Add MinGW support
      669e3a06 ConsoleBuf: Use a custom std::streambuf for console output on Windows
      f53440fe ConsoleBuf: Improve test error messages
      fd9e86e8 ConsoleBuf: Use two separate events for test sync
      fb8530ed ConsoleBuf: Make test more reliable
      c49ddccb ConsoleBuf: Fix test registry restoration
      10e3f947 ConsoleBuf: Fix test to compare all bytes of wide character strings
      3f69ac40 ConsoleBuf: Output console and test buffers on test failure
      b630d2f5 ConsoleBuf: Check for actual console with GetConsoleMode

James Johnston (1):
      1c147abb Directory: Use Windows API wherever possible and port to Embarcadero

Patrick Welche (3):
      8a989b44 SystemInformation: Treat BSDs more uniformly
      2ce319a6 SystemInformation: Treat Solaris the same as Linux
      3f55579d SystemTools: Fix FileExists for some SCO OpenServer file permissions
parent 2c4e9fa1
......@@ -123,6 +123,7 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
SET(KWSYS_USE_FStream 1)
SET(KWSYS_USE_String 1)
SET(KWSYS_USE_SystemInformation 1)
SET(KWSYS_USE_ConsoleBuf 1)
ENDIF()
# Enforce component dependencies.
......@@ -154,6 +155,9 @@ ENDIF()
IF(KWSYS_USE_FStream)
SET(KWSYS_USE_Encoding 1)
ENDIF()
IF(KWSYS_USE_ConsoleBuf)
SET(KWSYS_USE_Encoding 1)
ENDIF()
# Setup the large file support default.
IF(KWSYS_LFS_DISABLE)
......@@ -632,6 +636,11 @@ IF(KWSYS_USE_SystemInformation)
ENDIF()
ENDIF()
IF(KWSYS_USE_FStream)
KWSYS_PLATFORM_CXX_TEST(KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H
"Checking whether <ext/stdio_filebuf.h> is available" DIRECT)
ENDIF()
#-----------------------------------------------------------------------------
# Choose a directory for the generated headers.
IF(NOT KWSYS_HEADER_ROOT)
......@@ -668,7 +677,7 @@ SET(KWSYS_HXX_FILES Configure String
# Add selected C++ classes.
SET(cppclasses
Directory DynamicLoader Encoding Glob RegularExpression SystemTools
CommandLineArguments IOStream FStream SystemInformation
CommandLineArguments IOStream FStream SystemInformation ConsoleBuf
)
FOREACH(cpp ${cppclasses})
IF(KWSYS_USE_${cpp})
......@@ -921,6 +930,20 @@ IF(KWSYS_STANDALONE OR CMake_SOURCE_DIR)
testFStream
)
ENDIF()
IF(KWSYS_USE_ConsoleBuf)
ADD_EXECUTABLE(testConsoleBufChild testConsoleBufChild.cxx)
SET_PROPERTY(TARGET testConsoleBufChild PROPERTY LABELS ${KWSYS_LABELS_EXE})
TARGET_LINK_LIBRARIES(testConsoleBufChild ${KWSYS_NAMESPACE})
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS}
testConsoleBuf
)
IF("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC" AND
NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "19.0")
set_property(SOURCE testConsoleBuf.cxx testConsoleBufChild.cxx PROPERTY COMPILE_FLAGS /utf-8)
ENDIF()
SET_PROPERTY(SOURCE testConsoleBuf.cxx APPEND PROPERTY COMPILE_DEFINITIONS
KWSYS_ENCODING_DEFAULT_CODEPAGE=${KWSYS_ENCODING_DEFAULT_CODEPAGE})
ENDIF()
IF(KWSYS_USE_SystemInformation)
SET(KWSYS_CXX_TESTS ${KWSYS_CXX_TESTS} testSystemInformation)
ENDIF()
......
......@@ -17,6 +17,8 @@
/* Whether wstring is available. */
#define @KWSYS_NAMESPACE@_STL_HAS_WSTRING @KWSYS_STL_HAS_WSTRING@
/* Whether <ext/stdio_filebuf.h> is available. */
#define @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H @KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H@
/* If building a C++ file in kwsys itself, give the source file
access to the macros without a configured namespace. */
......@@ -24,8 +26,9 @@
# if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
# define kwsys @KWSYS_NAMESPACE@
# endif
# define KWSYS_NAME_IS_KWSYS @KWSYS_NAMESPACE@_NAME_IS_KWSYS
# define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING
# define KWSYS_NAME_IS_KWSYS @KWSYS_NAMESPACE@_NAME_IS_KWSYS
# define KWSYS_STL_HAS_WSTRING @KWSYS_NAMESPACE@_STL_HAS_WSTRING
# define KWSYS_CXX_HAS_EXT_STDIO_FILEBUF_H @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
#endif
#endif
/*============================================================================
KWSys - Kitware System Library
Copyright 2000-2016 Kitware, Inc., Insight Software Consortium
Distributed under the OSI-approved BSD License (the "License");
see accompanying file Copyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even the
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the License for more information.
============================================================================*/
#ifndef @KWSYS_NAMESPACE@_ConsoleBuf_hxx
#define @KWSYS_NAMESPACE@_ConsoleBuf_hxx
#include <@KWSYS_NAMESPACE@/Configure.hxx>
#include <@KWSYS_NAMESPACE@/Encoding.hxx>
#include <string>
#include <cstring>
#include <sstream>
#include <streambuf>
#include <iostream>
#include <stdexcept>
#if defined(_WIN32)
# include <windows.h>
# if __cplusplus >= 201103L
# include <system_error>
# endif
#endif
namespace @KWSYS_NAMESPACE@
{
#if defined(_WIN32)
template<class CharT, class Traits = std::char_traits<CharT> >
class @KWSYS_NAMESPACE@_EXPORT BasicConsoleBuf :
public std::basic_streambuf<CharT, Traits> {
public:
typedef typename Traits::int_type int_type;
typedef typename Traits::char_type char_type;
class Manager {
public:
Manager(std::basic_ios<CharT, Traits> &ios, const bool err = false)
: m_consolebuf(0)
{
m_ios = &ios;
try {
m_consolebuf = new BasicConsoleBuf<CharT, Traits>(err);
m_streambuf = m_ios->rdbuf(m_consolebuf);
} catch (const std::runtime_error& ex) {
std::cerr << "Failed to create ConsoleBuf!" << std::endl
<< ex.what() << std::endl;
};
}
~Manager()
{
if (m_consolebuf) {
delete m_consolebuf;
m_ios->rdbuf(m_streambuf);
}
}
private:
std::basic_ios<CharT, Traits> *m_ios;
std::basic_streambuf<CharT, Traits> *m_streambuf;
BasicConsoleBuf<CharT, Traits> *m_consolebuf;
};
BasicConsoleBuf(const bool err = false) :
flush_on_newline(true),
input_pipe_codepage(0),
output_pipe_codepage(0),
input_file_codepage(CP_UTF8),
output_file_codepage(CP_UTF8),
m_consolesCodepage(0)
{
m_hInput = ::GetStdHandle(STD_INPUT_HANDLE);
checkHandle(true, "STD_INPUT_HANDLE");
if (!setActiveInputCodepage()) {
throw std::runtime_error("setActiveInputCodepage failed!");
}
m_hOutput = err ? ::GetStdHandle(STD_ERROR_HANDLE) :
::GetStdHandle(STD_OUTPUT_HANDLE);
checkHandle(false, err ? "STD_ERROR_HANDLE" : "STD_OUTPUT_HANDLE");
if (!setActiveOutputCodepage()) {
throw std::runtime_error("setActiveOutputCodepage failed!");
}
_setg();
_setp();
}
~BasicConsoleBuf() throw()
{
sync();
}
bool activateCodepageChange()
{
return setActiveInputCodepage() && setActiveOutputCodepage();
}
protected:
virtual int sync() {
bool success = true;
if (m_hInput && m_isConsoleInput &&
::FlushConsoleInputBuffer(m_hInput) == 0) {
success = false;
}
if (m_hOutput && !m_obuffer.empty()) {
const std::wstring wbuffer = getBuffer(m_obuffer);
if (m_isConsoleOutput) {
DWORD charsWritten;
success = ::WriteConsoleW(m_hOutput, wbuffer.c_str(),
(DWORD)wbuffer.size(), &charsWritten,
NULL) == 0 ? false : true;
} else {
DWORD bytesWritten;
std::string buffer;
success = encodeOutputBuffer(wbuffer, buffer);
if (success) {
success = ::WriteFile(m_hOutput, buffer.c_str(),
(DWORD)buffer.size(), &bytesWritten,
NULL) == 0 ? false : true;
}
}
}
m_ibuffer.clear();
m_obuffer.clear();
_setg();
_setp();
return success ? 0 : -1;
}
virtual int_type underflow() {
if (this->gptr() >= this->egptr()) {
if (!m_hInput) {
_setg(true);
return Traits::eof();
}
if (m_isConsoleInput) {
wchar_t wbuffer[128];
DWORD charsRead;
if (::ReadConsoleW(m_hInput, wbuffer, (sizeof(wbuffer) / sizeof(wbuffer[0])) - 1,
&charsRead, NULL) == 0 || charsRead == 0) {
_setg(true);
return Traits::eof();
}
wbuffer[charsRead] = L'\0';
setBuffer(wbuffer, m_ibuffer);
} else {
std::wstring totalBuffer;
std::wstring wbuffer;
char buffer[128];
DWORD bytesRead;
while (::ReadFile(m_hInput, buffer, (sizeof(buffer) / sizeof(buffer[0])) - 1,
&bytesRead, NULL) == 0) {
if (::GetLastError() == ERROR_MORE_DATA) {
buffer[bytesRead] = '\0';
if (decodeInputBuffer(buffer, wbuffer)) {
totalBuffer += wbuffer;
continue;
}
}
_setg(true);
return Traits::eof();
}
buffer[bytesRead] = '\0';
if (!decodeInputBuffer(buffer, wbuffer)) {
_setg(true);
return Traits::eof();
}
totalBuffer += wbuffer;
setBuffer(totalBuffer, m_ibuffer);
}
_setg();
}
return Traits::to_int_type(*this->gptr());
}
virtual int_type overflow(int_type ch = Traits::eof()) {
if (!Traits::eq_int_type(ch, Traits::eof())) {
char_type chr = Traits::to_char_type(ch);
m_obuffer += chr;
if ((flush_on_newline && Traits::eq(chr, '\n')) ||
Traits::eq_int_type(ch, 0x00)) {
sync();
}
return ch;
}
sync();
return Traits::eof();
}
public:
bool flush_on_newline;
UINT input_pipe_codepage;
UINT output_pipe_codepage;
UINT input_file_codepage;
UINT output_file_codepage;
private:
HANDLE m_hInput;
HANDLE m_hOutput;
std::basic_string<char_type> m_ibuffer;
std::basic_string<char_type> m_obuffer;
bool m_isConsoleInput;
bool m_isConsoleOutput;
UINT m_activeInputCodepage;
UINT m_activeOutputCodepage;
UINT m_consolesCodepage;
void checkHandle(bool input, std::string handleName) {
if ((input && m_hInput == INVALID_HANDLE_VALUE) ||
(!input && m_hOutput == INVALID_HANDLE_VALUE)) {
std::string errmsg = "GetStdHandle(" + handleName +
") returned INVALID_HANDLE_VALUE";
#if __cplusplus >= 201103L
throw std::system_error(::GetLastError(),
std::system_category(), errmsg);
#else
throw std::runtime_error(errmsg);
#endif
}
}
UINT getConsolesCodepage() {
if (!m_consolesCodepage) {
m_consolesCodepage = GetConsoleCP();
if (!m_consolesCodepage) {
m_consolesCodepage = GetACP();
}
}
return m_consolesCodepage;
}
bool setActiveInputCodepage() {
m_isConsoleInput = false;
switch (GetFileType(m_hInput)) {
case FILE_TYPE_DISK:
m_activeInputCodepage = input_file_codepage;
break;
case FILE_TYPE_CHAR:
// Check for actual console.
DWORD consoleMode;
m_isConsoleInput = GetConsoleMode(m_hInput, &consoleMode) == 0 ? false : true;
if (m_isConsoleInput) {
break;
}
case FILE_TYPE_PIPE:
m_activeInputCodepage = input_pipe_codepage;
break;
default:
return false;
}
if (!m_isConsoleInput && m_activeInputCodepage == 0) {
m_activeInputCodepage = getConsolesCodepage();
}
return true;
}
bool setActiveOutputCodepage() {
m_isConsoleOutput = false;
switch (GetFileType(m_hOutput)) {
case FILE_TYPE_DISK:
m_activeOutputCodepage = output_file_codepage;
break;
case FILE_TYPE_CHAR:
// Check for actual console.
DWORD consoleMode;
m_isConsoleOutput = GetConsoleMode(m_hOutput, &consoleMode) == 0 ? false : true;
if (m_isConsoleOutput) {
break;
}
case FILE_TYPE_PIPE:
m_activeOutputCodepage = output_pipe_codepage;
break;
default:
return false;
}
if (!m_isConsoleOutput && m_activeOutputCodepage == 0) {
m_activeOutputCodepage = getConsolesCodepage();
}
return true;
}
void _setg(bool empty = false) {
if (!empty) {
this->setg((char_type *)m_ibuffer.data(),
(char_type *)m_ibuffer.data(),
(char_type *)m_ibuffer.data() + m_ibuffer.size());
} else {
this->setg((char_type *)m_ibuffer.data(),
(char_type *)m_ibuffer.data() + m_ibuffer.size(),
(char_type *)m_ibuffer.data() + m_ibuffer.size());
}
}
void _setp() {
this->setp((char_type *)m_obuffer.data(),
(char_type *)m_obuffer.data() + m_obuffer.size());
}
bool encodeOutputBuffer(const std::wstring wbuffer,
std::string &buffer) {
const int length = WideCharToMultiByte(m_activeOutputCodepage, 0,
wbuffer.c_str(),
(int)wbuffer.size(), NULL, 0,
NULL, NULL);
char *buf = new char[length + 1];
const bool success = WideCharToMultiByte(m_activeOutputCodepage, 0,
wbuffer.c_str(),
(int)wbuffer.size(), buf,
length, NULL, NULL) > 0
? true : false;
buf[length] = '\0';
buffer = buf;
delete[] buf;
return success;
}
bool decodeInputBuffer(const char *buffer, std::wstring &wbuffer) {
int actualCodepage = m_activeInputCodepage;
const char BOM_UTF8[] = { char(0xEF), char(0xBB), char(0xBF) };
if (std::memcmp(buffer, BOM_UTF8, sizeof(BOM_UTF8)) == 0) {
// PowerShell uses UTF-8 with BOM for pipes
actualCodepage = CP_UTF8;
buffer += sizeof(BOM_UTF8);
}
const int wlength = MultiByteToWideChar(actualCodepage, 0, buffer,
-1, NULL, 0);
wchar_t *wbuf = new wchar_t[wlength];
const bool success = MultiByteToWideChar(actualCodepage, 0, buffer,
-1, wbuf, wlength) > 0
? true : false;
wbuffer = wbuf;
delete[] wbuf;
return success;
}
std::wstring getBuffer(const std::basic_string<char> buffer) {
return Encoding::ToWide(buffer);
}
std::wstring getBuffer(const std::basic_string<wchar_t> buffer) {
return buffer;
}
void setBuffer(const std::wstring wbuffer,
std::basic_string<char> &target) {
target = Encoding::ToNarrow(wbuffer);
}
void setBuffer(const std::wstring wbuffer,
std::basic_string<wchar_t> &target) {
target = wbuffer;
}
}; // BasicConsoleBuf class
typedef BasicConsoleBuf<char> ConsoleBuf;
typedef BasicConsoleBuf<wchar_t> WConsoleBuf;
#endif
} // KWSYS_NAMESPACE
#endif
......@@ -84,9 +84,9 @@ void Directory::Clear()
} // namespace KWSYS_NAMESPACE
// First microsoft compilers
// First Windows platforms
#if defined(_MSC_VER) || defined(__WATCOMC__)
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#include <io.h>
#include <ctype.h>
......@@ -97,15 +97,25 @@ void Directory::Clear()
#include <sys/stat.h>
#include <sys/types.h>
// Wide function names can vary depending on compiler:
#ifdef __BORLANDC__
# define _wfindfirst_func __wfindfirst
# define _wfindnext_func __wfindnext
#else
# define _wfindfirst_func _wfindfirst
# define _wfindnext_func _wfindnext
#endif
namespace KWSYS_NAMESPACE
{
bool Directory::Load(const std::string& name)
{
this->Clear();
#if _MSC_VER < 1300
#if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
// Older Visual C++ and Embarcadero compilers.
long srchHandle;
#else
#else // Newer Visual C++
intptr_t srchHandle;
#endif
char* buf;
......@@ -132,7 +142,7 @@ bool Directory::Load(const std::string& name)
struct _wfinddata_t data; // data of current file
// Now put them into the file array
srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
srchHandle = _wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
delete [] buf;
if ( srchHandle == -1 )
......@@ -145,16 +155,17 @@ bool Directory::Load(const std::string& name)
{
this->Internal->Files.push_back(Encoding::ToNarrow(data.name));
}
while ( _wfindnext(srchHandle, &data) != -1 );
while ( _wfindnext_func(srchHandle, &data) != -1 );
this->Internal->Path = name;
return _findclose(srchHandle) != -1;
}
unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
{
#if _MSC_VER < 1300
#if (defined(_MSC_VER) && _MSC_VER < 1300) || defined(__BORLANDC__)
// Older Visual C++ and Embarcadero compilers.
long srchHandle;
#else
#else // Newer Visual C++
intptr_t srchHandle;
#endif
char* buf;
......@@ -172,7 +183,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
struct _wfinddata_t data; // data of current file
// Now put them into the file array
srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
srchHandle = _wfindfirst_func((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
delete [] buf;
if ( srchHandle == -1 )
......@@ -186,7 +197,7 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name)
{
count++;
}
while ( _wfindnext(srchHandle, &data) != -1 );
while ( _wfindnext_func(srchHandle, &data) != -1 );
_findclose(srchHandle);
return count;
}
......
......@@ -12,154 +12,250 @@
#ifndef @KWSYS_NAMESPACE@_FStream_hxx
#define @KWSYS_NAMESPACE@_FStream_hxx
#include <@KWSYS_NAMESPACE@/Configure.hxx>
#include <@KWSYS_NAMESPACE@/Encoding.hxx>
#include <fstream>
#if defined(_WIN32)
# if !defined(_MSC_VER) && @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H
# include <ext/stdio_filebuf.h>
# endif
#endif
namespace @KWSYS_NAMESPACE@
{
#if defined(_MSC_VER) && _MSC_VER >= 1400
#if defined(_WIN32) && (defined(_MSC_VER) || @KWSYS_NAMESPACE@_CXX_HAS_EXT_STDIO_FILEBUF_H)
# if defined(_NOEXCEPT)
# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT _NOEXCEPT
# else
# define @KWSYS_NAMESPACE@_FStream_NOEXCEPT
# endif
#if defined(_MSC_VER)
template<typename CharType,typename Traits>
class basic_filebuf : public std::basic_filebuf<CharType,Traits>
{
# if _MSC_VER >= 1400
public:
typedef std::basic_filebuf<CharType,Traits> my_base_type;
basic_filebuf *open(char const *s,std::ios_base::openmode mode)
{
const std::wstring wstr = Encoding::ToWide(s);
return static_cast<basic_filebuf*>(
my_base_type::open(Encoding::ToWide(s).c_str(), mode)
my_base_type::open(wstr.c_str(), mode)
);
}
# endif
};
#else
inline std::wstring getcmode(const std::ios_base::openmode mode) {
std::wstring cmode;
bool plus = false;
if (mode & std::ios_base::app) {
cmode += L"a";
plus = mode & std::ios_base::in ? true : false;
} else if (mode & std::ios_base::trunc ||
(mode & std::ios_base::out && (mode & std::ios_base::in) == 0)) {
cmode += L"w";
plus = mode & std::ios_base::in ? true : false;
} else {
cmode += L"r";
plus = mode & std::ios_base::out ? true : false;
}
if (plus) {
cmode += L"+";
}
if (mode & std::ios_base::binary) {
cmode += L"b";
} else {
cmode += L"t";
}
return cmode;
};
#endif
template<typename CharType,typename Traits = std::char_traits<CharType> >
class basic_ifstream : public std::basic_istream<CharType,Traits>
class basic_efilebuf
{
public:
#if defined(_MSC_VER)
typedef basic_filebuf<CharType,Traits> internal_buffer_type;
#else
typedef __gnu_cxx::stdio_filebuf<CharType,Traits> internal_buffer_type;
#endif
basic_efilebuf() : file_(0)
{
buf_ = 0;
}
bool _open(char const *file_name,std::ios_base::openmode mode)
{
if (is_open() || file_) {
return false;
}
#if defined(_MSC_VER)
const bool success = buf_->open(file_name,mode) != 0;
#else
const std::wstring wstr = Encoding::ToWide(file_name);
bool success = false;
std::wstring cmode = getcmode(mode);
file_ = _wfopen(wstr.c_str(), cmode.c_str());
if (file_) {
if (buf_) {
delete buf_;
}
buf_ = new internal_buffer_type(file_, mode);
success = true;
}
#endif
return success;
}
bool is_open()
{
if (!buf_) {
return false;
}
return buf_->is_open();
}
bool is_open() const
{
if (!buf_) {
return false;
}
return buf_->is_open();
}
bool _close()
{
bool success = false;
if (buf_) {
success = buf_->close() != 0;
#if !defined(_MSC_VER)