bool Adler32ByteArrayChecksumAlgorithm::calculateChecksum( QString* result,
                                                           const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range ) const
{
    quint32 a = 1;
    quint32 b = 0;

    // TODO: this is the "inefficient but straightforward implementation" from the Wikipedia entry, search for improved
    Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit;
    for( Okteta::Address i = range.start(); i<=range.end(); ++i )
    {
        a = (a + model->byte( i )) % MOD_ADLER;
        b = (b + a) % MOD_ADLER;

        if( i >= nextBlockEnd )
        {
            nextBlockEnd += CalculatedByteCountSignalLimit;
            emit calculatedBytes( range.localIndex(i)+1 );
        }
    }

    const quint32 sum = (b << 16) | a;
    *result = QString::fromLatin1("%1").arg( sum, 8, 16, QChar::fromLatin1('0') );

    return true;
}
bool ByteArrayValuesStreamEncoder::encodeDataToStream( QIODevice *device,
                                                       const ByteArrayView* byteArrayView,
                                                       const Okteta::AbstractByteArrayModel* byteArrayModel,
                                                       const Okteta::AddressRange& range )
{
    bool success = true;

    // settings
    mSettings.undefinedChar = byteArrayView->undefinedChar();
    mSettings.substituteChar = byteArrayView->substituteChar();
    mSettings.valueCoding = (Okteta::ValueCoding)byteArrayView->valueCoding();

    // encode
    QTextStream textStream( device );

    Okteta::ValueCodec* valueCodec = Okteta::ValueCodec::createCodec( mSettings.valueCoding );

    // prepare 
    QString valueString;
    valueString.resize( valueCodec->encodingWidth() );

    for( Okteta::Address i=range.start(); i<=range.end(); ++i )
    {
        if( i > range.start() )
            textStream << mSettings.separation;

        valueCodec->encode( valueString, 0, byteArrayModel->byte(i) );

        textStream << valueString;
    }
    // clean up
    delete valueCodec;

    return success;
}
QString AbstractByteArrayStreamEncoder::previewData( AbstractModel* model, const AbstractModelSelection* selection )
{
    const ByteArrayView* byteArrayView = qobject_cast<const ByteArrayView*>( model );

    const ByteArrayDocument* byteArrayDocument =
        byteArrayView ? qobject_cast<const ByteArrayDocument*>( byteArrayView->baseModel() ) : 0;
    if( byteArrayDocument == 0 )
        return QString();

    const Okteta::AbstractByteArrayModel* byteArray = byteArrayDocument->content();

    const ByteArraySelection* byteArraySelection =
        selection ? static_cast<const ByteArraySelection*>( selection ) : 0;

    Okteta::AddressRange range = byteArraySelection && byteArraySelection->isValid() ?
        byteArraySelection->range() :
        Okteta::AddressRange::fromWidth( 0, byteArray->size() );
    range.restrictEndByWidth( MaxPreviewSize );

    QByteArray data;
    QBuffer dataBuffer( &data );
    dataBuffer.open( QIODevice::WriteOnly );

    const bool success = encodeDataToStream( &dataBuffer, byteArrayView, byteArray, range );
    dataBuffer.close();

    return success ? QString::fromLatin1(data) : QString();
}
quint16 ModSum16ByteArrayChecksumAlgorithm::calculateModSumWithBigEndian( const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range ) const
{
    quint16 modSum = 0x0000;
    Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit;

    // TODO: move padding checks into extra code before and after loop
    for( Okteta::Address i = range.start(); i<=range.end(); ++i )
    {
        quint16 value = (quint16)( (quint8)(model->byte( i )) ) << 8;
        ++i;
        if( i<=range.end() )
            value |= (quint16)( (quint8)(model->byte( i )) );

        modSum += value;
#if 0
        const uchar value = (crcBits & 0xFF) + model->byte( i );
        crcBits >>= 8;
        crcBits ^= lookupTable[value];
#endif
        if( i >= nextBlockEnd )
        {
            nextBlockEnd += CalculatedByteCountSignalLimit;
            emit calculatedBytes( range.localIndex(i)+1 );
        }
    }

    return modSum;
}
Exemple #5
0
ByteArrayView::ByteArrayView( ByteArrayView* other, ByteArrayViewProfileSynchronizer* synchronizer,
                              Qt::Alignment alignment )
    : AbstractView( static_cast<ByteArrayDocument*>(other->baseModel()) )
    , mDocument( static_cast<ByteArrayDocument*>(other->baseModel()) )
    , mByteArrayViewProfileSynchronizer( synchronizer )
{
    init();

    mWidget->setStartOffset( other->startOffset() );
    mWidget->setFirstLineOffset( other->firstLineOffset() );

    setViewModus( other->viewModus() );
    setVisibleByteArrayCodings( other->visibleByteArrayCodings() );
    toggleOffsetColumn( other->offsetColumnVisible() );
    setOffsetCoding( other->offsetCoding() );

    setCharCoding( other->charCodingName() );
    setShowsNonprinting( other->showsNonprinting() );
    setSubstituteChar( other->substituteChar() );
    setUndefinedChar( other->undefinedChar() );

    setValueCoding( other->valueCoding() );

    setNoOfGroupedBytes( other->noOfGroupedBytes() );
    setNoOfBytesPerLine( other->noOfBytesPerLine() );
    // TODO: this can lead to different layouts due to possible one-pixel difference in width!
    setLayoutStyle( other->layoutStyle() );

    const Okteta::AddressRange selection = other->selection();
    setSelection( selection.start(), selection.end() );
    setZoomLevel( other->zoomLevel() );
    setCursorPosition( other->cursorPosition() );

    setOverwriteMode( other->isOverwriteMode() );
    setReadOnly( other->isReadOnly() );
    // TODO: all width

    const QRect otherViewRect = other->mWidget->viewRect();

    QPoint viewPos = otherViewRect.topLeft();
    if( alignment == Qt::AlignBottom )
    {
        viewPos.setY( otherViewRect.bottom() + 1 );
    }
    // TODO: care for resize style
    else if( alignment == Qt::AlignRight )
    {
        viewPos.setX( otherViewRect.right() + 1 );
    }
    // TODO: doesn't really work at this stage, because the widget will get resized when inserted
    // and then ensureCursorVisible destroys the fun
    mWidget->setViewPos( viewPos );

    synchronizer->setView( this );
}
void CharsetConversionTool::convertChars()
{
    QApplication::setOverrideCursor( Qt::WaitCursor );

    const Okteta::AddressRange convertedSection = mByteArrayView->selection();
    QByteArray conversionResult;
    conversionResult.resize( convertedSection.width() );

    Okteta::CharCodec* viewCharCodec =
        Okteta::CharCodec::createCodec( mByteArrayView->charCodingName() );
    Okteta::CharCodec* otherCharCodec =
        Okteta::CharCodec::createCodec( mOtherCharCodecName );
    const bool convertToOther = (mConversionDirection == ConvertTo);
    Okteta::CharCodec* fromCharCodec = convertToOther ? viewCharCodec : otherCharCodec;
    Okteta::CharCodec* toCharCodec = convertToOther ? otherCharCodec : viewCharCodec;
    CharsetConversionJob* charsetConversionJob =
        new CharsetConversionJob( reinterpret_cast<Okteta::Byte*>(conversionResult.data()),
                                  mByteArrayModel, convertedSection,
                                  convertToOther ? viewCharCodec : otherCharCodec,
                                  convertToOther ? otherCharCodec : viewCharCodec,
                                  mSubstitutingMissingChars, mSubstituteByte
                                ); // TODO: report also actually converted bytes
    const bool success = charsetConversionJob->exec();

    if( success ) //TODO: if nothing needed to be converted, just report and don't add change
    {
        Okteta::ChangesDescribable *changesDescribable =
            qobject_cast<Okteta::ChangesDescribable*>( mByteArrayModel );

        if( changesDescribable )
        {
            const QString description =
                i18nc("Converted from charset 1 to charset 2",
                      "%1 to %2", fromCharCodec->name(), toCharCodec->name());
            changesDescribable->openGroupedChange( description );
        }
        mByteArrayModel->replace( convertedSection, conversionResult );
        if( changesDescribable )
            changesDescribable->closeGroupedChange();
    }

    delete viewCharCodec;
    delete otherCharCodec;

    QApplication::restoreOverrideCursor();

    const QMap<Okteta::Byte, int>& failedPerByteCount = charsetConversionJob->failedPerByteCount();
    const int convertedBytesCount = charsetConversionJob->convertedBytesCount();

    mByteArrayView->setFocus();

    emit conversionDone( success, convertedBytesCount, failedPerByteCount );
}
Exemple #7
0
bool InvertByteArrayFilter::filter( Okteta::Byte* result,
                                    Okteta::AbstractByteArrayModel *model, const Okteta::AddressRange& range ) const
{
    int r = 0;
    Okteta::Address m = range.start();
    int nextBlockEnd = FilteredByteCountSignalLimit;
    while( m <= range.end() )
    {
        result[r++] = ~model->byte( m++ );

        if( r >= nextBlockEnd )
        {
            nextBlockEnd += FilteredByteCountSignalLimit;
            emit filteredBytes( r );
        }
    }

    return true;
}
bool Qca2ByteArrayChecksumAlgorithm::calculateChecksum( QString* result,
                                                        const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range ) const
{
    QCA::Hash hash( mType );

    // TODO: find a way without needing to copy, perhaps by smart iterator which can return spans of original data
    // TODO: see if buffer size could be a value which matches the algorithm and qca2

    char buffer[CalculatedByteCountSignalLimit];
    int bufferLength = CalculatedByteCountSignalLimit;
    Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit;
    for( Okteta::Address i = range.start(); i<=range.end(); i+=CalculatedByteCountSignalLimit )
    {
        if( range.end() < i+CalculatedByteCountSignalLimit )
            bufferLength = range.end() - i + 1;
        model->copyTo( reinterpret_cast<Okteta::Byte*>(buffer), i, bufferLength );
        hash.update( buffer, bufferLength );

        if( i >= nextBlockEnd )
        {
            nextBlockEnd += CalculatedByteCountSignalLimit;
            emit calculatedBytes( range.localIndex(i)+1 );
        }
    }

    const QByteArray hashResult = hash.final().toByteArray();

    *result = QCA::arrayToHex( hashResult );
    return true;
}
Exemple #9
0
bool OrByteArrayFilter::filter( Okteta::Byte* result,
                                Okteta::AbstractByteArrayModel *model, const Okteta::AddressRange& range ) const
{
    const QByteArray operand = mParameterSet.operand();
    const int operandSize = operand.size();

    if( mParameterSet.alignAtEnd() )
    {
        const int behindLastResult = range.width();
        int r = behindLastResult;
        Okteta::Address m = range.nextBehindEnd();
        int nextBlockEnd = r - FilteredByteCountSignalLimit;

        while( m > range.start() )
        {
            int o = operandSize;
            while( m > range.start() && o > 0 )
                result[(r--)-1] = model->byte( (m--)-1 ) | operand[(o--)-1];

            if( r <= nextBlockEnd )
            {
                nextBlockEnd -= FilteredByteCountSignalLimit;
                emit filteredBytes( behindLastResult - r );
            }
        }
    }
    else
    {
        Okteta::Address r = 0;
        Okteta::Address m = range.start();
        Okteta::Address nextBlockEnd = FilteredByteCountSignalLimit;

        while( m <= range.end() )
        {
            int o = 0;
            while( m <= range.end() && o < operandSize )
                result[r++] = model->byte( m++ ) | operand[o++];

            if( r >= nextBlockEnd )
            {
                nextBlockEnd += FilteredByteCountSignalLimit;
                emit filteredBytes( r );
            }
        }
    }

    return true;
}
Exemple #10
0
void PrintTool::print()
{
    const QString processTitle = i18nc( "@title:window", "Print Byte Array %1", mDocument->title() );

    QPrinter printer;

//     LayoutDialogPage* layoutPage = new LayoutDialogPage();
    QList<QWidget*> customDialogPages;
//     customDialogPages << layoutPage;
    QPrintDialog *printDialog = new QPrintDialog( &printer, 0 );
    // Disable PrintPageRange, this tells Qt we can't do client-side page selection,
    // so it will try do server-side page selection if supported
    printDialog->setOption(QPrintDialog::PrintPageRange, false);
//    printDialog->setOptionTabs(customDialogPages);

    printDialog->setWindowTitle( processTitle );
    if( printDialog->exec() )
    {
        QString creator = QString::fromLatin1( "Print Plugin for Okteta " ); // no i18n(), keep space at end as separator
//         creator += KDEUTILS_VERSION_STRING; // TODO: change to OKTETA_VERSION_STRING
        printer.setCreator( creator );

        FramesToPaperPrinter framesPrinter;
        framesPrinter.setPaperRect( printer.paperRect() );
        framesPrinter.setPageRect( printer.pageRect() );
        printer.setFullPage( true );


        PrintInfo info;
        const QRect pageRect = framesPrinter.pageRect();
        const int left = pageRect.left();
        const int width = pageRect.width();

        HeaderFooterFrameRenderer *headerFrameRenderer = new HeaderFooterFrameRenderer( &info );
        headerFrameRenderer->setTexts( QStringLiteral("%d"),
                                       QStringLiteral("%f"),
                                       i18nc("in the header of the printed page, e.g. Page 2 of 20","Page %p of %P") );
        headerFrameRenderer->setWidth( width );
        headerFrameRenderer->setPos( pageRect.topLeft() );

        HeaderFooterFrameRenderer *footerFrameRenderer = new HeaderFooterFrameRenderer( &info );
        footerFrameRenderer->setTexts( i18nc("in the footer of the printed page, e.g. Printed by: Joe User",
                                             "Printed by: %U"),
                                       QString(),
                                       QStringLiteral("%F") );
        footerFrameRenderer->setWidth( width );
        const int footerTop = pageRect.bottom() - footerFrameRenderer->height();
        footerFrameRenderer->setPos( left, footerTop );

        const int contentHeight = pageRect.height() - footerFrameRenderer->height() - headerFrameRenderer->height();
        const int contentTop = pageRect.top() + headerFrameRenderer->height();
        ByteArrayFrameRenderer *byteArrayFrameRenderer = new ByteArrayFrameRenderer;
        byteArrayFrameRenderer->setPos( left, contentTop );
        byteArrayFrameRenderer->setWidth( width );
        byteArrayFrameRenderer->setHeight( contentHeight );

        Okteta::AddressRange range = mByteArrayView->selection();
        if( ! range.isValid() )
            range.setByWidth( 0, mByteArrayModel->size() );
        byteArrayFrameRenderer->setByteArrayModel( mByteArrayModel, range.start(), range.width() );

        // TODO: use noOfBytesPerLine of view, scale resolution down if it does not fit the page
        const int noOfBytesPerLine = mByteArrayView->noOfBytesPerLine();
//         byteArrayFrameRenderer->setNoOfBytesPerLine( mByteArrayView->noOfBytesPerLine() );

        const Okteta::Address startOffset = mByteArrayView->startOffset() + range.start();
        const int line = startOffset / noOfBytesPerLine;
        const Okteta::Address firstLineOffset = mByteArrayView->firstLineOffset() + line*noOfBytesPerLine;
        byteArrayFrameRenderer->setFirstLineOffset( firstLineOffset );
        byteArrayFrameRenderer->setStartOffset( startOffset );

        byteArrayFrameRenderer->setCharCoding( mByteArrayView->charCodingName() );
        byteArrayFrameRenderer->setBufferSpacing( mByteArrayView->byteSpacingWidth(),
                                                  mByteArrayView->noOfGroupedBytes(),
                                                  mByteArrayView->groupSpacingWidth() );
        byteArrayFrameRenderer->setBinaryGapWidth( mByteArrayView->binaryGapWidth() );

        byteArrayFrameRenderer->setValueCoding( (Okteta::ValueCoding)mByteArrayView->valueCoding() );
        byteArrayFrameRenderer->setShowsNonprinting( mByteArrayView->showsNonprinting() );
        byteArrayFrameRenderer->setSubstituteChar( mByteArrayView->substituteChar() );
        byteArrayFrameRenderer->setUndefinedChar( mByteArrayView->undefinedChar() );
        byteArrayFrameRenderer->showByteArrayColumns( mByteArrayView->visibleByteArrayCodings() );

//     if( !confirmPrintPageNumber( byteArrayFrameRenderer->framesCount()) )
//         return;

        framesPrinter.addFrameRenderer( headerFrameRenderer );
        framesPrinter.addFrameRenderer( byteArrayFrameRenderer );
        framesPrinter.addFrameRenderer( footerFrameRenderer );

        info.setNoOfPages( byteArrayFrameRenderer->framesCount() );
        AbstractModelSynchronizer* synchronizer = mDocument->synchronizer();
        if (synchronizer) {
            info.setUrl( synchronizer->url() );
        }

        QApplication::setOverrideCursor( Qt::WaitCursor );

        PrintJob *printJob = new PrintJob( &framesPrinter, 0, byteArrayFrameRenderer->framesCount()-1, &printer );
        const bool success = printJob->exec();

        QApplication::restoreOverrideCursor();

        if( ! success )
        {
            const QString message = i18nc( "@info","Could not print." );

            KMessageBox::sorry( 0, message, processTitle );
        }
    }

    delete printDialog;
}