diff options
Diffstat (limited to 'src/svnqt/svnstream.cpp')
-rw-r--r-- | src/svnqt/svnstream.cpp | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/src/svnqt/svnstream.cpp b/src/svnqt/svnstream.cpp new file mode 100644 index 0000000..e3b6014 --- /dev/null +++ b/src/svnqt/svnstream.cpp @@ -0,0 +1,263 @@ +/*************************************************************************** + * Copyright (C) 2006-2007 by Rajko Albrecht * + * [email protected] * + * * + * 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. * + * * + * 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. * + ***************************************************************************/ +#include "svnqt/svnstream.hpp" +#include "svnqt/pool.hpp" +#include "svnqt/apr.hpp" + +// Subversion api +#include "svn_client.h" + +#include <qbuffer.h> +#include <qdatetime.h> +#include <qfile.h> + +#define MAX_TIME 300 + +namespace svn { + +namespace stream { +class SVNQT_NOEXPORT SvnStream_private +{ +public: + SvnStream_private(){m_Stream=0;m_LastError="";_context=0;cancel_timeout.start();} + ~SvnStream_private(){qDebug("Time elapsed: %i ",cancel_timeout.elapsed());} + + static svn_error_t * stream_write(void*baton,const char*data,apr_size_t*len); + static svn_error_t * stream_read(void*baton,char*data,apr_size_t*len); + + Pool m_Pool; + svn_stream_t * m_Stream; + QString m_LastError; + + svn_client_ctx_t* _context; + QTime cancel_timeout; +}; + +svn_error_t * SvnStream_private::stream_read(void*baton,char*data,apr_size_t*len) +{ + SvnStream*b = (SvnStream*)baton; + svn_client_ctx_t*ctx = b->context(); + + if (ctx&&ctx->cancel_func) { + SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); + } + + long res = b->isOk()?b->read(data,*len):-1; + + if (res<0) { + *len = 0; + return svn_error_create(SVN_ERR_MALFORMED_FILE,0L,b->lastError().TOUTF8()); + } + *len = res; + return SVN_NO_ERROR; +} + +svn_error_t * SvnStream_private::stream_write(void*baton,const char*data,apr_size_t*len) +{ + SvnStream*b = (SvnStream*)baton; + svn_client_ctx_t*ctx = b->context(); + + if (ctx&&ctx->cancel_func&&b->cancelElapsed()>50) { + qDebug("Check cancel"); + SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); + b->cancelTimeReset(); + } + + long res = b->isOk()?b->write(data,*len):-1; + if (res<0) { + *len = 0; + return svn_error_create(SVN_ERR_MALFORMED_FILE,0L,b->lastError().TOUTF8()); + } + *len = res; + return SVN_NO_ERROR; +} + +SvnStream::SvnStream(bool read, bool write,svn_client_ctx_t * ctx) +{ + m_Data = new SvnStream_private; + m_Data->m_Stream = svn_stream_create(this,m_Data->m_Pool); + m_Data->_context = ctx; + if (read) { + svn_stream_set_read(m_Data->m_Stream,SvnStream_private::stream_read); + } + if (write) { + svn_stream_set_write(m_Data->m_Stream,SvnStream_private::stream_write); + } +} + +SvnStream::SvnStream() +{ +} + +SvnStream::~SvnStream() +{ + delete m_Data; +} + +int SvnStream::cancelElapsed()const +{ + return m_Data->cancel_timeout.elapsed(); +} + +void SvnStream::cancelTimeReset() +{ + m_Data->cancel_timeout.restart(); +} + +SvnStream::operator svn_stream_t* ()const +{ + return m_Data->m_Stream; +} + +svn_client_ctx_t * SvnStream::context() +{ + return m_Data->_context; +} + +long SvnStream::write(const char*,const unsigned long) +{ + m_Data->m_LastError = "Write not supported with that stream"; + return -1; +} + +long SvnStream::read(char*,const unsigned long ) +{ + m_Data->m_LastError = "Read not supported with that stream"; + return -1; +} + +const QString&SvnStream::lastError()const +{ + return m_Data->m_LastError; +} + +void SvnStream::setError(const QString&aError)const +{ + m_Data->m_LastError = aError; +} + +#if QT_VERSION < 0x040000 +void SvnStream::setError(int ioError)const +{ + switch (ioError) { + case IO_Ok: + setError("Operation was successfull."); + break; + case IO_ReadError: + setError("Could not read from device"); + break; + case IO_WriteError: + setError("Could not write to device"); + break; + case IO_FatalError: + setError("A fatal unrecoverable error occurred."); + break; + case IO_OpenError: + setError("Could not open device or stream."); + break; + case IO_AbortError: + setError("The operation was unexpectedly aborted."); + break; + case IO_TimeOutError: + setError("The operation timed out."); + break; + case IO_UnspecifiedError: + setError("An unspecified error happened on close."); + break; + default: + setError("Unknown error happend."); + break; + } +} +#endif + +class SvnByteStream_private { +public: + SvnByteStream_private(); + virtual ~SvnByteStream_private(){} + + QByteArray m_Content; + QBuffer mBuf; +}; + +#if QT_VERSION < 0x040000 +SvnByteStream_private::SvnByteStream_private() + :mBuf(m_Content) +{ + mBuf.open(IO_WriteOnly); +} +#else +SvnByteStream_private::SvnByteStream_private() + :mBuf(&m_Content, 0) +{ + mBuf.open(QFile::WriteOnly); +} +#endif + +/* ByteStream implementation start */ +SvnByteStream::SvnByteStream(svn_client_ctx_t * ctx) + : SvnStream(false,true,ctx) +{ + m_ByteData = new SvnByteStream_private; + if (!m_ByteData->mBuf.isOpen()) { +#if QT_VERSION < 0x040000 + setError(m_ByteData->mBuf.status()); +#else + setError(m_ByteData->mBuf.errorString()); +#endif + } +} + +SvnByteStream::~SvnByteStream() +{ + delete m_ByteData; +} + +long SvnByteStream::write(const char*aData,const unsigned long max) +{ +#if QT_VERSION < 0x040000 + long i = m_ByteData->mBuf.writeBlock(aData,max); + if (i<0) { + setError(m_ByteData->mBuf.status()); + } +#else + long i = m_ByteData->mBuf.write(aData,max); + if (i<0) { + setError(m_ByteData->mBuf.errorString()); + } +#endif + return i; +} + +QByteArray SvnByteStream::content()const +{ + return m_ByteData->mBuf.buffer(); +} + +bool SvnByteStream::isOk()const +{ + return m_ByteData->mBuf.isOpen(); +} + +/* ByteStream implementation end */ + +} // namespace stream + +} // namespace svn |