예제 #1
0
bool LiteEditorFile::open(const QString &fileName, const QString &mimeType, bool bCheckCodec)
{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly)) {
        return false;
    }
    const QFileInfo fi(fileName);
    m_bReadOnly = !fi.isWritable();

    m_mimeType = mimeType;
    m_fileName = fileName;

    QByteArray buf = file.readAll();
    m_hasDecodingError = false;

    if (bCheckCodec) {
        if (mimeType == "text/html" || mimeType == "text/xml") {
            m_codec = QTextCodec::codecForHtml(buf,QTextCodec::codecForName("utf-8"));
        } else {
            LiteApi::IMimeType *im = m_liteApp->mimeTypeManager()->findMimeType(mimeType);
            if (im) {
                QString codecName = im->codec();
                if (!codecName.isEmpty()) {
                    m_codec = QTextCodec::codecForName(codecName.toAscii());
                }
            }
            int bytesRead = buf.size();
            QTextCodec *codec = m_codec;
            // code taken from qtextstream
            if (bytesRead >= 4 && ((uchar(buf[0]) == 0xff && uchar(buf[1]) == 0xfe && uchar(buf[2]) == 0 && uchar(buf[3]) == 0)
                                   || (uchar(buf[0]) == 0 && uchar(buf[1]) == 0 && uchar(buf[2]) == 0xfe && uchar(buf[3]) == 0xff))) {
                codec = QTextCodec::codecForName("UTF-32");
            } else if (bytesRead >= 2 && ((uchar(buf[0]) == 0xff && uchar(buf[1]) == 0xfe)
                                          || (uchar(buf[0]) == 0xfe && uchar(buf[1]) == 0xff))) {
                codec = QTextCodec::codecForName("UTF-16");
            } else if (bytesRead >= 3 && uchar(buf[0]) == 0xef && uchar(buf[1]) == 0xbb && uchar(buf[2])== 0xbf) {
                codec = QTextCodec::codecForName("UTF-8");
            } else if (!codec) {
                codec = QTextCodec::codecForLocale();
            }
            // end code taken from qtextstream
            m_codec = codec;
        }
    }


    QTextCodec::ConverterState state;
    QString text = m_codec->toUnicode(buf,buf.size(),&state);
    if (state.invalidChars > 0 || state.remainingChars > 0) {
        m_hasDecodingError = true;
    }
    //qDebug() << state.invalidChars << state.remainingChars;

