File indexing completed on 2024-04-28 05:42:11
0001 /*************************************************************************** 0002 * Copyright (C) 2006-2009 by Rajko Albrecht * 0003 * ral@alwins-world.de * 0004 * * 0005 * This program is free software; you can redistribute it and/or * 0006 * modify it under the terms of the GNU Lesser General Public * 0007 * License as published by the Free Software Foundation; either * 0008 * version 2.1 of the License, or (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 0013 * Lesser General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU Lesser General Public * 0016 * License along with this program (in the file LGPL.txt); if not, * 0017 * write to the Free Software Foundation, Inc., 51 Franklin St, * 0018 * Fifth Floor, Boston, MA 02110-1301 USA * 0019 * * 0020 * This software consists of voluntary contributions made by many * 0021 * individuals. For exact contribution history, see the revision * 0022 * history and logs, available at https://commits.kde.org/kdesvn. * 0023 ***************************************************************************/ 0024 #include "svnstream.h" 0025 0026 #include "apr.h" 0027 #include "pool.h" 0028 0029 // Subversion api 0030 #include <svn_client.h> 0031 0032 #include <QBuffer> 0033 #include <QElapsedTimer> 0034 0035 namespace svn 0036 { 0037 0038 namespace stream 0039 { 0040 class SVNQT_NOEXPORT SvnStream_private 0041 { 0042 public: 0043 SvnStream_private() 0044 { 0045 m_Stream = nullptr; 0046 _context = nullptr; /*cancel_timeout.start();*/ 0047 } 0048 ~SvnStream_private() 0049 { 0050 /*qDebug("Time elapsed: %i ",cancel_timeout.elapsed());*/ 0051 } 0052 0053 static svn_error_t *stream_write(void *baton, const char *data, apr_size_t *len); 0054 static svn_error_t *stream_read(void *baton, char *data, apr_size_t *len); 0055 0056 Pool m_Pool; 0057 svn_stream_t *m_Stream; 0058 QString m_LastError; 0059 0060 svn_client_ctx_t *_context; 0061 QElapsedTimer cancel_timeout; 0062 }; 0063 0064 svn_error_t *SvnStream_private::stream_read(void *baton, char *data, apr_size_t *len) 0065 { 0066 SvnStream *b = (SvnStream *)baton; 0067 svn_client_ctx_t *ctx = b->context(); 0068 0069 if (ctx && ctx->cancel_func) { 0070 SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); 0071 } 0072 0073 long res = b->isOk() ? b->read(data, *len) : -1; 0074 0075 if (res < 0) { 0076 *len = 0; 0077 return svn_error_create(SVN_ERR_MALFORMED_FILE, nullptr, b->lastError().toUtf8()); 0078 } 0079 *len = res; 0080 return SVN_NO_ERROR; 0081 } 0082 0083 svn_error_t *SvnStream_private::stream_write(void *baton, const char *data, apr_size_t *len) 0084 { 0085 SvnStream *b = (SvnStream *)baton; 0086 svn_client_ctx_t *ctx = b->context(); 0087 0088 if (ctx && ctx->cancel_func && b->cancelElapsed() > 50) { 0089 // qDebug("Check cancel"); 0090 SVN_ERR(ctx->cancel_func(ctx->cancel_baton)); 0091 b->cancelTimeReset(); 0092 } 0093 0094 long res = b->isOk() ? b->write(data, *len) : -1; 0095 if (res < 0) { 0096 *len = 0; 0097 return svn_error_create(SVN_ERR_MALFORMED_FILE, nullptr, b->lastError().toUtf8()); 0098 } 0099 *len = res; 0100 return SVN_NO_ERROR; 0101 } 0102 0103 SvnStream::SvnStream(bool read, bool write, svn_client_ctx_t *ctx) 0104 { 0105 m_Data = new SvnStream_private; 0106 m_Data->m_Stream = svn_stream_create(this, m_Data->m_Pool); 0107 m_Data->_context = ctx; 0108 if (read) { 0109 svn_stream_set_read(m_Data->m_Stream, SvnStream_private::stream_read); 0110 } 0111 if (write) { 0112 svn_stream_set_write(m_Data->m_Stream, SvnStream_private::stream_write); 0113 } 0114 } 0115 0116 SvnStream::~SvnStream() 0117 { 0118 delete m_Data; 0119 } 0120 0121 int SvnStream::cancelElapsed() const 0122 { 0123 return m_Data->cancel_timeout.elapsed(); 0124 } 0125 0126 void SvnStream::cancelTimeReset() 0127 { 0128 m_Data->cancel_timeout.restart(); 0129 } 0130 0131 SvnStream::operator svn_stream_t *() const 0132 { 0133 return m_Data->m_Stream; 0134 } 0135 0136 svn_client_ctx_t *SvnStream::context() 0137 { 0138 return m_Data->_context; 0139 } 0140 0141 long SvnStream::write(const char *, const unsigned long) 0142 { 0143 m_Data->m_LastError = QLatin1String("Write not supported with that stream"); 0144 return -1; 0145 } 0146 0147 long SvnStream::read(char *, const unsigned long) 0148 { 0149 m_Data->m_LastError = QLatin1String("Read not supported with that stream"); 0150 return -1; 0151 } 0152 0153 const QString &SvnStream::lastError() const 0154 { 0155 return m_Data->m_LastError; 0156 } 0157 0158 void SvnStream::setError(const QString &aError) const 0159 { 0160 m_Data->m_LastError = aError; 0161 } 0162 0163 /* ByteStream implementation start */ 0164 SvnByteStream::SvnByteStream(svn_client_ctx_t *ctx) 0165 : SvnStream(false, true, ctx) 0166 , m_ByteData(new QBuffer) 0167 { 0168 m_ByteData->open(QIODevice::ReadWrite); 0169 if (!m_ByteData->isOpen()) { 0170 setError(m_ByteData->errorString()); 0171 } 0172 } 0173 0174 SvnByteStream::~SvnByteStream() 0175 { 0176 delete m_ByteData; 0177 } 0178 0179 long SvnByteStream::write(const char *aData, const unsigned long max) 0180 { 0181 qint64 i = m_ByteData->write(aData, max); 0182 if (i < 0) { 0183 setError(m_ByteData->errorString()); 0184 } 0185 return i; 0186 } 0187 0188 QByteArray SvnByteStream::content() const 0189 { 0190 return m_ByteData->buffer(); 0191 } 0192 0193 bool SvnByteStream::isOk() const 0194 { 0195 return m_ByteData->isOpen(); 0196 } 0197 0198 /* ByteStream implementation end */ 0199 0200 } // namespace stream 0201 0202 } // namespace svn