mirror of https://github.com/KLayout/klayout.git
Non-Qt implementations of file utils - needs testing.
This commit is contained in:
parent
239b7ca3ff
commit
7fca6f5f31
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tlFileUtils.h"
|
#include "tlFileUtils.h"
|
||||||
|
#include "tlStream.h"
|
||||||
#include "tlLog.h"
|
#include "tlLog.h"
|
||||||
#include "tlInternational.h"
|
#include "tlInternational.h"
|
||||||
|
|
||||||
|
|
@ -28,6 +29,7 @@
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
namespace tl
|
namespace tl
|
||||||
{
|
{
|
||||||
|
|
@ -191,35 +193,140 @@ is_parent_path (const std::string &parent, const std::string &path)
|
||||||
return (is_same_file (parent, tl::combine_path (tl::join (parts, ""), "")));
|
return (is_same_file (parent, tl::combine_path (tl::join (parts, ""), "")));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rm_dir_recursive (const std::string &path)
|
std::vector<std::string> dir_entries (const std::string &s, bool with_files, bool with_dirs, bool without_dotfiles)
|
||||||
{
|
{
|
||||||
#if 0 // @@@
|
std::vector<std::string> ee;
|
||||||
QDir dir (path);
|
|
||||||
|
|
||||||
QStringList entries = dir.entryList (QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
|
#if defined(_WIN32)
|
||||||
for (QStringList::const_iterator e = entries.begin (); e != entries.end (); ++e) {
|
|
||||||
QFileInfo fi (dir.absoluteFilePath (*e));
|
struct _wfinddata_t fileinfo;
|
||||||
if (fi.isDir ()) {
|
|
||||||
if (! rm_dir_recursive (fi.filePath ())) {
|
intptr_t h = _wfindfirst (tl::to_wstring (s + "\\*.*").c_str (), &fileinfo);
|
||||||
return false;
|
if (h != -1) {
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
std::string e = tl::to_string fileinfo.name);
|
||||||
|
if (e.empty () || e == "." || e == "..") {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
} else if (fi.isFile ()) {
|
|
||||||
if (! dir.remove (*e)) {
|
bool is_dir = ((fileinfo.attrib & _A_SUBDIR) != 0);
|
||||||
tl::error << tr ("Unable to remove file: %1").arg (dir.absoluteFilePath (*e));
|
if ((e[0] != '.' || !without_dotfiles) && ((is_dir && with_dirs) || (!is_dir && with_files))) {
|
||||||
|
ee.push_back (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (_wfindnext (h, &fileinfo) == 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_wfindclose (h);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
DIR *h = opendir (tl::to_local (s).c_str ());
|
||||||
|
if (h) {
|
||||||
|
|
||||||
|
struct dirent *d;
|
||||||
|
while ((d = readdir (h)) != NULL) {
|
||||||
|
|
||||||
|
std::string e = tl::to_string_from_local (d->d_name);
|
||||||
|
if (e.empty () || e == "." || e == "..") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_dir = (d->d_type == DT_DIR);
|
||||||
|
if ((e[0] != '.' || !without_dotfiles) && ((is_dir && with_dirs) || (!is_dir && with_files))) {
|
||||||
|
ee.push_back (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir (h);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ee;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mkdir (const std::string &path)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
return _wunlink (tl::to_wstring (path).c_str ()) == 0;
|
||||||
|
#else
|
||||||
|
return unlink (tl::to_local (path).c_str ()) == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool mkpath (const std::string &p)
|
||||||
|
{
|
||||||
|
std::vector<std::string> parts = split_path (absolute_file_path (p));
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
std::string front;
|
||||||
|
if (! parts.empty () && is_drive (parts.front ())) {
|
||||||
|
front = parts.front ();
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < parts.size ()) {
|
||||||
|
front += parts[i++];
|
||||||
|
if (! file_exists (front)) {
|
||||||
|
if (! mkdir (front)) {
|
||||||
|
tl::error << tr ("Unable to create directory: ") << front;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString name = dir.dirName ();
|
return true;
|
||||||
if (dir.cdUp ()) {
|
}
|
||||||
if (! dir.rmdir (name)) {
|
|
||||||
tl::error << tr ("Unable to remove directory: %1").arg (dir.absoluteFilePath (name));
|
bool rm_file (const std::string &path)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
return _wunlink (tl::to_wstring (path).c_str ()) == 0;
|
||||||
|
#else
|
||||||
|
return unlink (tl::to_local (path).c_str ()) == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rm_dir (const std::string &path)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
return _wrmdir (tl::to_wstring (path).c_str ()) == 0;
|
||||||
|
#else
|
||||||
|
return rmdir (tl::to_local (path).c_str ()) == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rm_dir_recursive (const std::string &p)
|
||||||
|
{
|
||||||
|
std::vector<std::string> entries;
|
||||||
|
std::string path = tl::absolute_file_path (p);
|
||||||
|
|
||||||
|
entries = dir_entries (path, false /*without_files*/, true /*with_dirs*/);
|
||||||
|
for (std::vector<std::string>::const_iterator e = entries.begin (); e != entries.end (); ++e) {
|
||||||
|
if (! rm_dir_recursive (tl::combine_path (path, *e))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
entries = dir_entries (path, true /*with_files*/, false /*without_dirs*/);
|
||||||
|
for (std::vector<std::string>::const_iterator e = entries.begin (); e != entries.end (); ++e) {
|
||||||
|
std::string tc = tl::combine_path (path, *e);
|
||||||
|
if (! rm_file (tc)) {
|
||||||
|
tl::error << tr ("Unable to remove file: ") << tc;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! rm_dir (path)) {
|
||||||
|
tl::error << tr ("Unable to remove directory: ") << path;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -227,72 +334,47 @@ bool rm_dir_recursive (const std::string &path)
|
||||||
bool
|
bool
|
||||||
cp_dir_recursive (const std::string &source, const std::string &target)
|
cp_dir_recursive (const std::string &source, const std::string &target)
|
||||||
{
|
{
|
||||||
#if 0 // @@@
|
std::vector<std::string> entries;
|
||||||
QDir dir (source);
|
std::string path = tl::absolute_file_path (source);
|
||||||
QDir dir_target (target);
|
std::string path_to = tl::absolute_file_path (target);
|
||||||
|
|
||||||
QStringList entries = dir.entryList (QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
|
entries = dir_entries (path, false /*without_files*/, true /*with_dirs*/);
|
||||||
for (QStringList::const_iterator e = entries.begin (); e != entries.end (); ++e) {
|
for (std::vector<std::string>::const_iterator e = entries.begin (); e != entries.end (); ++e) {
|
||||||
|
std::string tc = tl::combine_path (path_to, *e);
|
||||||
|
if (! mkpath (tc)) {
|
||||||
|
tl::error << tr ("Unable to create target directory: ") << tc;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (! cp_dir_recursive (tl::combine_path (path, *e), tc)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QFileInfo fi (dir.absoluteFilePath (*e));
|
entries = dir_entries (path, true /*with_files*/, false /*without_dirs*/);
|
||||||
QFileInfo fi_target (dir_target.absoluteFilePath (*e));
|
for (std::vector<std::string>::const_iterator e = entries.begin (); e != entries.end (); ++e) {
|
||||||
|
|
||||||
if (fi.isDir ()) {
|
|
||||||
|
|
||||||
// Copy subdirectory
|
|
||||||
if (! fi_target.exists ()) {
|
|
||||||
if (! dir_target.mkdir (*e)) {
|
|
||||||
tl::error << tr ("Unable to create target directory: %1").arg (dir_target.absoluteFilePath (*e));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (! fi_target.isDir ()) {
|
|
||||||
tl::error << tr ("Unable to create target directory (is a file already): %1").arg (dir_target.absoluteFilePath (*e));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (! cp_dir_recursive (fi.filePath (), fi_target.filePath ())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: leave symlinks symlinks? How to copy symlinks with Qt?
|
// TODO: leave symlinks symlinks? How to copy symlinks with Qt?
|
||||||
} else if (fi.isFile ()) {
|
|
||||||
|
|
||||||
QFile file (fi.filePath ());
|
// copy the files
|
||||||
QFile file_target (fi_target.filePath ());
|
try {
|
||||||
|
|
||||||
if (! file.open (QIODevice::ReadOnly)) {
|
tl::OutputFile os_file (tl::combine_path (path_to, *e));
|
||||||
tl::error << tr ("Unable to open source file for reading: %1").arg (fi.filePath ());
|
tl::OutputStream os (os_file);
|
||||||
return false;
|
tl::InputFile is_file (tl::combine_path (path, *e));
|
||||||
}
|
tl::InputStream is (is_file);
|
||||||
if (! file_target.open (QIODevice::WriteOnly)) {
|
is.copy_to (os);
|
||||||
tl::error << tr ("Unable to open target file for writing: %1").arg (fi_target.filePath ());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t chunk_size = 64 * 1024;
|
|
||||||
|
|
||||||
while (! file.atEnd ()) {
|
|
||||||
QByteArray data = file.read (chunk_size);
|
|
||||||
file_target.write (data);
|
|
||||||
}
|
|
||||||
|
|
||||||
file.close ();
|
|
||||||
file_target.close ();
|
|
||||||
|
|
||||||
|
} catch (tl::Exception &ex) {
|
||||||
|
tl::error << tr ("Unable to copy file ") << tl::combine_path (path_to, *e) << tr (" to ") << tl::combine_path (path, *e)
|
||||||
|
<< tr ("(Error ") << ex.msg () << ")";
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mkpath (const std::string &path)
|
|
||||||
{
|
|
||||||
// @@@
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string absolute_path (const std::string &s)
|
std::string absolute_path (const std::string &s)
|
||||||
{
|
{
|
||||||
std::vector<std::string> parts = split_path (absolute_file_path (s));
|
std::vector<std::string> parts = split_path (absolute_file_path (s));
|
||||||
|
|
@ -305,39 +387,58 @@ std::string absolute_path (const std::string &s)
|
||||||
|
|
||||||
std::string current_dir ()
|
std::string current_dir ()
|
||||||
{
|
{
|
||||||
char *cwd;
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
cwd = _getcwd (NULL, 0);
|
|
||||||
#else
|
|
||||||
cwd = getcwd (NULL, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
wchar_t *cwd = _wgetcwd (NULL, 0);
|
||||||
if (cwd == NULL) {
|
if (cwd == NULL) {
|
||||||
return std::string ();
|
return std::string ();
|
||||||
} else {
|
} else {
|
||||||
std::string cwds (cwd);
|
std::string cwds (tl::to_string (std::wstring (cwd)));
|
||||||
free (cwd);
|
free (cwd);
|
||||||
return cwds;
|
return cwds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
char *cwd = getcwd (NULL, 0);
|
||||||
|
if (cwd == NULL) {
|
||||||
|
return std::string ();
|
||||||
|
} else {
|
||||||
|
std::string cwds (tl::to_string_from_local (cwd));
|
||||||
|
free (cwd);
|
||||||
|
return cwds;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static std::pair<std::string, bool> absolute_path_of_existing (const std::string &s)
|
static std::pair<std::string, bool> absolute_path_of_existing (const std::string &s)
|
||||||
{
|
{
|
||||||
char *fp;
|
|
||||||
#if defined (_WIN32)
|
#if defined (_WIN32)
|
||||||
fp = _fullpath (NULL, s.c_str (), 0);
|
|
||||||
#else
|
|
||||||
fp = realpath (s.c_str (), NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
wchar_t *fp = _wfullpath (NULL, tl::to_wstring (s).c_str (), 0);
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
return std::make_pair (std::string (), false);
|
return std::make_pair (std::string (), false);
|
||||||
} else {
|
} else {
|
||||||
std::string fps (fp);
|
std::string fps (tl::to_string (std::wstring (fp)));
|
||||||
free (fp);
|
free (fp);
|
||||||
return std::make_pair (fps, true);
|
return std::make_pair (fps, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
char *fp;
|
||||||
|
fp = realpath (tl::to_local (s).c_str (), NULL);
|
||||||
|
if (fp == NULL) {
|
||||||
|
return std::make_pair (std::string (), false);
|
||||||
|
} else {
|
||||||
|
std::string fps (tl::to_string_from_local (fp));
|
||||||
|
free (fp);
|
||||||
|
return std::make_pair (fps, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string absolute_file_path (const std::string &s)
|
std::string absolute_file_path (const std::string &s)
|
||||||
|
|
@ -436,16 +537,25 @@ std::string extension (const std::string &s)
|
||||||
return tl::join (fnp, ".");
|
return tl::join (fnp, ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int stat_func (const std::string &s, struct stat &st)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
return _wstat (tl::to_wstring (s).c_str (), &st);
|
||||||
|
#else
|
||||||
|
return stat (tl::to_local (s).c_str (), &st);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool file_exists (const std::string &p)
|
bool file_exists (const std::string &p)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
return stat (p.c_str (), &st) == 0;
|
return stat_func (p, st) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_dir (const std::string &p)
|
bool is_dir (const std::string &p)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat (p.c_str (), &st) != 0) {
|
if (stat_func (p, st) != 0) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
return !S_ISREG (st.st_mode);
|
return !S_ISREG (st.st_mode);
|
||||||
|
|
@ -466,8 +576,8 @@ bool is_same_file (const std::string &a, const std::string &b)
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
|
||||||
HANDLE h1 = ::CreateFile (a.c_str (), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
HANDLE h1 = ::CreateFileW (tl::to_wstring (a).c_str (), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
HANDLE h2 = ::CreateFile (b.c_str (), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
HANDLE h2 = ::CreateFileW (tl::to_wstring (b).c_str (), 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
|
@ -493,10 +603,7 @@ bool is_same_file (const std::string &a, const std::string &b)
|
||||||
#else
|
#else
|
||||||
|
|
||||||
struct stat sta, stb;
|
struct stat sta, stb;
|
||||||
if (stat (a.c_str (), &sta) != 0) {
|
if (stat_func (a, sta) != 0 || stat_func (b, stb) != 0) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (stat (b.c_str (), &stb) != 0) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,25 @@ bool TL_PUBLIC file_exists (const std::string &s);
|
||||||
*/
|
*/
|
||||||
bool TL_PUBLIC is_dir (const std::string &s);
|
bool TL_PUBLIC is_dir (const std::string &s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the directory entries for the given directory
|
||||||
|
* This method will NEVER return the ".." entry.
|
||||||
|
* @param with_files Includes all files
|
||||||
|
* @param with_dirs Include all directories
|
||||||
|
* @param without_dotfiles Exclude all ".*" files
|
||||||
|
*/
|
||||||
|
std::vector<std::string> TL_PUBLIC dir_entries (const std::string &s, bool with_files = true, bool with_dirs = true, bool without_dotfiles = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes the given file and returns true on success
|
||||||
|
*/
|
||||||
|
bool TL_PUBLIC rm_file (const std::string &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Removes the given directory and returns true on success
|
||||||
|
*/
|
||||||
|
bool TL_PUBLIC rm_dir (const std::string &path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns true, if the given path is the same directory of file than the other one
|
* @brief Returns true, if the given path is the same directory of file than the other one
|
||||||
*/
|
*/
|
||||||
|
|
@ -120,7 +139,7 @@ std::string TL_PUBLIC current_dir ();
|
||||||
* added if the path terminates with a separator (like "C:\" or "/home/user/").
|
* added if the path terminates with a separator (like "C:\" or "/home/user/").
|
||||||
* The idea is that the last element is the file name part.
|
* The idea is that the last element is the file name part.
|
||||||
*/
|
*/
|
||||||
static std::vector<std::string> split_path (const std::string &p);
|
std::vector<std::string> split_path (const std::string &p);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,185 +124,6 @@ public:
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// Input file delegate implementations - declaration and implementation
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A zlib input file delegate
|
|
||||||
*
|
|
||||||
* Implements the reader for a zlib stream
|
|
||||||
*/
|
|
||||||
class InputZLibFile
|
|
||||||
: public InputStreamBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Open a file with the given path
|
|
||||||
*
|
|
||||||
* Opening a file is a prerequisite for reading from the
|
|
||||||
* object. open() will throw a FileOpenErrorException if
|
|
||||||
* an error occurs.
|
|
||||||
*
|
|
||||||
* @param path The (relative) path of the file to open
|
|
||||||
*/
|
|
||||||
InputZLibFile (const std::string &path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Close the file
|
|
||||||
*
|
|
||||||
* The destructor will automatically close the file.
|
|
||||||
*/
|
|
||||||
virtual ~InputZLibFile ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read from a file
|
|
||||||
*
|
|
||||||
* Implements the basic read method.
|
|
||||||
* Will throw a ZLibReadErrorException if an error occurs.
|
|
||||||
*/
|
|
||||||
virtual size_t read (char *b, size_t n);
|
|
||||||
|
|
||||||
virtual void reset ();
|
|
||||||
|
|
||||||
virtual void close ();
|
|
||||||
|
|
||||||
virtual std::string source () const
|
|
||||||
{
|
|
||||||
return m_source;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string absolute_path () const;
|
|
||||||
|
|
||||||
virtual std::string filename () const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_source;
|
|
||||||
gzFile m_zs;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A simple input file delegate
|
|
||||||
*
|
|
||||||
* Implements the reader for ordinary files.
|
|
||||||
*/
|
|
||||||
class InputFile
|
|
||||||
: public InputStreamBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Open a file with the given path
|
|
||||||
*
|
|
||||||
* Opening a file is a prerequisite for reading from the
|
|
||||||
* object. open() will throw a FileOpenErrorException if
|
|
||||||
* an error occurs.
|
|
||||||
*
|
|
||||||
* @param path The (relative) path of the file to open
|
|
||||||
* @param read True, if the file should be read, false on write.
|
|
||||||
*/
|
|
||||||
InputFile (const std::string &path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Close the file
|
|
||||||
*
|
|
||||||
* The destructor will automatically close the file.
|
|
||||||
*/
|
|
||||||
virtual ~InputFile ();
|
|
||||||
|
|
||||||
virtual size_t read (char *b, size_t n);
|
|
||||||
|
|
||||||
virtual void reset ();
|
|
||||||
|
|
||||||
virtual void close ();
|
|
||||||
|
|
||||||
virtual std::string source () const
|
|
||||||
{
|
|
||||||
return m_source;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string absolute_path () const;
|
|
||||||
|
|
||||||
virtual std::string filename () const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_source;
|
|
||||||
int m_fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A simple pipe input delegate
|
|
||||||
*
|
|
||||||
* Implements the reader for pipe streams
|
|
||||||
*/
|
|
||||||
class InputPipe
|
|
||||||
: public InputStreamBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Open a stream by connecting with the stdout of a given command
|
|
||||||
*
|
|
||||||
* Opening a pipe is a prerequisite for reading from the
|
|
||||||
* object. open() will throw a FilePOpenErrorException if
|
|
||||||
* an error occurs - commonly if the command cannot be executed.
|
|
||||||
* This implementation is based on popen ().
|
|
||||||
*
|
|
||||||
* @param cmd The command to execute
|
|
||||||
* @param read True, if the file should be read, false on write.
|
|
||||||
*/
|
|
||||||
InputPipe (const std::string &path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Close the pipe
|
|
||||||
*
|
|
||||||
* The destructor will automatically close the pipe.
|
|
||||||
*/
|
|
||||||
virtual ~InputPipe ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Read from the pipe
|
|
||||||
*
|
|
||||||
* Implements the basic read method.
|
|
||||||
* Will throw a FilePReadErrorException if an error occurs.
|
|
||||||
*/
|
|
||||||
virtual size_t read (char *b, size_t n);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Reset to the beginning of the file
|
|
||||||
*/
|
|
||||||
virtual void reset ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Closes the pipe
|
|
||||||
*/
|
|
||||||
virtual void close ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Get the source specification (the file name)
|
|
||||||
*
|
|
||||||
* Returns an empty string if no file name is available.
|
|
||||||
*/
|
|
||||||
virtual std::string source () const
|
|
||||||
{
|
|
||||||
// No source (in the sense of a file name) is available ..
|
|
||||||
return std::string ();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string absolute_path () const
|
|
||||||
{
|
|
||||||
// No source (in the sense of a file name) is available ..
|
|
||||||
return std::string ();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string filename () const
|
|
||||||
{
|
|
||||||
// No source (in the sense of a file name) is available ..
|
|
||||||
return std::string ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
FILE *m_file;
|
|
||||||
std::string m_source;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// InputStream implementation
|
// InputStream implementation
|
||||||
|
|
||||||
|
|
@ -490,8 +311,7 @@ InputStream::read_all ()
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void InputStream::copy_to(tl::OutputStream &os)
|
||||||
InputStream::copy_to (tl::OutputStream &os)
|
|
||||||
{
|
{
|
||||||
const size_t chunk = 65536;
|
const size_t chunk = 65536;
|
||||||
char b [chunk];
|
char b [chunk];
|
||||||
|
|
@ -794,147 +614,6 @@ InputZLibFile::filename () const
|
||||||
return tl::filename (m_source);
|
return tl::filename (m_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
|
||||||
// OutputStreamBase implementations - declarations and implementation
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A zlib output file delegate
|
|
||||||
*
|
|
||||||
* Implements the writer for a zlib stream
|
|
||||||
*/
|
|
||||||
class OutputZLibFile
|
|
||||||
: public OutputStreamBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Open a file with the given path
|
|
||||||
*
|
|
||||||
* Opening a file is a prerequisite for reading from the
|
|
||||||
* object. open() will throw a FileOpenErrorException if
|
|
||||||
* an error occurs.
|
|
||||||
*
|
|
||||||
* @param path The (relative) path of the file to open
|
|
||||||
*/
|
|
||||||
OutputZLibFile (const std::string &path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Close the file
|
|
||||||
*
|
|
||||||
* The destructor will automatically close the file.
|
|
||||||
*/
|
|
||||||
virtual ~OutputZLibFile ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write to a file
|
|
||||||
*
|
|
||||||
* Implements the basic write method.
|
|
||||||
* Will throw a ZLibWriteErrorException if an error occurs.
|
|
||||||
*/
|
|
||||||
virtual void write (const char *b, size_t n);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_source;
|
|
||||||
gzFile m_zs;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A simple output file delegate
|
|
||||||
*
|
|
||||||
* Implements the writer for ordinary files.
|
|
||||||
*/
|
|
||||||
class OutputFile
|
|
||||||
: public OutputStreamBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Open a file with the given path
|
|
||||||
*
|
|
||||||
* Opening a file is a prerequisite for reading from the
|
|
||||||
* object. open() will throw a FileOpenErrorException if
|
|
||||||
* an error occurs.
|
|
||||||
*
|
|
||||||
* @param path The (relative) path of the file to open
|
|
||||||
* @param read True, if the file should be read, false on write.
|
|
||||||
*/
|
|
||||||
OutputFile (const std::string &path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Close the file
|
|
||||||
*
|
|
||||||
* The destructor will automatically close the file.
|
|
||||||
*/
|
|
||||||
virtual ~OutputFile ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Seek to the specified position
|
|
||||||
*
|
|
||||||
* Writing continues at that position after a seek.
|
|
||||||
*/
|
|
||||||
virtual void seek (size_t s);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns a value indicating whether that stream supports seek
|
|
||||||
*/
|
|
||||||
bool supports_seek ()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write to a file
|
|
||||||
*
|
|
||||||
* Implements the basic write method.
|
|
||||||
* Will throw a FileWriteErrorException if an error occurs.
|
|
||||||
*/
|
|
||||||
virtual void write (const char *b, size_t n);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string m_source;
|
|
||||||
int m_fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A simple pipe output delegate
|
|
||||||
*
|
|
||||||
* Implements the writer for pipe streams
|
|
||||||
*/
|
|
||||||
class OutputPipe
|
|
||||||
: public OutputStreamBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Open a stream by connecting with the stdout of a given command
|
|
||||||
*
|
|
||||||
* Opening a pipe is a prerequisite for reading from the
|
|
||||||
* object. open() will throw a FilePOpenErrorException if
|
|
||||||
* an error occurs - commonly if the command cannot be executed.
|
|
||||||
* This implementation is based on popen ().
|
|
||||||
*
|
|
||||||
* @param cmd The command to execute
|
|
||||||
* @param read True, if the file should be read, false on write.
|
|
||||||
*/
|
|
||||||
OutputPipe (const std::string &path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Close the pipe
|
|
||||||
*
|
|
||||||
* The destructor will automatically close the pipe.
|
|
||||||
*/
|
|
||||||
virtual ~OutputPipe ();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Write to a file
|
|
||||||
*
|
|
||||||
* Implements the basic write method.
|
|
||||||
* Will throw a FilePWriteErrorException if an error occurs.
|
|
||||||
*/
|
|
||||||
virtual void write (const char *b, size_t n);
|
|
||||||
|
|
||||||
private:
|
|
||||||
FILE *m_file;
|
|
||||||
std::string m_source;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------
|
// ---------------------------------------------------------------
|
||||||
// OutputStream implementation
|
// OutputStream implementation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,182 @@ private:
|
||||||
size_t m_length, m_pos;
|
size_t m_length, m_pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A zlib input file delegate
|
||||||
|
*
|
||||||
|
* Implements the reader for a zlib stream
|
||||||
|
*/
|
||||||
|
class InputZLibFile
|
||||||
|
: public InputStreamBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Open a file with the given path
|
||||||
|
*
|
||||||
|
* Opening a file is a prerequisite for reading from the
|
||||||
|
* object. open() will throw a FileOpenErrorException if
|
||||||
|
* an error occurs.
|
||||||
|
*
|
||||||
|
* @param path The (relative) path of the file to open
|
||||||
|
*/
|
||||||
|
InputZLibFile (const std::string &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close the file
|
||||||
|
*
|
||||||
|
* The destructor will automatically close the file.
|
||||||
|
*/
|
||||||
|
virtual ~InputZLibFile ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read from a file
|
||||||
|
*
|
||||||
|
* Implements the basic read method.
|
||||||
|
* Will throw a ZLibReadErrorException if an error occurs.
|
||||||
|
*/
|
||||||
|
virtual size_t read (char *b, size_t n);
|
||||||
|
|
||||||
|
virtual void reset ();
|
||||||
|
|
||||||
|
virtual void close ();
|
||||||
|
|
||||||
|
virtual std::string source () const
|
||||||
|
{
|
||||||
|
return m_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string absolute_path () const;
|
||||||
|
|
||||||
|
virtual std::string filename () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_source;
|
||||||
|
gzFile m_zs;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A simple input file delegate
|
||||||
|
*
|
||||||
|
* Implements the reader for ordinary files.
|
||||||
|
*/
|
||||||
|
class InputFile
|
||||||
|
: public InputStreamBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Open a file with the given path
|
||||||
|
*
|
||||||
|
* Opening a file is a prerequisite for reading from the
|
||||||
|
* object. open() will throw a FileOpenErrorException if
|
||||||
|
* an error occurs.
|
||||||
|
*
|
||||||
|
* @param path The (relative) path of the file to open
|
||||||
|
* @param read True, if the file should be read, false on write.
|
||||||
|
*/
|
||||||
|
InputFile (const std::string &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close the file
|
||||||
|
*
|
||||||
|
* The destructor will automatically close the file.
|
||||||
|
*/
|
||||||
|
virtual ~InputFile ();
|
||||||
|
|
||||||
|
virtual size_t read (char *b, size_t n);
|
||||||
|
|
||||||
|
virtual void reset ();
|
||||||
|
|
||||||
|
virtual void close ();
|
||||||
|
|
||||||
|
virtual std::string source () const
|
||||||
|
{
|
||||||
|
return m_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string absolute_path () const;
|
||||||
|
|
||||||
|
virtual std::string filename () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_source;
|
||||||
|
int m_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A simple pipe input delegate
|
||||||
|
*
|
||||||
|
* Implements the reader for pipe streams
|
||||||
|
*/
|
||||||
|
class InputPipe
|
||||||
|
: public InputStreamBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Open a stream by connecting with the stdout of a given command
|
||||||
|
*
|
||||||
|
* Opening a pipe is a prerequisite for reading from the
|
||||||
|
* object. open() will throw a FilePOpenErrorException if
|
||||||
|
* an error occurs - commonly if the command cannot be executed.
|
||||||
|
* This implementation is based on popen ().
|
||||||
|
*
|
||||||
|
* @param cmd The command to execute
|
||||||
|
* @param read True, if the file should be read, false on write.
|
||||||
|
*/
|
||||||
|
InputPipe (const std::string &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close the pipe
|
||||||
|
*
|
||||||
|
* The destructor will automatically close the pipe.
|
||||||
|
*/
|
||||||
|
virtual ~InputPipe ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read from the pipe
|
||||||
|
*
|
||||||
|
* Implements the basic read method.
|
||||||
|
* Will throw a FilePReadErrorException if an error occurs.
|
||||||
|
*/
|
||||||
|
virtual size_t read (char *b, size_t n);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset to the beginning of the file
|
||||||
|
*/
|
||||||
|
virtual void reset ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Closes the pipe
|
||||||
|
*/
|
||||||
|
virtual void close ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the source specification (the file name)
|
||||||
|
*
|
||||||
|
* Returns an empty string if no file name is available.
|
||||||
|
*/
|
||||||
|
virtual std::string source () const
|
||||||
|
{
|
||||||
|
// No source (in the sense of a file name) is available ..
|
||||||
|
return std::string ();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string absolute_path () const
|
||||||
|
{
|
||||||
|
// No source (in the sense of a file name) is available ..
|
||||||
|
return std::string ();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual std::string filename () const
|
||||||
|
{
|
||||||
|
// No source (in the sense of a file name) is available ..
|
||||||
|
return std::string ();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE *m_file;
|
||||||
|
std::string m_source;
|
||||||
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -248,8 +424,9 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Copies the content of the stream to the output stream
|
* @brief Copies the content of the stream to the output stream
|
||||||
|
* Throws an exception on error.
|
||||||
*/
|
*/
|
||||||
void copy_to (tl::OutputStream &os);
|
void copy_to(tl::OutputStream &os);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable uncompression of the following DEFLATE-compressed block
|
* @brief Enable uncompression of the following DEFLATE-compressed block
|
||||||
|
|
@ -604,6 +781,144 @@ private:
|
||||||
std::ostringstream m_stream;
|
std::ostringstream m_stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A zlib output file delegate
|
||||||
|
*
|
||||||
|
* Implements the writer for a zlib stream
|
||||||
|
*/
|
||||||
|
class OutputZLibFile
|
||||||
|
: public OutputStreamBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Open a file with the given path
|
||||||
|
*
|
||||||
|
* Opening a file is a prerequisite for reading from the
|
||||||
|
* object. open() will throw a FileOpenErrorException if
|
||||||
|
* an error occurs.
|
||||||
|
*
|
||||||
|
* @param path The (relative) path of the file to open
|
||||||
|
*/
|
||||||
|
OutputZLibFile (const std::string &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close the file
|
||||||
|
*
|
||||||
|
* The destructor will automatically close the file.
|
||||||
|
*/
|
||||||
|
virtual ~OutputZLibFile ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write to a file
|
||||||
|
*
|
||||||
|
* Implements the basic write method.
|
||||||
|
* Will throw a ZLibWriteErrorException if an error occurs.
|
||||||
|
*/
|
||||||
|
virtual void write (const char *b, size_t n);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_source;
|
||||||
|
gzFile m_zs;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A simple output file delegate
|
||||||
|
*
|
||||||
|
* Implements the writer for ordinary files.
|
||||||
|
*/
|
||||||
|
class OutputFile
|
||||||
|
: public OutputStreamBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Open a file with the given path
|
||||||
|
*
|
||||||
|
* Opening a file is a prerequisite for reading from the
|
||||||
|
* object. open() will throw a FileOpenErrorException if
|
||||||
|
* an error occurs.
|
||||||
|
*
|
||||||
|
* @param path The (relative) path of the file to open
|
||||||
|
* @param read True, if the file should be read, false on write.
|
||||||
|
*/
|
||||||
|
OutputFile (const std::string &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close the file
|
||||||
|
*
|
||||||
|
* The destructor will automatically close the file.
|
||||||
|
*/
|
||||||
|
virtual ~OutputFile ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Seek to the specified position
|
||||||
|
*
|
||||||
|
* Writing continues at that position after a seek.
|
||||||
|
*/
|
||||||
|
virtual void seek (size_t s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns a value indicating whether that stream supports seek
|
||||||
|
*/
|
||||||
|
bool supports_seek ()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write to a file
|
||||||
|
*
|
||||||
|
* Implements the basic write method.
|
||||||
|
* Will throw a FileWriteErrorException if an error occurs.
|
||||||
|
*/
|
||||||
|
virtual void write (const char *b, size_t n);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_source;
|
||||||
|
int m_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A simple pipe output delegate
|
||||||
|
*
|
||||||
|
* Implements the writer for pipe streams
|
||||||
|
*/
|
||||||
|
class OutputPipe
|
||||||
|
: public OutputStreamBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Open a stream by connecting with the stdout of a given command
|
||||||
|
*
|
||||||
|
* Opening a pipe is a prerequisite for reading from the
|
||||||
|
* object. open() will throw a FilePOpenErrorException if
|
||||||
|
* an error occurs - commonly if the command cannot be executed.
|
||||||
|
* This implementation is based on popen ().
|
||||||
|
*
|
||||||
|
* @param cmd The command to execute
|
||||||
|
* @param read True, if the file should be read, false on write.
|
||||||
|
*/
|
||||||
|
OutputPipe (const std::string &path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Close the pipe
|
||||||
|
*
|
||||||
|
* The destructor will automatically close the pipe.
|
||||||
|
*/
|
||||||
|
virtual ~OutputPipe ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write to a file
|
||||||
|
*
|
||||||
|
* Implements the basic write method.
|
||||||
|
* Will throw a FilePWriteErrorException if an error occurs.
|
||||||
|
*/
|
||||||
|
virtual void write (const char *b, size_t n);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FILE *m_file;
|
||||||
|
std::string m_source;
|
||||||
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,9 @@ static std::locale c_locale ("C");
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Conversion of UTF8 to wchar_t
|
// Conversion of UTF8 to wchar_t
|
||||||
|
|
||||||
static std::vector<wchar_t> utf8_to_wchar (const std::string &s)
|
std::wstring to_wstring (const std::string &s)
|
||||||
{
|
{
|
||||||
std::vector<wchar_t> ws;
|
std::wstring ws;
|
||||||
|
|
||||||
const char *cpe = s.c_str () + s.size ();
|
const char *cpe = s.c_str () + s.size ();
|
||||||
for (const char *cp = s.c_str (); cp < cpe; ) {
|
for (const char *cp = s.c_str (); cp < cpe; ) {
|
||||||
|
|
@ -61,10 +61,10 @@ static std::vector<wchar_t> utf8_to_wchar (const std::string &s)
|
||||||
|
|
||||||
if (c32 >= 0x10000) {
|
if (c32 >= 0x10000) {
|
||||||
c32 -= 0x10000;
|
c32 -= 0x10000;
|
||||||
ws.push_back (wchar_t (0xd800 + (c32 >> 10)));
|
ws += wchar_t (0xd800 + (c32 >> 10));
|
||||||
ws.push_back (wchar_t (0xdc00 + (c32 & 0x3ff)));
|
ws += wchar_t (0xdc00 + (c32 & 0x3ff));
|
||||||
} else {
|
} else {
|
||||||
ws.push_back (wchar_t (c32));
|
ws += wchar_t (c32);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -72,11 +72,11 @@ static std::vector<wchar_t> utf8_to_wchar (const std::string &s)
|
||||||
return ws;
|
return ws;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string wchar_to_utf8 (const std::vector<wchar_t> &ws)
|
std::string to_string (const std::wstring &ws)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
for (std::vector<wchar_t>::const_iterator c = ws.begin (); c != ws.end (); ++c) {
|
for (std::wstring::const_iterator c = ws.begin (); c != ws.end (); ++c) {
|
||||||
|
|
||||||
uint32_t c32 = *c;
|
uint32_t c32 = *c;
|
||||||
if (c32 >= 0xd800 && c + 1 < ws.end ()) {
|
if (c32 >= 0xd800 && c + 1 < ws.end ()) {
|
||||||
|
|
@ -140,20 +140,36 @@ std::string tl::db_to_string (double d)
|
||||||
|
|
||||||
std::string tl::to_upper_case (const std::string &s)
|
std::string tl::to_upper_case (const std::string &s)
|
||||||
{
|
{
|
||||||
std::vector<wchar_t> ws = utf8_to_wchar (s);
|
std::wstring ws = to_wstring (s);
|
||||||
for (std::vector<wchar_t>::iterator c = ws.begin (); c != ws.end (); ++c) {
|
for (std::wstring::iterator c = ws.begin (); c != ws.end (); ++c) {
|
||||||
*c = towupper (*c);
|
*c = towupper (*c);
|
||||||
}
|
}
|
||||||
return wchar_to_utf8 (ws);
|
return to_string (ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tl::to_lower_case (const std::string &s)
|
std::string tl::to_lower_case (const std::string &s)
|
||||||
{
|
{
|
||||||
std::vector<wchar_t> ws = utf8_to_wchar (s);
|
std::wstring ws = to_wstring (s);
|
||||||
for (std::vector<wchar_t>::iterator c = ws.begin (); c != ws.end (); ++c) {
|
for (std::wstring::iterator c = ws.begin (); c != ws.end (); ++c) {
|
||||||
*c = towlower (*c);
|
*c = towlower (*c);
|
||||||
}
|
}
|
||||||
return wchar_to_utf8 (ws);
|
return to_string (ws);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_local (const std::string &s)
|
||||||
|
{
|
||||||
|
std::auto_ptr<char> buffer (new char [MB_CUR_MAX]); // MB_CUR_MAX isn't a constant
|
||||||
|
std::string ls;
|
||||||
|
|
||||||
|
std::wstring ws = to_wstring (s);
|
||||||
|
for (std::wstring::const_iterator c = ws.begin (); c != ws.end (); ++c) {
|
||||||
|
int length = wctomb (buffer.get (), *c);
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
ls += buffer.get ()[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ls;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string_from_local (const char *cp)
|
std::string to_string_from_local (const char *cp)
|
||||||
|
|
@ -161,7 +177,7 @@ std::string to_string_from_local (const char *cp)
|
||||||
mbstate_t state;
|
mbstate_t state;
|
||||||
memset ((void *) &state, 0, sizeof (mbstate_t));
|
memset ((void *) &state, 0, sizeof (mbstate_t));
|
||||||
|
|
||||||
std::vector<wchar_t> ws;
|
std::wstring ws;
|
||||||
|
|
||||||
size_t max = strlen (cp);
|
size_t max = strlen (cp);
|
||||||
|
|
||||||
|
|
@ -172,12 +188,12 @@ std::string to_string_from_local (const char *cp)
|
||||||
if (length < 1) {
|
if (length < 1) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ws.push_back (wc);
|
ws += wc;
|
||||||
cp += length;
|
cp += length;
|
||||||
max -= length;
|
max -= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wchar_to_utf8 (ws);
|
return to_string (ws);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,9 @@
|
||||||
#include "tlException.h"
|
#include "tlException.h"
|
||||||
#include "tlVariant.h"
|
#include "tlVariant.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_QT)
|
||||||
class QImage;
|
class QImage;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace tl {
|
namespace tl {
|
||||||
|
|
||||||
|
|
@ -262,6 +264,7 @@ TL_PUBLIC std::string to_string (float d, int prec);
|
||||||
TL_PUBLIC std::string to_string (const unsigned char *cp, int length);
|
TL_PUBLIC std::string to_string (const unsigned char *cp, int length);
|
||||||
TL_PUBLIC std::string to_string (const char *cp, int length);
|
TL_PUBLIC std::string to_string (const char *cp, int length);
|
||||||
TL_PUBLIC std::string to_string_from_local (const char *cp);
|
TL_PUBLIC std::string to_string_from_local (const char *cp);
|
||||||
|
TL_PUBLIC std::string to_local (const std::string &s);
|
||||||
|
|
||||||
template <class T> inline std::string to_string (const T &o) { return o.to_string (); }
|
template <class T> inline std::string to_string (const T &o) { return o.to_string (); }
|
||||||
template <> inline std::string to_string (const double &d) { return to_string (d, 12); }
|
template <> inline std::string to_string (const double &d) { return to_string (d, 12); }
|
||||||
|
|
@ -287,8 +290,20 @@ template <> inline std::string to_string (const std::string &s) { return s; }
|
||||||
// to a variant object
|
// to a variant object
|
||||||
template <> inline std::string to_string (const tl::Variant &v) { return v.to_parsable_string (); }
|
template <> inline std::string to_string (const tl::Variant &v) { return v.to_parsable_string (); }
|
||||||
|
|
||||||
|
#if defined(HAVE_QT)
|
||||||
// some dummy conversions provided for tl::Variant implementation
|
// some dummy conversions provided for tl::Variant implementation
|
||||||
template <> inline std::string to_string (const QImage &) { return std::string (); }
|
template <> inline std::string to_string (const QImage &) { return std::string (); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts UTF-8 to wide character string
|
||||||
|
*/
|
||||||
|
std::wstring TL_PUBLIC to_wstring (const std::string &s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts a wide character string to UTF-8
|
||||||
|
*/
|
||||||
|
std::string TL_PUBLIC to_string (const std::wstring &ws);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Convert to a quoted string
|
* @brief Convert to a quoted string
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@
|
||||||
#include "tlFileUtils.h"
|
#include "tlFileUtils.h"
|
||||||
#include "tlUnitTest.h"
|
#include "tlUnitTest.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_QT)
|
||||||
|
|
||||||
|
// A few things we cross-check against Qt
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
|
@ -161,3 +165,5 @@ TEST (3)
|
||||||
file.close ();
|
file.close ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue