// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*-
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
//
//
// 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
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
// ACDK
//
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
//
// $Header: /cvsroot/acdk/acdk/acdk_core/src/acdk/io/FileStandardImpl.cpp,v 1.22 2005/05/02 23:07:41 kommer Exp $
#include <acdk.h>
#include <acdk/io/File.h>
#include <acdk/io/FileWriter.h>
#include <acdk/io/FileReader.h>
#include "../Config.h"
#include "FileStandardImpl.h"
#include "FileStatus.h"
#include <acdk/lang/ObjectArrayImpl.h>
#include <acdk/lang/Math.h>
#include <acdk/util/StringTokenizer.h>
#include <stdio.h>
#include <errno.h>
#ifdef HAS_UNISTD_H
# include <unistd.h>
#endif
/FONT>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined(ACDK_OS_WIN32) && !defined(ACDK_OS_CYGWIN32)
# include <direct.h>
# include <io.h>
# include <wchar.h>
# include <windows.h>
#endif
/FONT>
#if defined(ACDK_OS_UNIX) || defined(ACDK_OS_CYGWIN32)
# include <dirent.h>
#endif
/FONT>
#include <acdk/lang/UnsupportedOperationException.h>
#if defined(ACDK_OS_WIN32)
#define trmdir _wrmdir
#define tunlink _wunlink
#define tmkdir _wmkdir
#define trename _wrename
#define topen _wopen
#else
/FONT>
#define trmdir rmdir
#define tunlink unlink
#define tmkdir mkdir
#define trename rename
#define topen open
#endif
/FONT>
namespace acdk {
namespace io {
RFileImpl
FileStandardImpl::create(IN(RString) fname)
{
return new FileStandardImpl(fname);
}
//virtual
bool
FileStandardImpl::exists()
{
return FileStatus(getCanonicalPath()).exists();
}
//virtual
bool
FileStandardImpl::canRead()
{
return FileStatus(getCanonicalPath()).canRead();
}
//virtual
bool
FileStandardImpl::canWrite()
{
return FileStatus(getCanonicalPath()).canWrite();
}
//virtual
bool
FileStandardImpl::isDirectory()
{
return FileStatus(getCanonicalPath()).isDirectory();
}
//virtual
bool
FileStandardImpl::isFile()
{
return FileStatus(getCanonicalPath()).isFile();
}
//virtual
bool
FileStandardImpl::isHidden()
{
return false;
}
//virtual
jlong
FileStandardImpl::length()
{
return FileStatus(getCanonicalPath()).length();
}
//virtual
bool
FileStandardImpl::createNewFile()
{
if (exists() == true)
return false;
RString cpath = getCanonicalPath()->convertToNative();
int erg = topen(ACDK_API_CONSTCHARPTR(cpath->native_c_str()), O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
if (erg == -1)
return false;
close(erg);
return true;
}
//virtual
bool
FileStandardImpl::deleteFile()
{
if (exists() == false)
return false;
RString canp = getCanonicalPath()->convertToNative();
if (isDirectory())
return trmdir(ACDK_API_CONSTCHARPTR(canp->native_c_str())) == 0;
return tunlink(ACDK_API_CONSTCHARPTR(canp->native_c_str())) == 0;
}
RStringArray
FileStandardImpl::_listFiles(IN(RString) dir)
{
#if defined(ACDK_OS_WIN32) && !defined(ACDK_OS_CYGWIN32)
RString tdir = dir + File::separator() + "*";
WIN32_FIND_DATA fd;
tdir = tdir->convertToNative();
HANDLE fh = FindFirstFile(ACDK_API_CONSTCHARPTR(tdir->native_c_str()), &fd);
if (fh == NULL)
return new ObjectArrayImpl<RString>(0);
RStringArray files = new ObjectArrayImpl<RString>(20);
int count = 0;
do {
files->resize(count + 1);
files[count] = SCS((const uc2char*)fd.cFileName);
++count;
} while (FindNextFile(fh, &fd));
FindClose(fh);
files->resize(count);
return files;
#endif // defined(ACDK_OS_WIN32) && !defined(ACDK_OS_CYGWIN32)
#if defined(ACDK_OS_UNIX) || defined(ACDK_OS_CYGWIN32)
DIR* dp;
RString tdir = dir->convertToNative();
dp = opendir(dir->native_c_str());
if (dp == NULL)
return new ObjectArrayImpl<RString>(0);
RStringArray files = new ObjectArrayImpl<RString>(20);
struct dirent* dirp;
int i = 0;
for (; (dirp = readdir(dp)) != NULL; i++) {
files->ensureCapacity(i + 1);
files[i] = SCS(dirp->d_name);
}
closedir(dp);
files->resize(i);
return files;
#endif //ACDK_OS_UNIX
}
//virtual
RStringArray
FileStandardImpl::list(IN(RFilenameFilter) filter/* = Nil*/, int listFlags/* = FileListBoth*/)
{
if (isDirectory() == false)
return new StringArray(0);
RString cp = getCanonicalPath();
RFileArray files = getFileSystem()->listFiles(cp, listFlags);
RStringArray erglist = new StringArray(0);
int ergcount = 0;
int i;
File tf(this);
for (i = 0; i < files->length(); i++)
{
RString name = files[i]->getName();
if (filter == Nil || filter->accept(&tf, name) == true)
{
RString fqn = files[i]->getCanonicalPath();
name = fqn->substr(cp->length() + 1);
erglist->append(name);
}
}
return erglist;
}
//virtual
RFileArray
FileStandardImpl::listFiles(IN(RFileFilter) filter/* = Nil*/, int listFlags/* = FileListBoth*/)
{
if (isDirectory() == false)
return Nil;
RString cp = getCanonicalPath();
RFileArray files = getFileSystem()->listFiles(cp, listFlags);
if (filter == Nil)
return files;
RFileArray erglist = new FileArray(0);
int ergcount = 0;
for (int i = 0; i < files->length(); i++)
{
if (filter->accept(files[i]) == true)
{
erglist->append(files[i]);
}
}
return erglist;
}
//virtual
jlong
FileStandardImpl::lastModified()
{
if (exists() == false)
return 0;
return FileStatus(getCanonicalPath()).lastModified();
}
//virtual
jlong
FileStandardImpl::fileCreated()
{
if (exists() == false)
return 0;
return FileStatus(getCanonicalPath()).created();
}
//virtual
bool
FileStandardImpl::mkdir(int mode/* = 0777*/)
{
if (exists() == true)
return false;
RString cpath = getCanonicalPath()->convertToNative();
#if defined(ACDK_OS_UNIX) || defined(ACDK_OS_CYGWIN32)
return ::tmkdir(cpath->native_c_str(), mode) == 0;
#else
/FONT>
return ::tmkdir(ACDK_API_CONSTCHARPTR(cpath->native_c_str())) == 0;
#endif
/FONT>
}
//virtual
bool
FileStandardImpl::renameTo(IN(RFile) dest)
{
//### check if same file implementation
if (exists() == false)
return false;
if (isDirectory()) {
_throwNotImplementedYet("File::renameTo()");
}
if (dest->exists())
return false;
RString cpath = getCanonicalPath()->convertToNative();
RString destcpath = dest->getCanonicalPath()->convertToNative();
return ::trename(ACDK_API_CONSTCHARPTR(cpath->native_c_str()), ACDK_API_CONSTCHARPTR(destcpath->native_c_str())) == 0;
}
//virtual
bool
FileStandardImpl::setLastModified(jlong time)
{
if (exists() == false)
return false;
return FileStatus(getCanonicalPath()).lastModified(time);
}
//virtual
bool
FileStandardImpl::setFileCreated(jlong time)
{
if (exists() == false)
return false;
return FileStatus(getCanonicalPath()).created(time);
}
//virtual
RReader
FileStandardImpl::getReader()
{
return new FileReader(_path);
}
//virtual
RWriter
FileStandardImpl::getWriter()
{
return new FileWriter(_path);
}
//virtual
RFileSystem
FileStandardImpl::getFileSystem()
{
return StandardFileSystem::standarFileSystem();
}
RFileInfo
FileStandardImpl::getFileInfo()
{
#if defined(ACDK_OS_WIN32)
return FileStatus(getPath()).getFileInfo();
#else
/FONT>
return FileImpl::getFileInfo();
#endif
/FONT>
}
bool
FileStandardImpl::setFileAttributes(int mask, int flags)
{
return FileStatus(getPath()).setFileAttributes(mask, flags);
}
//static
RString
FileStandardImpl::fileUrlToFileName(IN(RString) furl)
{
if (furl->startsWith("file:///") == false)
return furl;
RString fname = furl;
fname = fname->substr(8);
if (File::separatorChar() != '/')
fname = fname->replace('/', File::separatorChar());
return fname;
}
} // io
} // acdk
|