You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/kvilib/file/kvi_fileutils.cpp

506 lines
12 KiB

//=============================================================================
//
// File : kvi_fileutils.cpp
// Creation date : Fri Dec 25 1998 18:26:48 by Szymon Stefanek
//
// This file is part of the KVirc irc client distribution
// Copyright (C) 1998-2007 Szymon Stefanek (pragma at kvirc dot net)
//
// This program 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 opinion) any later version.
//
// This program 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.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, write to the Free Software Foundation,
// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
#define __KVILIB__
#define _KVI_FILEUTLIS_CPP_
#include "kvi_fileutils.h"
#include "kvi_qstring.h"
#include "kvi_file.h"
#include "kvi_malloc.h"
#include <tqdir.h>
#include <tqfileinfo.h>
#include <tqglobal.h>
#include <tqtextcodec.h>
#include <tqtextstream.h>
namespace KviFileUtils
{
/*
WORKING CODE BUT UNUSED FOR NOW
bool readLine(TQFile * f,TQString &szBuffer,bool bClearBuffer)
{
// FIXME: Should this assume UTF8 encoding ?
char tmp_buf[256];
int cur_len = 0;
//char *cur_ptr = tmp_buf;
if(bClearBuffer)szBuffer = "";
int ch = f->getch();
while((ch != -1)&&(ch != '\n')&&(ch != 0))
{
tmp_buf[cur_len] = ch;
cur_len++;
if(cur_len > 255)
{
if(tmp_buf[255] == '\r')cur_len--; //Ignore CR...
int lastlen = szBuffer.length();
szBuffer.setLength(lastlen + cur_len);
TQChar *p1 = szBuffer.unicode() + lastlen;
char * p2 = tmp_buf;
for(int i=0;i<cur_len;i++)*p1++ = *p2++;
cur_len = 0;
}
ch = f->getch();
}
if(ch == 0)
{
tqDebug("Warning : %s is not an ascii file",f->name().latin1());
}
if(cur_len > 0)
{
if(tmp_buf[cur_len - 1] == '\r')cur_len--; //Ignore CR...
int lastlen = szBuffer.length();
szBuffer.setLength(lastlen + cur_len);
TQChar *p1 = szBuffer.unicode() + lastlen;
char * p2 = tmp_buf;
for(int i=0;i<cur_len;i++)*p1++ = *p2++;
}
return (ch == '\n'); //more data to read else a broken file or EOF
}
bool loadFileStripCR(const TQString &szPath,TQString &szBuffer)
{
TQFile f(szPath);
if(!f.open(IO_ReadOnly))return false;
szBuffer = "";
while(readLine(&f,szBuffer,false))
{
szBuffer.append('\n'); // readLine returned true...last char was a newline
}
// readLine returned false , no ending newline encountered
return true;
}
*/
bool makeDir(const TQString &szPath)
{
TQDir d;
TQString dir = KviTQString::trimmed(szPath);
adjustFilePath(dir);
TQString createdDir;
#ifdef COMPILE_ON_WINDOWS
#ifdef COMPILE_USE_QT4
int idx = dir.indexOf(':');
#else
int idx = dir.find(':');
#endif
if(idx == 1)
{
createdDir = dir.left(2);
dir.remove(0,2);
}
#endif
KviTQString::stripLeft(dir,KVI_PATH_SEPARATOR_CHAR);
while(!dir.isEmpty())
{
createdDir += KVI_PATH_SEPARATOR;
createdDir += KviTQString::getToken(dir,KVI_PATH_SEPARATOR_CHAR);
if(!directoryExists(createdDir))
{
if(!d.mkdir(createdDir))
{
tqDebug("Can't create directory %s",KviTQString::toUtf8(createdDir).data());
return false;
}
}
KviTQString::stripLeft(dir,KVI_PATH_SEPARATOR_CHAR);
}
return true;
}
bool makeDir(const char* path)
{
TQString szPath=TQString::fromUtf8(path);
return makeDir(szPath);
}
bool renameFile(const TQString &szSrc,const TQString &szDst)
{
TQDir d;
return d.rename(szSrc,szDst);
}
bool renameFile(const char* path,const char* path2)
{
TQString szPath=TQString::fromUtf8(path);
TQString szPath2=TQString::fromUtf8(path2);
return renameFile(szPath,szPath2);
}
bool copyFile(const TQString &szSrc,const TQString &szDst)
{
KviFile f1(szSrc);
if(!f1.openForReading())return false;
KviFile f2(szDst);
if(!f2.openForWriting())
{
f1.close();
return false;
}
char buffer[1024];
while(!f1.atEnd())
{
int len = f1.readBlock(buffer,1024);
if(len <= 0)
{
f1.close();
f2.close();
return false; //"serious error"
}
f2.writeBlock(buffer,len);
}
f1.close();
f2.close();
return true;
}
bool copyFile(const char* path,const char* path2)
{
TQString szPath=TQString::fromUtf8(path);
TQString szPath2=TQString::fromUtf8(path2);
return copyFile(szPath,szPath2);
}
bool loadFile(const TQString &szPath,TQString &szBuffer,bool bUtf8)
{
KviFile f(szPath);
if(!f.openForReading())return false;
if(bUtf8)
{
TQByteArray ba = f.readAll();
szBuffer = TQString::fromUtf8(ba.data(),ba.size());
//tqDebug("BUFFERLEN: %d",szBuffer.length());
} else {
szBuffer = TQString(f.readAll());
}
return true;
}
bool loadFile(const char* path,TQString &szBuffer,bool bUtf8)
{
TQString szPath=TQString::fromUtf8(path);
return loadFile(szPath,szBuffer,bUtf8);
}
void adjustFilePath(TQString &szPath)
{
#ifdef COMPILE_ON_WINDOWS
szPath.replace('/',"\\");
#ifdef COMPILE_USE_QT4
szPath.replace("\\\\","\\");
#else
while(szPath.find("\\\\") != -1)szPath.replace("\\\\","\\");
#endif
// FIXME: Use the default drive here ?
if(szPath.startsWith("\\"))szPath.prepend("C:");
#else
szPath.replace('\\',"/");
#ifdef COMPILE_USE_QT4
szPath.replace("//","/");
#else
while(KviTQString::find(szPath,"//") != -1)szPath.replace("//","/");
#endif
// deal with windows paths
if((szPath.length() > 2) && (szPath.at(0) != TQChar('/')))
{
if((szPath.at(1) == TQChar(':')) && (szPath.at(2) == TQChar('/')))
{
szPath.remove(0,2);
}
}
#ifdef COMPILE_USE_QT4
szPath=TQDir::cleanPath(szPath);
#else
szPath=TQDir::cleanDirPath(szPath);
#endif
#endif
}
bool directoryExists(const TQString &szPath)
{
TQFileInfo f(szPath);
return (f.exists() && f.isDir());
}
bool directoryExists(const char* path)
{
TQString szPath=TQString::fromUtf8(path);
TQFileInfo f(szPath);
return (f.exists() && f.isDir());
}
bool fileExists(const TQString &szPath)
{
TQFileInfo f(szPath);
return (f.exists() && f.isFile());
}
bool fileExists(const char* path)
{
TQString szPath=TQString::fromUtf8(path);
return fileExists(szPath);
}
bool removeFile(const TQString &szPath)
{
TQDir d;
return d.remove(szPath);
}
bool removeFile(const char* path)
{
TQString szPath=TQString::fromUtf8(path);
return removeFile(szPath);
}
bool removeDir(const TQString &szPath)
{
TQDir d;
return d.rmdir(szPath);
}
bool removeDir(const char* path)
{
TQString szPath=TQString::fromUtf8(path);
return removeDir(szPath);
}
bool deleteDir(const TQString &szPath)
{
TQDir d(szPath);
TQStringList sl = d.entryList(TQDir::Dirs);
TQStringList::Iterator it;
for(it=sl.begin();it != sl.end();it++)
{
TQString szSubdir = *it;
if(!(KviTQString::equalCS(szSubdir,"..") || KviTQString::equalCS(szSubdir,".")))
{
TQString szSubPath = szPath;
KviTQString::ensureLastCharIs(szSubPath,TQChar(KVI_PATH_SEPARATOR_CHAR));
szSubPath += szSubdir;
if(!KviFileUtils::deleteDir(szSubPath))
return false;
}
}
sl = d.entryList(TQDir::Files);
for(it=sl.begin();it != sl.end();it++)
{
TQString szFilePath = szPath;
KviTQString::ensureLastCharIs(szFilePath,TQChar(KVI_PATH_SEPARATOR_CHAR));
szFilePath += *it;
if(!KviFileUtils::removeFile(szFilePath))
return false;
}
return KviFileUtils::removeDir(szPath);
}
bool writeFile(const TQString &szPath,const TQString &szData,bool bAppend)
{
KviFile f(szPath);
if(!f.openForWriting(bAppend))return false;
KviTQCString szTmp = KviTQString::toUtf8(szData);
if(!szTmp.data())return true;
if(f.writeBlock(szTmp.data(),szTmp.length()) != ((int)(szTmp.length())))return false;
return true;
}
bool writeFile(const char* path,const TQString &szData,bool bAppend)
{
TQString szPath=TQString::fromUtf8(path);
return writeFile(szPath,szData,bAppend);
}
bool writeFileLocal8Bit(const TQString &szPath,const TQString &szData,bool bAppend)
{
KviFile f(szPath);
if(!f.openForWriting(bAppend))return false;
KviTQCString szTmp = TQTextCodec::codecForLocale()->fromUnicode(szData);
if(!szTmp.data())return true;
if(f.writeBlock(szTmp.data(),szTmp.length()) != ((int)(szTmp.length())))return false;
return true;
}
bool writeFileLocal8Bit(const char* path,const TQString &szData,bool bAppend)
{
TQString szPath=TQString::fromUtf8(path);
return writeFileLocal8Bit(szPath,szData,bAppend);
}
bool readFile(const TQString &szPath,TQString &szBuffer,unsigned int uMaxSize)
{
KviFile f(szPath);
if(!f.openForReading())return false;
if(f.size() < 1)
{
szBuffer = "";
f.close();
return true;
}
if(f.size() > uMaxSize)return false;
char * buf = new char[f.size() + 1];
if(f.readBlock(buf,f.size()) != ((long int)f.size()))
{
delete buf;
buf = 0;
return false;
}
buf[f.size()] = '\0';
szBuffer = TQString::fromUtf8(buf);
delete[] buf;
return true;
}
bool readFile(const char* path,TQString &szBuffer,unsigned int uMaxSize)
{
TQString szPath=TQString::fromUtf8(path);
return readFile(szPath,szBuffer,uMaxSize);
}
TQString extractFileName(const TQString &szFileNameWithPath)
{
return TQFileInfo(szFileNameWithPath).fileName();
}
TQString extractFilePath(const TQString &szFileNameWithPath)
{
return TQFileInfo(szFileNameWithPath).dirPath(true);
}
bool readLine(TQFile * f,TQString &szBuffer,bool bUtf8)
{
TQTextStream stream(f);
stream.setEncoding(bUtf8 ? TQTextStream::UnicodeUTF8 : TQTextStream::Locale);
szBuffer=stream.readLine();
return !szBuffer.isNull();
}
bool readLines(TQFile * f,TQStringList &buffer,int iStartLine, int iCount, bool bUtf8)
{
TQTextStream stream( f );
stream.setEncoding(bUtf8 ? TQTextStream::UnicodeUTF8 : TQTextStream::Locale);
for(int i=0;i<iStartLine;i++)
stream.readLine();
if(iCount>0)
{
for(; (iCount>0 && !stream.atEnd()) ; iCount-- )
buffer.append(stream.readLine());
} else {
while(!stream.atEnd()) {
buffer.append(stream.readLine());
}
}
return buffer.count()!= 0;
}
bool isReadable(const TQString &szFname)
{
TQFileInfo f(szFname);
return (f.exists() && f.isFile() && f.isReadable());
}
bool isReadable(const char* path)
{
TQString szPath=TQString::fromUtf8(path);
return isReadable(szPath);
}
bool isAbsolutePath(const TQString &szPath)
{
TQFileInfo f(szPath);
return !f.isRelative();
}
};
static char hexchars[16] = { '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , 'A' , 'B' , 'C' , 'D' , 'E' , 'F' };
void kvi_encodeFileName(KviStr & path)
{
TQString szPath(path.ptr());
kvi_encodeFileName(szPath);
path=szPath;
}
void kvi_encodeFileName(TQString & path)
{
TQString src(path);
path="";
for(int i=0;i<src.length();i++)
{
TQChar cur=src[i];
if( ! (cur.isLetter() || cur.isDigit() || cur==' ' || cur=='_' || cur=='.' || cur=='#' || cur=='%') )
{
if(cur.row()!=0)
{
path+='%';
path+=hexchars[cur.row() >> 4];
path+=hexchars[cur.row() & 15];
}
path+='%';
path+=hexchars[cur.cell() >> 4];
path+=hexchars[cur.cell() & 15];
} else if (cur=='%')
{
path+="%%";
} else {
path+=cur;
}
}
}
//================ kvi_isAbsolutePath ===============//
bool kvi_isAbsolutePath(const char *path)
{
if(*path == '/')return true;
if(isalpha(*path))
{
if((*(path + 1)) == ':')return true;
}
return false;
}
//=================== kvi_readLine =====================//
bool kvi_readLine(TQFile *f,KviStr &str)
{
TQTextStream stream(f);
TQString szBuff=stream.readLine();
str=szBuff;
return szBuff.isNull() ? 1 : 0;
}