/*
    QByteArray verifyBuf = m_codec->fromUnicode(text); // slow
    // the minSize trick lets us ignore unicode headers
    int minSize = qMin(verifyBuf.size(), buf.size());
    m_hasDecodingError = (minSize < buf.size()- 4
                          || memcmp(verifyBuf.constData() + verifyBuf.size() - minSize,
                                    buf.constData() + buf.size() - minSize, minSize));
*/
    /*
    if (text.length()*2+4 < buf.length()) {
        m_hasDecodingError = true;
    }
    */

    int lf = text.indexOf('\n');
    if (lf < 0) {
        m_lineTerminatorMode = NativeLineTerminator;
    } else if (lf == 0) {
        m_lineTerminatorMode = LFLineTerminator;
    } else {
        lf = text.indexOf(QRegExp("[^\r]\n"),lf-1);
        if (lf >= 0) {
            m_lineTerminatorMode = LFLineTerminator;
        } else {
            m_lineTerminatorMode = CRLFLineTerminator;
        }
    }
    bool noprintCheck = m_liteApp->settings()->value(EDITOR_NOPRINTCHECK,true).toBool();
    if (noprintCheck) {
        for (int i = 0; i < text.length(); i++) {
            if (!text[i].isPrint() && !text[i].isSpace() && text[i] != '\r' && text[i] != '\n') {
                text[i] = '.';
                m_hasDecodingError = true;
            }
        }
    }

    m_document->setPlainText(text);
    return true;
}
예제 #2
0
bool LiteEditorFile::loadFileHelper(const QString &fileName, const QString &mimeType, bool bCheckCodec, QString &outText)
{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly)) {
        return false;
    }
    const QFileInfo fi(fileName);
    m_bReadOnly = !fi.isWritable();

    m_mimeType = mimeType;
    m_fileName = fileName;

    if (file.size() > (3 << 24)) {
        m_liteApp->appendLog("LiteEditor","Large file not open in the text editor! "+fileName,true);
        m_hasDecodingError = true;
        return false;
    }

    QByteArray buf = file.readAll();
    m_hasDecodingError = false;

    if (HasBinaryData(buf,32)) {
        m_liteApp->appendLog("LiteEditor","Binary file not open in the text editor! "+fileName,true);
        m_hasDecodingError = true;
        //outText = "error load binary file!!!";
        return false;
    }

    if (bCheckCodec) {
        m_codec = QTextCodec::codecForName("UTF-8");
        m_hasUtf8Bom = false;

        if (mimeType == "text/html" || mimeType == "text/xml") {
            m_codec = QTextCodec::codecForHtml(buf,QTextCodec::codecForName("utf-8"));
        } else {
            LiteApi::IMimeType *im = m_liteApp->mimeTypeManager()->findMimeType(mimeType);
            if (im) {
                QString codecName = im->codec();
                if (!codecName.isEmpty()) {
                    m_codec = QTextCodec::codecForName(codecName.toLatin1());
                }
            }
            int bytesRead = buf.size();
            QTextCodec *codec = m_codec;
            // code taken from qtextstream
            if (bytesRead >= 4 && ((uchar(buf[0]) == 0xff && uchar(buf[1]) == 0xfe && uchar(buf[2]) == 0 && uchar(buf[3]) == 0)
                                   || (uchar(buf[0]) == 0 && uchar(buf[1]) == 0 && uchar(buf[2]) == 0xfe && uchar(buf[3]) == 0xff))) {
                codec = QTextCodec::codecForName("UTF-32");
            } else if (bytesRead >= 2 && ((uchar(buf[0]) == 0xff && uchar(buf[1]) == 0xfe)
                                          || (uchar(buf[0]) == 0xfe && uchar(buf[1]) == 0xff))) {
                codec = QTextCodec::codecForName("UTF-16");
            } else if (bytesRead >= 3 && uchar(buf[0]) == 0xef && uchar(buf[1]) == 0xbb && uchar(buf[2])== 0xbf) {
                codec = QTextCodec::codecForName("UTF-8");
                buf.remove(0,3);
                m_hasUtf8Bom = true;
            } else if (!codec){
                codec = QTextCodec::codecForLocale();
            }
            // end code taken from qtextstream
            m_codec = codec;
        }
    }

    QTextCodec::ConverterState state;
    outText = m_codec->toUnicode(buf,buf.size(),&state);
    if (state.invalidChars > 0 || state.remainingChars > 0) {
         m_hasDecodingError = true;
    }
    if (m_hasDecodingError && bCheckCodec) {
        QByteArray testName = m_libucd.parse(buf);
        if (!testName.isEmpty()) {
            QTextCodec *c = QTextCodec::codecForName(testName);
            if (c && (c->mibEnum() != m_codec->mibEnum()) ) {
                QTextCodec::ConverterState testState;
                QString testText = c->toUnicode(buf,buf.size(),&testState);
                if (testState.invalidChars == 0 && testState.remainingChars == 0) {
                    m_hasDecodingError = false;
                    m_codec = c;
                    outText = testText;
                }
            }
        }
    }
/*
    QByteArray verifyBuf = m_codec->fromUnicode(text); // slow
    // the minSize trick lets us ignore unicode headers
    int minSize = qMin(verifyBuf.size(), buf.size());
    m_hasDecodingError = (minSize < buf.size()- 4
                          || memcmp(verifyBuf.constData() + verifyBuf.size() - minSize,
                                    buf.constData() + buf.size() - minSize, minSize));
*/
    /*
    if (text.length()*2+4 < buf.length()) {
        m_hasDecodingError = true;
    }
    */

    int lf = outText.indexOf('\n');
    if (lf < 0) {
        m_lineTerminatorMode = NativeLineTerminator;
    } else if (lf == 0) {
        m_lineTerminatorMode = LFLineTerminator;
    } else {
        lf = outText.indexOf(QRegExp("[^\r]\n"),lf-1);
        if (lf >= 0) {
            m_lineTerminatorMode = LFLineTerminator;
        } else {
            m_lineTerminatorMode = CRLFLineTerminator;
        }
    }

    if (m_lineTerminatorMode == CRLFLineTerminator) {
        outText.replace("\r\n","\n");
    }

    bool noprintCheck = m_liteApp->settings()->value(EDITOR_NOPRINTCHECK,true).toBool();
    if (noprintCheck && !LiteApi::mimeIsText(mimeType)) {
        for (int i = 0; i < outText.length(); i++) {
//            if (!outText[i].isPrint() && !outText[i].isSpace() && outText[i] != '\r' && outText[i] != '\n') {
//                outText[i] = '.';
//                m_hasDecodingError = true;
//            }
            if (IsBinaryCode(outText[i].unicode())) {
                outText[i] = '.';
                m_hasDecodingError = true;
            }
        }
    }

    if (m_hasDecodingError) {
        m_liteApp->appendLog("LiteEditor",QString("Decode file error! file:\"%1\" codec:%2").arg(fileName).arg(textCodec()),true);
    }

    return true;
}