⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qtsslsocket.cpp

📁 Qtopia下的邮件处理程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 2000-2006 TROLLTECH ASA. All rights reserved.**** This file is part of the Phone Edition of the Qtopia Toolkit.**** Licensees holding a valid license agreement from Trolltech or any of its** authorized distributors may use this file in accordance with** the License Agreement provided with the Licensed Software.**** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for**   information about Trolltech's Commercial License Agreements.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.********** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************///#define QTSSLSOCKET_DEBUG#include "qtsslsocket.h"#include <QtCore/QDateTime>#include <QtCore/QDebug>#include <QtCore/QFile>#include <QtCore/QList>#include <QtCore/QStringList>#include <QtCore/QTimer>#include <QtNetwork/QHostAddress>#include <qtopia/qtopianamespace.h>// OpenSSL includes#include "ssllibrary.h"//#endifconst int SslReadBlockSize = 4096;#define SSL_ERRORSTR() lib->ERR_error_string(lib->ERR_get_error(), NULL)class QtRingBuffer{public:    QtRingBuffer(int growth = 4096);    int nextDataBlockSize() const;    char *readPointer() const;    void free(int bytes);    char *reserve(int bytes);    void truncate(int bytes);    bool isEmpty() const;    int getChar();    void putChar(char c);    void ungetChar(char c);    int size() const;    void clear();    int indexOf(char c) const;    int readLine(char *data, int maxLength);    bool canReadLine() const;private:    QList<QByteArray> buffers;    int head, tail;    int tailBuffer;    int basicBlockSize;    int bufferSize;};/*! \internal    Creates an empty ring buffer. The buffer will grow in steps of \a    growth as data is written to it.*/QtRingBuffer::QtRingBuffer(int growth)    : basicBlockSize(growth){    buffers << QByteArray();    clear();}/*! \internal    Returns the number of bytes that can be read in one operation. The    data is read from readPointer().*/int QtRingBuffer::nextDataBlockSize() const{    return (tailBuffer == 0 ? tail : buffers.at(0).size()) - head;}/*! \internal    Returns a pointer to where no more than nextDataBlockSize() bytes    of data can be read. Call free() to remove data after reading.*/char *QtRingBuffer::readPointer() const{    if (buffers.count() == 0)        return 0;    return const_cast<char *>(buffers[0].data()) + head;}/*! \internal    Removes \a bytes bytes from the front of the buffer. If \a bytes    is larger than the size of the buffer, the buffer is cleared.*/void QtRingBuffer::free(int bytes){    bufferSize -= bytes;    if (bufferSize < 0)        bufferSize = 0;    for (;;) {        int nextBlockSize = nextDataBlockSize();        if (bytes < nextBlockSize) {            head += bytes;            if (head == tail && tailBuffer == 0)                head = tail = 0;            return;        }        bytes -= nextBlockSize;        if (buffers.count() == 1) {            if (buffers.at(0).size() != basicBlockSize)                buffers[0].resize(basicBlockSize);            head = tail = 0;            tailBuffer = 0;            return;        }        buffers.removeAt(0);        --tailBuffer;        head = 0;    }}/*! \internal    Reserves space in the buffer for \a bytes new bytes, and returns a    pointer to the first byte.*/char *QtRingBuffer::reserve(int bytes){    bufferSize += bytes;    // if there is already enough space, simply return.    if (tail + bytes <= buffers.at(tailBuffer).size()) {        char *writePtr = buffers[tailBuffer].data() + tail;        tail += bytes;        return writePtr;    }    // if our buffer isn't half full yet, simply resize it.    if (tail < buffers.at(tailBuffer).size() / 2) {        buffers[tailBuffer].resize(tail + bytes);        char *writePtr = buffers[tailBuffer].data() + tail;        tail += bytes;        return writePtr;    }    // shrink this buffer to its current size    buffers[tailBuffer].resize(tail);    // create a new QByteArray with the right size    buffers << QByteArray();    ++tailBuffer;    buffers[tailBuffer].resize(qMax(basicBlockSize, bytes));    tail = bytes;    return buffers[tailBuffer].data();}/*! \internal    Removes \a bytes bytes from the end of the buffer. If \a bytes is    larger than the buffer size, the buffer is cleared.*/void QtRingBuffer::truncate(int bytes){    bufferSize -= bytes;    if (bufferSize < 0)        bufferSize = 0;    for (;;) {        // special case: head and tail are in the same buffer        if (tailBuffer == 0) {            tail -= bytes;            if (tail <= head)                tail = head = 0;            return;        }        if (bytes <= tail) {            tail -= bytes;            return;        }        bytes -= tail;        buffers.removeAt(tailBuffer);        --tailBuffer;        tail = buffers.at(tailBuffer).size();    }}/*! \internal    Returns and removes the first character in the buffer. Returns -1    if the buffer is empty.*/int QtRingBuffer::getChar(){    if (isEmpty())       return -1;    char c = *readPointer();    free(1);    return c;}/*! \internal    Appends the character \a c to the end of the buffer.*/void QtRingBuffer::putChar(char c){    char *ptr = reserve(1);    *ptr = c;}/*! \internal    Prepends the character \a c to the front of the buffer.*/void QtRingBuffer::ungetChar(char c){    --head;    if (head < 0) {        buffers.prepend(QByteArray());        buffers[0].resize(basicBlockSize);        head = basicBlockSize - 1;        ++tailBuffer;    }    buffers[0][head] = c;    ++bufferSize;}/*! \internal    Returns the size of the buffer; e.g. the number of bytes    currently in use.*/int QtRingBuffer::size() const{    return bufferSize;}/*! \internal    Removes all data from the buffer and resets its size to 0.*/void QtRingBuffer::clear(){    QByteArray tmp = buffers[0];    buffers.clear();    buffers << tmp;    if (buffers.at(0).size() != basicBlockSize)        buffers[0].resize(basicBlockSize);    head = tail = 0;    tailBuffer = 0;    bufferSize = 0;}/*! \internal    Returns true if the buffer is empty; otherwise returns false.*/bool QtRingBuffer::isEmpty() const{    return tailBuffer == 0 && tail == 0;}/*! \internal    Returns the index of the first occurrence of the character \a c in    the buffer. In no such character is found, -1 is returned.*/int QtRingBuffer::indexOf(char c) const{    int index = 0;    for (int i = 0; i < buffers.size(); ++i) {        int start = 0;        int end = buffers.at(i).size();        if (i == 0)            start = head;        if (i == tailBuffer)            end = tail;        const char *ptr = buffers.at(i).data() + start;        for (int j = start; j < end; ++j) {            if (*ptr++ == c)                return index;            ++index;        }    }    return -1;}/*! \internal    Reads one line of data (all data up to and including the '\\n'    character), no longer than \a maxSize - 1 bytes, and stores it in \a    data. If the line is too long, maxSize bytes of the line are read.    \a data is always terminated by a '\\0' byte.*/int QtRingBuffer::readLine(char *data, int maxSize){    int index = indexOf('\n');    if (index == -1 || maxSize <= 0)        return -1;    int readSoFar = 0;    while (readSoFar < index && readSoFar < maxSize - 1) {        int bytesToRead = qMin((index + 1) - readSoFar, nextDataBlockSize());        bytesToRead = qMin(bytesToRead, (maxSize - 1) - readSoFar);        memcpy(data + readSoFar, readPointer(), bytesToRead);        readSoFar += bytesToRead;        free(bytesToRead);    }    // Terminate it.    data[readSoFar] = '\0';    return readSoFar;}/*! \internal    Returns true if a line can be read from the buffer; otherwise    returns false.*/bool QtRingBuffer::canReadLine() const{    return indexOf('\n') != -1;}class QtSslSocketPrivate{public:    QtSslSocketPrivate(QtSslSocket *qq);    void initializeConnection(QTcpSocket *socket);    QtRingBuffer readBuffer;    QtRingBuffer writeBuffer;    bool connectionSecured;    QTcpSocket *socket;    QtSslSocket::Mode mode;    bool initialized;    bool calledWriteToSocket;    bool readyReadEmitted;    // SSL context    SSL *ssl;    SSL_CTX *ctx;    BIO *rbio;    BIO *wbio;    QString cert;    QString certDir;    QString key;    QString cafile;    QString cadir;    QString ciph;    QtSslSocket *q;};QtSslSocketPrivate::QtSslSocketPrivate(QtSslSocket *qq)    : connectionSecured(false), socket(0), mode(QtSslSocket::Client),      initialized(false), calledWriteToSocket(false),      readyReadEmitted(false), ssl(0), ctx(0), rbio(0), wbio(0),      q(qq){}void QtSslSocketPrivate::initializeConnection(QTcpSocket *socket){    socket->disconnect();    QObject::connect(socket, SIGNAL(connected()),                     q, SLOT(sslConnect()));    QObject::connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),                     q, SLOT(handleSocketError(QAbstractSocket::SocketError)));    QObject::connect(socket, SIGNAL(disconnected()),                     q, SIGNAL(disconnected()));    QObject::connect(socket, SIGNAL(readyRead()),                     q, SLOT(readFromSocket()));    QObject::connect(socket, SIGNAL(bytesWritten(qint64)),                     q, SLOT(socketBytesWritten(qint64)));}/*!    \class QtSslSocket    \brief The QtSslSocket class provides a TCP socket with SSL    encryption support.    It provides some extra functionality which is needed for working    with SSL, but otherwise there is no difference from    QTcpSocket. Example:    \code    void MyClient::connectToHost(const QString &host, int port)    {        // Create a new SSL socket        socket = new QtSslSocket();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -