Files
SingularityViewer/indra/llcommon/llfile.h
Aleric Inglewood b424d0232b Make #includes in llcommon header files more complete.
These includes are needed. The current code includes them
in .cpp files *before* including these include files, but
that is not very clean, and not useful.

Actually including what a header file needs makes it more
clear what it drags in, it doesn't drag in more then before.
It also allows to include these headers without having to
includes needed for the included header file in a specific
order, in every .cpp file.
2013-11-05 03:01:46 +01:00

444 lines
14 KiB
C++

/**
* @file llfile.h
* @author Michael Schlachter
* @date 2006-03-23
* @brief Declaration of cross-platform POSIX file buffer and c++
* stream classes.
*
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_LLFILE_H
#define LL_LLFILE_H
#include <fstream>
#include <sys/stat.h>
/**
* This class provides a cross platform interface to the filesystem.
* Attempts to mostly mirror the POSIX style IO functions.
*/
typedef FILE LLFILE;
#if LL_WINDOWS
// windows version of stat function and stat data structure are called _stat
typedef struct _stat llstat;
#else
typedef struct stat llstat;
#include <ext/stdio_filebuf.h>
#include <bits/postypes.h>
#endif
#ifndef S_ISREG
# define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
# define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
#endif
#include "llstring.h" // safe char* -> std::string conversion
class LL_COMMON_API LLFile
{
public:
// All these functions take UTF8 path/filenames.
static LLFILE* fopen(const std::string& filename,const char* accessmode); /* Flawfinder: ignore */
static LLFILE* _fsopen(const std::string& filename,const char* accessmode,int sharingFlag);
static int close(LLFILE * file);
// perms is a permissions mask like 0777 or 0700. In most cases it will
// be overridden by the user's umask. It is ignored on Windows.
static int mkdir(const std::string& filename, int perms = 0700);
static int rmdir(const std::string& filename);
static int remove(const std::string& filename);
static int rename(const std::string& filename,const std::string& newname);
static int stat(const std::string& filename,llstat* file_status);
static bool isdir(const std::string& filename);
static bool isfile(const std::string& filename);
static LLFILE * _Fiopen(const std::string& filename,
std::ios::openmode mode);
static const char * tmpdir();
static std::string strerr(int errn);
static std::string strerr();
};
/**
* @brief Provides a layer of compatibility for C/POSIX.
*
* This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and
* VC's basic_filebuf implementation.
* This file buffer provides extensions for working with standard C FILE*'s
* and POSIX file descriptors for platforms that support this.
*/
namespace
{
#if LL_WINDOWS
//typedef std::filebuf _Myfb;
//Singu note: Wrap around std::filebuf to override the open procedure.
// The client encodes filepaths in UTF-8, however Windows uses UTF-16 encoding natively.
// Need to convert paths to UTF-16 before calling std::filebuf::open.
struct _Myfb : public std::filebuf
{
_Myfb() : std::filebuf() {}
_Myfb(_Filet* file) : std::filebuf(file) {}
_Myt *open(const char *filename, std::ios_base::openmode mode, int prot = (int)std::ios_base::_Openprot)
{
return std::filebuf::open(utf8str_to_utf16str(filename).c_str(),mode,prot);
}
};
#else
typedef __gnu_cxx::stdio_filebuf< char > _Myfb;
typedef std::__c_file _Filet;
#endif /* LL_WINDOWS */
}
class LL_COMMON_API llstdio_filebuf : public _Myfb
{
public:
/**
* deferred initialization / destruction
*/
llstdio_filebuf() : _Myfb() {}
virtual ~llstdio_filebuf() {}
/**
* @param f An open @c FILE*.
* @param mode Same meaning as in a standard filebuf.
* @param size Optimal or preferred size of internal buffer, in chars.
* Defaults to system's @c BUFSIZ.
*
* This constructor associates a file stream buffer with an open
* C @c FILE*. The @c FILE* will not be automatically closed when the
* stdio_filebuf is closed/destroyed.
*/
llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode,
//size_t __size = static_cast<size_t>(BUFSIZ)) :
size_t __size = static_cast<size_t>(1)) :
#if LL_WINDOWS
_Myfb(__f) {}
#else
_Myfb(__f, __mode, __size) {}
#endif
/**
* @brief Opens an external file.
* @param s The name of the file.
* @param mode The open mode flags.
* @return @c this on success, NULL on failure
*
* If a file is already open, this function immediately fails.
* Otherwise it tries to open the file named @a s using the flags
* given in @a mode.
*/
//llstdio_filebuf* open(const char *_Filename,
// std::ios_base::openmode _Mode);
/**
* @param fd An open file descriptor.
* @param mode Same meaning as in a standard filebuf.
* @param size Optimal or preferred size of internal buffer, in chars.
*
* This constructor associates a file stream buffer with an open
* POSIX file descriptor. The file descriptor will be automatically
* closed when the stdio_filebuf is closed/destroyed.
*/
#if !LL_WINDOWS
llstdio_filebuf(int __fd, std::ios_base::openmode __mode,
//size_t __size = static_cast<size_t>(BUFSIZ)) :
size_t __size = static_cast<size_t>(1)) :
_Myfb(__fd, __mode, __size) {}
#endif
// *TODO: Seek the underlying c stream for better cross-platform compatibility?
#if !LL_WINDOWS
protected:
/** underflow() and uflow() functions are called to get the next
* character from the real input source when the buffer is empty.
* Buffered input uses underflow()
*/
/*virtual*/ int_type underflow();
/* Convert internal byte sequence to external, char-based
* sequence via codecvt.
*/
bool _convert_to_external(char_type*, std::streamsize);
/** The overflow() function is called to transfer characters to the
* real output destination when the buffer is full. A call to
* overflow(c) outputs the contents of the buffer plus the
* character c.
* Consume some sequence of the characters in the pending sequence.
*/
/*virtual*/ int_type overflow(int_type __c = traits_type::eof());
/** sync() flushes the underlying @c FILE* stream.
*/
/*virtual*/ int sync();
std::streamsize xsgetn(char_type*, std::streamsize);
std::streamsize xsputn(char_type const*, std::streamsize);
#endif
};
/**
* @brief Controlling input for files.
*
* This class supports reading from named files, using the inherited
* functions from std::basic_istream. To control the associated
* sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
* which allows construction using a pre-exisintg file stream buffer.
* We refer to this std::basic_filebuf (or derivative) as @c sb.
*/
class LL_COMMON_API llifstream : public std::istream
{
// input stream associated with a C stream
public:
// Constructors:
/**
* @brief Default constructor.
*
* Initializes @c sb using its default constructor, and passes
* @c &sb to the base class initializer. Does not open any files
* (you haven't given it a filename to open).
*/
llifstream();
/**
* @brief Create an input file stream.
* @param Filename String specifying the filename.
* @param Mode Open file in specified mode (see std::ios_base).
*
* @c ios_base::in is automatically included in @a mode.
*/
explicit llifstream(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::in);
explicit llifstream(const char* _Filename,
ios_base::openmode _Mode = ios_base::in);
/**
* @brief Create a stream using an open c file stream.
* @param File An open @c FILE*.
@param Mode Same meaning as in a standard filebuf.
@param Size Optimal or preferred size of internal buffer, in chars.
Defaults to system's @c BUFSIZ.
*/
explicit llifstream(_Filet *_File,
ios_base::openmode _Mode = ios_base::in,
//size_t _Size = static_cast<size_t>(BUFSIZ));
size_t _Size = static_cast<size_t>(1));
/**
* @brief Create a stream using an open file descriptor.
* @param fd An open file descriptor.
@param Mode Same meaning as in a standard filebuf.
@param Size Optimal or preferred size of internal buffer, in chars.
Defaults to system's @c BUFSIZ.
*/
#if !LL_WINDOWS
explicit llifstream(int __fd,
ios_base::openmode _Mode = ios_base::in,
//size_t _Size = static_cast<size_t>(BUFSIZ));
size_t _Size = static_cast<size_t>(1));
#endif
/**
* @brief The destructor does nothing.
*
* The file is closed by the filebuf object, not the formatting
* stream.
*/
virtual ~llifstream() {}
// Members:
/**
* @brief Accessing the underlying buffer.
* @return The current basic_filebuf buffer.
*
* This hides both signatures of std::basic_ios::rdbuf().
*/
llstdio_filebuf* rdbuf() const
{ return const_cast<llstdio_filebuf*>(&_M_filebuf); }
/**
* @brief Wrapper to test for an open file.
* @return @c rdbuf()->is_open()
*/
bool is_open() const;
/**
* @brief Opens an external file.
* @param Filename The name of the file.
* @param Node The open mode flags.
*
* Calls @c llstdio_filebuf::open(s,mode|in). If that function
* fails, @c failbit is set in the stream's error state.
*/
void open(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::in)
{ open(_Filename.c_str(), _Mode); }
void open(const char* _Filename,
ios_base::openmode _Mode = ios_base::in);
/**
* @brief Close the file.
*
* Calls @c llstdio_filebuf::close(). If that function
* fails, @c failbit is set in the stream's error state.
*/
void close();
private:
llstdio_filebuf _M_filebuf;
};
/**
* @brief Controlling output for files.
*
* This class supports writing to named files, using the inherited
* functions from std::basic_ostream. To control the associated
* sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
* which allows construction using a pre-exisintg file stream buffer.
* We refer to this std::basic_filebuf (or derivative) as @c sb.
*/
class LL_COMMON_API llofstream : public std::ostream
{
public:
// Constructors:
/**
* @brief Default constructor.
*
* Initializes @c sb using its default constructor, and passes
* @c &sb to the base class initializer. Does not open any files
* (you haven't given it a filename to open).
*/
llofstream();
/**
* @brief Create an output file stream.
* @param Filename String specifying the filename.
* @param Mode Open file in specified mode (see std::ios_base).
*
* @c ios_base::out|ios_base::trunc is automatically included in
* @a mode.
*/
explicit llofstream(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
explicit llofstream(const char* _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
/**
* @brief Create a stream using an open c file stream.
* @param File An open @c FILE*.
@param Mode Same meaning as in a standard filebuf.
@param Size Optimal or preferred size of internal buffer, in chars.
Defaults to system's @c BUFSIZ.
*/
explicit llofstream(_Filet *_File,
ios_base::openmode _Mode = ios_base::out,
//size_t _Size = static_cast<size_t>(BUFSIZ));
size_t _Size = static_cast<size_t>(1));
/**
* @brief Create a stream using an open file descriptor.
* @param fd An open file descriptor.
@param Mode Same meaning as in a standard filebuf.
@param Size Optimal or preferred size of internal buffer, in chars.
Defaults to system's @c BUFSIZ.
*/
#if !LL_WINDOWS
explicit llofstream(int __fd,
ios_base::openmode _Mode = ios_base::out,
//size_t _Size = static_cast<size_t>(BUFSIZ));
size_t _Size = static_cast<size_t>(1));
#endif
/**
* @brief The destructor does nothing.
*
* The file is closed by the filebuf object, not the formatting
* stream.
*/
virtual ~llofstream() {}
// Members:
/**
* @brief Accessing the underlying buffer.
* @return The current basic_filebuf buffer.
*
* This hides both signatures of std::basic_ios::rdbuf().
*/
llstdio_filebuf* rdbuf() const
{ return const_cast<llstdio_filebuf*>(&_M_filebuf); }
/**
* @brief Wrapper to test for an open file.
* @return @c rdbuf()->is_open()
*/
bool is_open() const;
/**
* @brief Opens an external file.
* @param Filename The name of the file.
* @param Node The open mode flags.
*
* Calls @c llstdio_filebuf::open(s,mode|out). If that function
* fails, @c failbit is set in the stream's error state.
*/
void open(const std::string& _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc)
{ open(_Filename.c_str(), _Mode); }
void open(const char* _Filename,
ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
/**
* @brief Close the file.
*
* Calls @c llstdio_filebuf::close(). If that function
* fails, @c failbit is set in the stream's error state.
*/
void close();
private:
llstdio_filebuf _M_filebuf;
};
/**
* @breif filesize helpers.
*
* The file size helpers are not considered particularly efficient,
* and should only be used for config files and the like -- not in a
* loop.
*/
std::streamsize LL_COMMON_API llifstream_size(llifstream& fstr);
std::streamsize LL_COMMON_API llofstream_size(llofstream& fstr);
#endif // not LL_LLFILE_H