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; }
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 ); }
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; }
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; }
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; }