blob: 3e9d087216c593f3e76c9bbcb59ee2cb418016c4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <log4cxx/logstring.h>
#include <log4cxx/file.h>
#include <apr_file_io.h>
#include <apr_file_info.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/pool.h>
#include <assert.h>
#include <log4cxx/helpers/exception.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
File::File() {
}
template<class S>
static LogString decodeLS(const S* src) {
LogString dst;
if (src != 0) {
Transcoder::decode(src, dst);
}
return dst;
}
template<class S>
static LogString decodeLS(const std::basic_string<S>& src) {
LogString dst;
Transcoder::decode(src, dst);
return dst;
}
File::File(const std::string& name1)
: path(decodeLS(name1)) {
}
File::File(const char* name1)
: path(decodeLS(name1)) {
}
#if LOG4CXX_WCHAR_T_API
File::File(const std::wstring& name1)
: path(decodeLS(name1)) {
}
File::File(const wchar_t* name1)
: path(decodeLS(name1)) {
}
#endif
#if LOG4CXX_UNICHAR_API
File::File(const std::basic_string<UniChar>& name1)
: path(decodeLS(name1)) {
}
File::File(const UniChar* name1)
: path(decodeLS(name1)) {
}
#endif
#if LOG4CXX_CFSTRING_API
File::File(const CFStringRef& name1)
: path(decodeLS(name1)) {
}
#endif
File::File(const File& src)
: path(src.path) {
}
File& File::operator=(const File& src) {
if (this == &src) return *this;
path.assign(src.path);
return *this;
}
File::~File() {
}
LogString File::getPath() const {
return path;
}
File& File::setPath(const LogString& newName) {
path.assign(newName);
return *this;
}
LogString File::getName() const {
const logchar slashes[] = { 0x2F, 0x5C, 0 };
size_t lastSlash = path.find_last_of(slashes);
if (lastSlash != LogString::npos) {
return path.substr(lastSlash+1);
}
return path;
}
char* File::getPath(Pool& p) const {
int style = APR_FILEPATH_ENCODING_UNKNOWN;
apr_filepath_encoding(&style, p.getAPRPool());
char* retval = NULL;
if (style == APR_FILEPATH_ENCODING_UTF8) {
retval = Transcoder::encodeUTF8(path, p);
} else {
retval = Transcoder::encode(path, p);
}
return retval;
}
log4cxx_status_t File::open(apr_file_t** file, int flags,
int perm, Pool& p) const {
return apr_file_open(file, getPath(p), flags, perm, p.getAPRPool());
}
bool File::exists(Pool& p) const {
apr_finfo_t finfo;
apr_status_t rv = apr_stat(&finfo, getPath(p),
0, p.getAPRPool());
return rv == APR_SUCCESS;
}
char* File::convertBackSlashes(char* src) {
for(char* c = src; *c != 0; c++) {
if(*c == '\\') {
*c = '/';
}
}
return src;
}
bool File::deleteFile(Pool& p) const {
apr_status_t rv = apr_file_remove(convertBackSlashes(getPath(p)),
p.getAPRPool());
return rv == APR_SUCCESS;
}
bool File::renameTo(const File& dest, Pool& p) const {
apr_status_t rv = apr_file_rename(convertBackSlashes(getPath(p)),
convertBackSlashes(dest.getPath(p)),
p.getAPRPool());
return rv == APR_SUCCESS;
}
size_t File::length(Pool& pool) const {
apr_finfo_t finfo;
apr_status_t rv = apr_stat(&finfo, getPath(pool),
APR_FINFO_SIZE, pool.getAPRPool());
if (rv == APR_SUCCESS) {
return (size_t) finfo.size;
}
return 0;
}
log4cxx_time_t File::lastModified(Pool& pool) const {
apr_finfo_t finfo;
apr_status_t rv = apr_stat(&finfo, getPath(pool),
APR_FINFO_MTIME, pool.getAPRPool());
if (rv == APR_SUCCESS) {
return finfo.mtime;
}
return 0;
}
std::vector<LogString> File::list(Pool& p) const {
apr_dir_t *dir;
apr_finfo_t entry;
std::vector<LogString> filenames;
apr_status_t stat = apr_dir_open(&dir,
convertBackSlashes(getPath(p)),
p.getAPRPool());
if(stat == APR_SUCCESS) {
int style = APR_FILEPATH_ENCODING_UNKNOWN;
apr_filepath_encoding(&style, p.getAPRPool());
stat = apr_dir_read(&entry, APR_FINFO_DIRENT, dir);
while(stat == APR_SUCCESS) {
if (entry.name != NULL) {
LogString filename;
if(style == APR_FILEPATH_ENCODING_UTF8) {
Transcoder::decodeUTF8(entry.name, filename);
} else {
Transcoder::decode(entry.name, filename);
}
filenames.push_back(filename);
}
stat = apr_dir_read(&entry, APR_FINFO_DIRENT, dir);
}
stat = apr_dir_close(dir);
}
return filenames;
}
LogString File::getParent(Pool&) const {
LogString::size_type slashPos = path.rfind(LOG4CXX_STR('/'));
LogString::size_type backPos = path.rfind(LOG4CXX_STR('\\'));
if (slashPos == LogString::npos) {
slashPos = backPos;
} else {
if (backPos != LogString::npos && backPos > slashPos) {
slashPos = backPos;
}
}
LogString parent;
if (slashPos != LogString::npos && slashPos > 0) {
parent.assign(path, 0, slashPos);
}
return parent;
}
bool File::mkdirs(Pool& p) const {
apr_status_t stat = apr_dir_make_recursive(convertBackSlashes(getPath(p)),
APR_OS_DEFAULT, p.getAPRPool());
return stat == APR_SUCCESS;
}