// -*- 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/File.cpp,v 1.25 2005/03/10 19:18:49 kommer Exp $
#include <acdk.h>
#include "File.h"
#include "FileStandardImpl.h"
#include "Writer.h"
#include <acdk/lang/System.h>
#include <acdk/lang/Integer.h>
#if defined(ACDK_OS_WIN32) && !defined(ACDK_OS_CYGWIN32)
# include <direct.h>
# include <io.h>
# include <windows.h>
#endif
/FONT>
#if defined(ACDK_OS_UNIX) || defined(ACDK_OS_CYGWIN32)
# include <dirent.h>
#endif
/FONT>
#if defined(ACDK_OS_UNIX)
#include <unistd.h>
#endif
namespace acdk {
namespace io {
#if defined(ACDK_OS_WIN32)
const char File::_pathSeparatorChar = ';';
const char File::_nameSeparatorChar = '\\';
#else //defined(ACDK_OS_WIN32)
const char File::_pathSeparatorChar = ':';
const char File::_nameSeparatorChar = '/';
#endif //defined(ACDK_OS_WIN32)
//static
RString
File::pathSeparator()
{
static char buf[2]; buf[1] = 0; buf[0] = pathSeparatorChar();
/*
#if defined(ACDK_OS_WIN32)
static char ubuf[2]; buf[1] = 0; buf[0] = ':';
if (System::_unixMode == true)
return new String(ubuf);
#endif
*/
return new String(buf);
}
//static
RString
File::separator()
{
static char buf[2]; buf[1] = 0; buf[0] = separatorChar();
/*
#if defined(ACDK_OS_WIN32)
static char ubuf[2]; buf[1] = 0; buf[0] = '/';
if (System::_unixMode == true)
return new String(ubuf);
#endif
*/
return new String(buf);
}
//static
RString
File::endOfLine()
{
#if defined(ACDK_OS_WIN32)
if (System::_unixMode == true)
return new String("\n");
return new String("\r\n");
#else
/FONT>
return new String("\n");
#endif
/FONT>
}
/*
RFileImplFactoryArray getStaticFactory()
{
static RFileImplFactoryArray _factories;
if (_factories == Nil) {
_factories = new FileImplFactoryArray(0);
}
return _factories;
}
//static
//static
void
File::registerFileImpl(RFileImplFactory fimplfactory)
{
RFileImplFactoryArray factories = getStaticFactory();
factories->append(fimplfactory);
}
*/
//static
RFileImpl
File::getFileImpl(IN(RString) fname)
{
RFileSystem fs = FileSystem::findFileSystem(fname);
if (fs == Nil)
return new FileStandardImpl(fname);
return fs->getFileImpl(fname);
/*reimplement
int l = fac->length();
for (int i = 0; i < l; ++i)
{
if (fac[i]->handleFile(fname) == true)
return fac[i]->create(fname);
}
*/
}
File::File(IN(RString) path)
{
_fileImpl = getFileImpl(path);
}
File::File(IN(RFile) parent, IN(RString) child)
{
_fileImpl = parent->makeChild(child)->getFileImpl(); //## performance: may go directly over file system
}
File::File(IN(RString) parent, IN(RString) child)
{
_fileImpl = File(parent).makeChild(child)->getFileImpl();
}
//static
RString
File::concat(IN(RString) parent, IN(RString) child)
{
if (parent == Nil)
return child;
if (child == Nil)
return parent;
return File(parent).makeChild(child)->getPath();
/*
if (parent->endsWith(separator()))
return parent + child;
else
return parent + separator() + child;
*/
}
//static
RString
File::getCWD()
{
char buffer[ACDK_MAX_PATH];
if (getcwd(buffer, ACDK_MAX_PATH) == NULL)
return Nil;
return SCS(buffer);
}
//static
bool
File::setCWD(IN(RString) newpath)
{
#if defined(ACDK_OS_WIN32) && !defined(ACDK_OS_CYGWIN32)
char buffer[ACDK_MAX_PATH];
if (getcwd(buffer, ACDK_MAX_PATH) != NULL) {
if (newpath->length() > 1 && newpath->charAt(0) != buffer[0]) {
char cb[3]; cb[0] = newpath->charAt(0); cb[1] = ':'; cb[2] = '\0';
chdir(cb);
}
}
#endif //defined(ACDK_OS_WIN32) && !defined(ACDK_OS_CYGWIN32)
RString ascpath = newpath->convert(CCAscii);
return chdir(ascpath->c_str()) == 0;
}
//static
RFile
File::getCWDFile()
{
return new File(getCWD());
}
bool
File::mkdirs(int mode)
{
if (exists() == true)
return true;
if (mkdir(mode) == true)
return true;
RString fname = getCanonicalPath();
int lpos = fname->lastIndexOf(separatorChar());
if (lpos == 0 || lpos == -1)
return false;
if (File(fname->substr(0, lpos)).mkdirs(mode) == false)
return false;
return mkdir(mode);
}
//static
RFile
File::createTempFile(IN(RString) prefix, IN(RString) suffix)
{
if (prefix == Nil || prefix->length() < 3)
THROW1(IllegalArgumentException, "File::createTempFile: prefix needs at least 3 characters");
RString suf = suffix;
if (suf == Nil)
suf = ".tmp";
RString tdir = System::getProperty("TEMP");
if (tdir == Nil || tdir->length() == 0)
tdir = File::getCWD();
return createTempFile(prefix, suf, new File(tdir));
}
//static
RFile
File::createTempFile(IN(RString) prefix, IN(RString) suffix, IN(RFile) directory)
{
if (prefix == Nil || prefix->length() < 3)
THROW1(IllegalArgumentException, "File::createTempFile: prefix needs at least 3 characters");
RClass fileclass = File::GetClass();
SYNCOBJECT(fileclass);
RString suf = suffix;
if (suf == Nil)
suf = ".tmp";
int c = 0;
while (true)
{
RString fname = File::concat(directory->getCanonicalPath(), prefix + Integer::toString(c) + suf);
RFile ret = new File(fname);
if (ret->exists() == false)
{
ret->createNewFile();
return ret;
}
++c;
}
return Nil;
}
//static
RFileArray
File::listRoots()
{
#if defined(ACDK_OS_UNIX) || defined(ACDK_OS_CYGWIN32) //|| defined(ACDK_OS_WIN32)
# if defined(ACDK_OS_WIN32) // dead code
if (System::_unixMode == true)
{
# endif
/FONT>
RFileArray roots = new FileArray(1);
roots[0] = new File("/");
return roots;
# if defined(ACDK_OS_WIN32)
}
# endif
/FONT>
#endif
/FONT>
#if defined(ACDK_OS_WIN32) && !defined(ACDK_OS_CYGWIN32)
TCHAR buffer[260];
RFileArray roots = new FileArray(26);
if (GetLogicalDriveStrings(260, buffer) == 0)
{
roots->resize(0);
return roots;
}
TCHAR* ptr = buffer;
int i;
for (i = 0; *ptr; i++)
{
roots[i] = new File((uc2char*)ptr);
ptr += tstrlen(ptr) + 1;
}
roots->resize(i);
return roots;
#endif //defined(ACDK_OS_WIN32) && !defined(ACDK_OS_CYGWIN32)
}
//foreign virtual
int
File::compareTo(IN(acdk::lang::Object) o)
{
return compareTo((RFile)o);
}
//virtual
int
File::compareTo(IN(RFile) o)
{
RString str1 = getCanonicalPath();
RString str2 = o->getCanonicalPath();
#if defined(ACDK_OS_WIN32)
if (str1->equalsIgnoreCase(str2) == true)
return 0;
#endif
/FONT>
return str1->compareTo(str2);
}
//foreign virtual
bool
File::equals(IN(acdk::lang::Object) o)
{
if (instanceof(o, File) == false)
return false;
return compareTo((RFile)o) == 0;
}
//foreign
RString
File::toString()
{
return _fileImpl->getPath();
}
//foreign virtual
int
File::hashCode()
{
return getCanonicalPath()->hashCode();
}
void
File::deleteOnExit()
{
_throwNotImplementedYet("File::deleteOnExit()");
}
//virtual
RReader
File::getReader()
{
return _fileImpl->getReader();
}
//virtual
RWriter
File::getWriter()
{
return _fileImpl->getWriter();
}
RString
File::loadAscii()
{
return new String(RcharArray(loadBinary()));
}
RbyteArray
File::loadBinary()
{
if (canRead() == false)
return new byteArray(0);
jlong l = length();
RbyteArray ch = new byteArray(l);
RReader fin = getReader();
fin->read(ch, 0, ch->length());
return ch;
}
} // io
} // acdk
|