File indexing completed on 2024-04-28 05:52:31

0001 /*
0002     This file is part of the Okteta Core library, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2008 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 "replacepiecetablechange.hpp"
0010 
0011 // lib
0012 #include "piecetable.hpp"
0013 //
0014 #include <arraychangemetrics.hpp>
0015 // KF
0016 #include <KLocalizedString>
0017 
0018 namespace KPieceTable {
0019 
0020 ReplacePieceTableChange::~ReplacePieceTableChange() = default;
0021 
0022 int ReplacePieceTableChange::type() const { return ReplaceId; }
0023 
0024 QString ReplacePieceTableChange::description() const
0025 {
0026     return i18nc("name of the change", "Replace");
0027 }
0028 
0029 Address ReplacePieceTableChange::storageOffset() const { return mStorageOffset; }
0030 
0031 bool ReplacePieceTableChange::merge(const AbstractPieceTableChange* other)
0032 {
0033 // TODO: remove me again after synching solved
0034 // return false;
0035     bool result = false;
0036 
0037     if (other->type() == ReplaceId) {
0038         const auto* otherReplaceChange = static_cast<const ReplacePieceTableChange*>(other);
0039         // other replaced after?
0040         if (mRemoveRange.start() + mInsertLength == otherReplaceChange->mRemoveRange.start()) {
0041             mRemoveRange.moveEndBy(otherReplaceChange->mRemoveRange.width());
0042             mInsertLength += otherReplaceChange->mInsertLength;
0043             mRemovedPieces.append(otherReplaceChange->mRemovedPieces);
0044             result = true;
0045         }
0046         // other replaced before would be two swapped ranges in the change buffer, if this ever needed/wanted?
0047     }
0048 
0049     return result;
0050 }
0051 
0052 AddressRange ReplacePieceTableChange::apply(PieceTable* pieceTable) const
0053 {
0054     const Size oldSize = pieceTable->size();
0055 
0056     pieceTable->replace(mRemoveRange, mInsertLength, mStorageOffset);
0057 
0058     const Size newSize = pieceTable->size();
0059     const Address lastChanged = (newSize == oldSize) ? mRemoveRange.end() :
0060                                 (newSize > oldSize) ?  newSize - 1 :
0061                                                        oldSize - 1;
0062     return AddressRange(mRemoveRange.start(), lastChanged);
0063 }
0064 
0065 AddressRange ReplacePieceTableChange::revert(PieceTable* pieceTable) const
0066 {
0067     const Size oldSize = pieceTable->size();
0068 
0069     const AddressRange insertedSection = AddressRange::fromWidth(mRemoveRange.start(), mInsertLength);
0070     pieceTable->replace(insertedSection, mRemovedPieces);
0071 
0072     const Size newSize = pieceTable->size();
0073     const Address lastChanged = (newSize == oldSize) ? insertedSection.end() :
0074                                 (newSize > oldSize) ?  newSize - 1 :
0075                                                        oldSize - 1;
0076     return AddressRange(mRemoveRange.start(), lastChanged);
0077 }
0078 
0079 ArrayChangeMetrics ReplacePieceTableChange::metrics() const
0080 {
0081     return ArrayChangeMetrics::asReplacement(mRemoveRange.start(), mRemoveRange.width(), mInsertLength);
0082 }
0083 
0084 Size ReplacePieceTableChange::dataSize() const { return mInsertLength; }
0085 
0086 }