diff options
Diffstat (limited to 'vcs/cvsservice/cvsdir.cpp')
-rw-r--r-- | vcs/cvsservice/cvsdir.cpp | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/vcs/cvsservice/cvsdir.cpp b/vcs/cvsservice/cvsdir.cpp new file mode 100644 index 00000000..2b7602e6 --- /dev/null +++ b/vcs/cvsservice/cvsdir.cpp @@ -0,0 +1,321 @@ +/*************************************************************************** + * Copyright (C) 2003 by Mario Scalas * + * mario.scalas@libero.it * + * * + * 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 option) any later version. * + * * + ***************************************************************************/ + +#include <qfile.h> +#include <qtextstream.h> + +#include "cvsdir.h" + +/////////////////////////////////////////////////////////////////////////////// +// class CVSDir +/////////////////////////////////////////////////////////////////////////////// + +CVSDir::CVSDir() : QDir() +{ +} + +/////////////////////////////////////////////////////////////////////////////// + +CVSDir::CVSDir( const QDir &dir ) + : QDir( dir ) +{ + // We deal with absolute paths only + convertToAbs(); + + m_cvsDir = absPath() + QDir::separator() + "CVS"; + + if (isValid()) + refreshEntriesCache(); +} + +/////////////////////////////////////////////////////////////////////////////// + +CVSDir::CVSDir( const CVSDir &aCvsDir ) + : QDir( aCvsDir ) +{ + *this = aCvsDir; +} + +/////////////////////////////////////////////////////////////////////////////// + +CVSDir &CVSDir::operator=( const CVSDir &aCvsDir ) +{ + m_cvsDir = aCvsDir.m_cvsDir; + m_cachedEntries = aCvsDir.m_cachedEntries; + QDir::operator=( aCvsDir ); + + return *this; +} + +/////////////////////////////////////////////////////////////////////////////// + +CVSDir::~CVSDir() +{ +} + +/////////////////////////////////////////////////////////////////////////////// + +bool CVSDir::isValid() const +{ + return exists() && + QFile::exists( entriesFileName() ) && + QFile::exists( rootFileName() ) && + QFile::exists( repoFileName() ); +} + +/////////////////////////////////////////////////////////////////////////////// + +QString CVSDir::entriesFileName() const +{ + return m_cvsDir + QDir::separator() + "Entries"; +} + +/////////////////////////////////////////////////////////////////////////////// + +QString CVSDir::rootFileName() const +{ + return m_cvsDir + QDir::separator() + "Root"; +} + +/////////////////////////////////////////////////////////////////////////////// + +QString CVSDir::repoFileName() const +{ + return m_cvsDir + QDir::separator() + "Repository"; +} + +/////////////////////////////////////////////////////////////////////////////// + +QString CVSDir::cvsIgnoreFileName() const +{ + return absPath() + QDir::separator() + ".cvsignore"; +} + +/////////////////////////////////////////////////////////////////////////////// + +QString CVSDir::repository() const +{ + // The content of CVS/Repository is a single line with the path into the + // repository of the modules checked out in this directory (just like + // "kdevelop/parts/cvsservice"): so we can read a single line of the file + // and we are done! + QString content; + + if (!isValid()) + return QString::null; + + QByteArray bytes = cacheFile( repoFileName() ); + QTextStream t( bytes, IO_ReadOnly ); + content += t.readLine(); + + return content; +} + +/////////////////////////////////////////////////////////////////////////////// + +QString CVSDir::root() const +{ + // Same as CVSDir::repository() but CVS/Root contains the path of the + // CVS server as used in "cvs -d <server-path>" (in example: + // ":pserver:marios@cvs.kde.org:/home/kde") + QString content; + + if (!isValid()) + return QString::null; + + QByteArray bytes = cacheFile( repoFileName() ); + QTextStream t( bytes, IO_ReadOnly ); + content += t.readLine(); + + return content; +} + +/////////////////////////////////////////////////////////////////////////////// + +QByteArray CVSDir::cacheFile( const QString &fileName ) +{ + QFile f( fileName ); + if (!f.open( IO_ReadOnly )) + return QByteArray(); + return f.readAll(); +} + +/////////////////////////////////////////////////////////////////////////////// + +QStringList CVSDir::registeredEntryList() const +{ + QStringList l; + if (!isValid()) + return l; + + QByteArray bytes = cacheFile( entriesFileName() ); + QTextStream t( bytes, IO_ReadOnly ); + CVSEntry entry; + while (!t.eof()) + { + QString line = t.readLine(); + entry.parse( line, *this ); + if (entry.isValid()) + l.append( entry.fileName() ); + } + return l; +} + +/////////////////////////////////////////////////////////////////////////////// + +bool CVSDir::isRegistered( const QString fileName ) const +{ + CVSEntry entry = fileStatus( fileName ); + return entry.isValid() && entry.fileName() == fileName; +} + +/////////////////////////////////////////////////////////////////////////////// + +void CVSDir::refreshEntriesCache() const +{ + m_cachedEntries.clear(); + + QByteArray bytes = cacheFile( entriesFileName() ); + QTextStream t( bytes, IO_ReadOnly ); + CVSEntry entry; + while (!t.eof()) + { + QString line = t.readLine(); + entry.parse( line, *this ); + if (entry.isValid()) + m_cachedEntries[ entry.fileName() ] = entry; + } +} + +/////////////////////////////////////////////////////////////////////////////// + +CVSEntry CVSDir::fileStatus( const QString &fileName, bool refreshCache ) const +{ + if (refreshCache) + refreshEntriesCache(); + + if (m_cachedEntries.contains( fileName )) + { + return m_cachedEntries[ fileName ]; + } + else + return CVSEntry( fileName, *this ); // Just the file name +} + +/////////////////////////////////////////////////////////////////////////////// + +void CVSDir::ignoreFile( const QString &fileName ) +{ + if (!isValid()) + return; + + QFile f( cvsIgnoreFileName() ); + if (!f.open( IO_ReadOnly)) + return; + + QByteArray cachedFile = f.readAll(); + QTextStream t( cachedFile, IO_ReadOnly | IO_WriteOnly ); + + QString readFileName; + bool found = false; + + while (!t.eof() && !found) + { + readFileName = t.readLine(); + found = (fileName == readFileName); + } + + f.close(); + if (!found) + { + f.open( IO_WriteOnly ); + + t << fileName << "\n"; + + f.writeBlock( cachedFile ); + f.close(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +void CVSDir::doNotIgnoreFile( const QString &fileName ) +{ + if (!isValid()) + return; + + // 1. Read all .ignore file in memory + QFile f( cvsIgnoreFileName() ); + if (!f.open( IO_ReadOnly )) + return; // No .cvsignore file? Nothing to do then! + + QByteArray cachedFile = f.readAll(); + QTextIStream is( cachedFile ); + + QByteArray cachedOutputFile; + QTextOStream os( cachedOutputFile ); + + bool removed = false; + while (!is.eof()) + { + QString readLine = is.readLine(); + if (readLine != fileName) + os << readLine << "\n"; // QTextStream::readLine() eats the "\n" ... + else + removed = true; + } + + f.close(); + if (removed) + { + f.open( IO_WriteOnly ); + f.writeBlock( cachedOutputFile ); + f.close(); + } +} + +/////////////////////////////////////////////////////////////////////////////// + +VCSFileInfoMap CVSDir::dirStatus() const +{ + VCSFileInfoMap vcsInfo; + /// Convert to VCSFileInfoMap: \FIXME : any speed improvement here? + QStringList entries = registeredEntryList(); + QStringList::const_iterator it = entries.begin(), end = entries.end(); + for ( ; it != end; ++it) + { + const QString &fileName = (*it); + const CVSEntry entry = fileStatus( fileName ); + + vcsInfo.insert( fileName, entry.toVCSFileInfo() ); + } + + return vcsInfo; +} + +/////////////////////////////////////////////////////////////////////////////// + +VCSFileInfoMap *CVSDir::cacheableDirStatus() const +{ + VCSFileInfoMap *vcsInfo = new VCSFileInfoMap; + /// Convert to VCSFileInfoMap: \FIXME : any speed improvement here? + QStringList entries = registeredEntryList(); + QStringList::const_iterator it = entries.begin(), end = entries.end(); + for ( ; it != end; ++it) + { + const QString &fileName = (*it); + const CVSEntry entry = fileStatus( fileName ); + + vcsInfo->insert( fileName, entry.toVCSFileInfo() ); + } + + return vcsInfo; +} |