File indexing completed on 2024-05-26 05:56:26

0001 /*
0002     This file is part of the Okteta Kasten module, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2011 Friedrich W. H. Kossebau <kossebau@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0007 */
0008 
0009 #include "charsetconversionjob.hpp"
0010 
0011 // Okteta core
0012 #include <Okteta/AbstractByteArrayModel>
0013 #include <Okteta/CharCodec>
0014 #include <Okteta/Character>
0015 // Qt
0016 #include <QCoreApplication>
0017 
0018 namespace Kasten {
0019 
0020 static constexpr int CharsetConversionBlockSize = 100000;
0021 
0022 bool CharsetConversionJob::exec()
0023 {
0024     // reset
0025     mConvertedBytesCount = 0;
0026     mFailedPerByteCount.clear();
0027 
0028     // check
0029     if (!mByteArrayModel || !mRange.isValid()) {
0030         deleteLater(); // TODO: could be reused on next operation
0031 
0032         return false;
0033     }
0034 
0035     bool success = true;
0036     int r = 0;
0037     Okteta::Address i = mRange.start();
0038     Okteta::Address blockEnd = mRange.start();
0039     while (i <= mRange.end() && success) {
0040         blockEnd += CharsetConversionBlockSize;
0041         if (blockEnd > mRange.end()) {
0042             blockEnd = mRange.end();
0043         }
0044 
0045         for (; i <= blockEnd && success; ++i) {
0046             Okteta::Byte convertedByte;
0047             const Okteta::Byte originalByte = mByteArrayModel->byte(i);
0048             const Okteta::Character decodedChar = mSourceCharCodec->decode(originalByte);
0049             bool isConverted = !decodedChar.isUndefined();
0050             if (isConverted) {
0051                 isConverted = mTargetCharCodec->encode(&convertedByte, decodedChar);
0052             }
0053 
0054             if (!isConverted) {
0055                 if (!mSubstitutingMissingChars) {
0056                     success = false;
0057                     break;
0058                 }
0059                 mFailedPerByteCount[originalByte]++;
0060                 convertedByte = mSubstituteByte;
0061             }
0062 
0063             // TODO: means if the default byte equals a not convertable original
0064             // byte that one is not counted. okay, or should be made explicit to user?
0065             if (originalByte != convertedByte) {
0066                 mConvertedBytesCount++;
0067             }
0068 
0069             mResult[r++] = convertedByte;
0070         }
0071 
0072         QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers);
0073     }
0074 
0075     deleteLater(); // TODO: could be reused on next operation
0076 
0077     return success;
0078 }
0079 
0080 }
0081 
0082 #include "moc_charsetconversionjob.cpp"