/* === S Y N F I G ========================================================= */
/*! \file filesystemnative.cpp
** \brief FileSystemNative
**
** $Id$
**
** \legal
** ......... ... 2013 Ivan Mahonin
**
** This package is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License as
** published by the Free Software Foundation; either version 2 of
** the License, or (at your option) any later version.
**
** This package 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
** General Public License for more details.
** \endlegal
*/
/* ========================================================================= */
/* === H E A D E R S ======================================================= */
#ifdef USING_PCH
# include "pch.h"
#else
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <giomm.h>
#include <glibmm.h>
#include <sys/stat.h>
#include "general.h"
#include <synfig/localization.h>
#include "filesystemnative.h"
#include "guid.h"
#endif
/* === U S I N G =========================================================== */
using namespace std;
using namespace etl;
using namespace synfig;
/* === M A C R O S ========================================================= */
/* === G L O B A L S ======================================================= */
/* === P R O C E D U R E S ================================================= */
/* === M E T H O D S ======================================================= */
const FileSystemNative::Handle FileSystemNative::instance__(new FileSystemNative);
// ReadStream
FileSystemNative::ReadStream::ReadStream(FileSystem::Handle file_system, FILE *file):
FileSystem::ReadStream(file_system), file_(file) { }
FileSystemNative::ReadStream::~ReadStream()
{ fclose(file_); }
size_t FileSystemNative::ReadStream::internal_read(void *buffer, size_t size)
{ return fread(buffer, 1, size, file_); }
// WriteStream
FileSystemNative::WriteStream::WriteStream(FileSystem::Handle file_system, FILE *file):
FileSystem::WriteStream(file_system), file_(file) { }
FileSystemNative::WriteStream::~WriteStream()
{ fclose(file_); }
size_t FileSystemNative::WriteStream::internal_write(const void *buffer, size_t size)
{ return fwrite(buffer, 1, size, file_); }
// FileSystemNative
FileSystemNative::FileSystemNative() { }
FileSystemNative::~FileSystemNative() { }
bool FileSystemNative::is_file(const String &filename)
{
return Gio::File::create_for_path(fix_slashes(filename))->query_file_type()
== Gio::FILE_TYPE_REGULAR;
}
bool FileSystemNative::is_directory(const String &filename)
{
return Gio::File::create_for_path(fix_slashes(filename))->query_file_type()
== Gio::FILE_TYPE_DIRECTORY;
}
bool FileSystemNative::directory_create(const String &dirname)
{
return is_directory(dirname)
|| Gio::File::create_for_path(fix_slashes(dirname))->make_directory();
}
bool FileSystemNative::directory_scan(const String &dirname, FileList &out_files)
{
out_files.clear();
if (!is_directory(dirname)) return false;
Glib::Dir dir(dirname);
for(Glib::DirIterator i = dir.begin(); i != dir.end(); ++i)
out_files.push_back(Glib::filename_to_utf8(*i));
return true;
}
bool FileSystemNative::file_remove(const String &filename)
{
return 0 == remove(fix_slashes(filename).c_str());
}
bool FileSystemNative::file_rename(const String &from_filename, const String &to_filename)
{
#ifdef _WIN32
// On Win32 platforms, rename() has bad behavior. Work around it.
// Make random filename and ensure there's no file with such name exist
struct stat buf;
String old_file;
do {
synfig::GUID guid;
old_file = to_filename+"."+guid.get_string().substr(0,8);
} while (stat(Glib::locale_from_utf8(old_file).c_str(), &buf) != -1);
rename(Glib::locale_from_utf8(to_filename).c_str(),Glib::locale_from_utf8(old_file).c_str());
if(rename(Glib::locale_from_utf8(from_filename).c_str(),Glib::locale_from_utf8(to_filename).c_str())!=0)
{
rename(Glib::locale_from_utf8(old_file).c_str(),Glib::locale_from_utf8(to_filename).c_str());
synfig::error("synfig::save_canvas(): Unable to rename file to correct filename, errno=%d",errno);
return false;
}
remove(Glib::locale_from_utf8(old_file).c_str());
return true;
#else
return 0 == rename(from_filename.c_str(), to_filename.c_str());
#endif
}
FileSystem::ReadStream::Handle FileSystemNative::get_read_stream(const String &filename)
{
#ifdef _WIN32
FILE *f = fopen(Glib::locale_from_utf8(fix_slashes(filename)).c_str(), "rb");
#else
FILE *f = fopen(fix_slashes(filename).c_str(), "rb");
#endif
return f == NULL
? FileSystem::ReadStream::Handle()
: FileSystem::ReadStream::Handle(new ReadStream(this, f));
}
FileSystem::WriteStream::Handle FileSystemNative::get_write_stream(const String &filename)
{
#ifdef _WIN32
FILE *f = fopen(Glib::locale_from_utf8(fix_slashes(filename)).c_str(), "wb");
#else
FILE *f = fopen(fix_slashes(filename).c_str(), "wb");
#endif
return f == NULL
? FileSystem::WriteStream::Handle()
: FileSystem::WriteStream::Handle(new WriteStream(this, f));
}
String FileSystemNative::get_real_uri(const String &filename)
{
if (filename.empty()) return String();
return Glib::filename_to_uri(etl::absolute_path(filename));
}
/* === E N T R Y P O I N T ================================================= */