summaryrefslogtreecommitdiffstats
path: root/src/svnqt/svnstream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/svnqt/svnstream.cpp')
-rw-r--r--src/svnqt/svnstream.cpp263
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 *
+ * *
+ * 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