File indexing completed on 2024-04-14 15:52:45

0001 /*
0002     This file is part of the Okteta Core library, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2008-2009 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 #ifndef OKTETA_PIECETABLEBYTEARRAYMODEL_P_HPP
0010 #define OKTETA_PIECETABLEBYTEARRAYMODEL_P_HPP
0011 
0012 // lib
0013 #include "abstractbytearraymodel_p.hpp"
0014 #include "piecetablebytearraymodel.hpp"
0015 #include "bookmarksconstiterator.hpp"
0016 #include "bookmarklistconstiteratoradapter.hpp"
0017 #include "bookmarklist.hpp"
0018 #include "changesdatastorage.hpp"
0019 #include "arraychangemetricslist.hpp"
0020 // piecetable
0021 #include "piecetable/revertablepiecetable.hpp"
0022 
0023 namespace Okteta {
0024 
0025 class PieceTableByteArrayModelPrivate : public AbstractByteArrayModelPrivate
0026 {
0027 public:
0028     /**  */
0029     explicit PieceTableByteArrayModelPrivate(PieceTableByteArrayModel* parent, const QByteArray& data);
0030     /** creates a writeable buffer which is deleted at the end */
0031     explicit PieceTableByteArrayModelPrivate(PieceTableByteArrayModel* parent, int size, Byte fillByte = '\0');
0032 
0033     ~PieceTableByteArrayModelPrivate() override;
0034 
0035 public: // AbstractByteArrayModel API
0036     Byte byte(Address offset) const;
0037     Size size() const;
0038     bool isReadOnly() const;
0039     bool isModified() const;
0040 
0041     Size insert(Address offset, const Byte* insertData, int insertLength);
0042     Size remove(const AddressRange& removeRange);
0043     Size replace(const AddressRange& removeRange, const Byte* insertData, int insertLength);
0044     bool swap(Address firstStart, const AddressRange& secondRange);
0045     Size fill(Byte fillByte, Address offset = 0, Size fillLength = -1);
0046     void setByte(Address offset, Byte byte);
0047 
0048     void setModified(bool modified = true);
0049     void setReadOnly(bool isReadOnly = true);
0050 
0051 public: // Versionable API
0052     int versionIndex() const;
0053     int versionCount() const;
0054     QString versionDescription(int versionIndex) const;
0055 
0056 public: // set/action
0057     void revertToVersionByIndex(int versionIndex);
0058 
0059 public:
0060     void addBookmarks(const QVector<Bookmark>& bookmarks);
0061     void removeBookmarks(const QVector<Bookmark>& bookmarks);
0062     void removeAllBookmarks();
0063     void setBookmark(unsigned int index, const Bookmark& bookmark);
0064 
0065     BookmarksConstIterator createBookmarksConstIterator() const;
0066     const Bookmark& bookmarkAt(unsigned int index) const;
0067     const Bookmark& bookmarkFor(int offset) const;
0068     bool containsBookmarkFor(int offset) const;
0069     unsigned int bookmarksCount() const;
0070 
0071 public: // ChangesDescribable API
0072     void openGroupedChange(const QString& description);
0073     void cancelGroupedChange();
0074     void closeGroupedChange(const QString& description);
0075 
0076 public: // ChangeHistory API
0077     QVector<ByteArrayChange> changes(int firstVersionIndex, int lastVersionIndex) const;
0078     const QByteArray& initialData() const;
0079     void doChanges(const QVector<Okteta::ByteArrayChange>& changes,
0080                    int oldVersionIndex, int newVersionIndex);
0081 
0082 public:
0083     void setData(const QByteArray& data);
0084 
0085 private:
0086     void doInsertChange(Address offset, const Byte* insertData, int insertLength);
0087     void doRemoveChange(const AddressRange& removeRange);
0088     void doReplaceChange(const AddressRange& removeRange, const Byte* insertData, int insertLength);
0089     void doSwapChange(Address firstStart, const AddressRange& secondRange);
0090     void doFillChange(Address offset, Size filledLength,
0091                       Byte fillByte, int fillLength);
0092 
0093     void beginChanges();
0094     void endChanges();
0095 
0096 private: // data
0097     /**  */
0098     bool mReadOnly : 1;
0099 
0100     QByteArray mInitialData;
0101     KPieceTable::RevertablePieceTable mPieceTable;
0102     ChangesDataStorage mChangesDataStorage;
0103     /** */
0104     BookmarkList mBookmarks;
0105     /** temporary workaround for cancelling groups. If -1 no group is opened. */
0106     int mBeforeGroupedChangeVersionIndex;
0107 
0108     int mBeforeChangesVersionIndex;
0109     ArrayChangeMetricsList mChangeMetrics;
0110     QVector<ByteArrayChange> mChanges;
0111     bool mBeforeChangesModified : 1;
0112     bool mBookmarksModified : 1;
0113 
0114 private:
0115     Q_DECLARE_PUBLIC(PieceTableByteArrayModel)
0116 };
0117 
0118 inline const QByteArray& PieceTableByteArrayModelPrivate::initialData() const { return mInitialData; }
0119 inline Size PieceTableByteArrayModelPrivate::size() const { return mPieceTable.size(); }
0120 
0121 inline bool PieceTableByteArrayModelPrivate::isReadOnly()   const { return mReadOnly; }
0122 inline bool PieceTableByteArrayModelPrivate::isModified()   const { return !mPieceTable.isAtBase(); }
0123 
0124 inline void PieceTableByteArrayModelPrivate::setReadOnly(bool readOnly)
0125 {
0126     Q_Q(PieceTableByteArrayModel);
0127 
0128     if (mReadOnly != readOnly) {
0129         mReadOnly = readOnly;
0130         emit q->readOnlyChanged(readOnly);
0131     }
0132 }
0133 inline void PieceTableByteArrayModelPrivate::setModified(bool modified)
0134 {
0135     Q_Q(PieceTableByteArrayModel);
0136 
0137     if (isModified() != modified) {
0138         mPieceTable.setBeforeCurrentChangeAsBase(modified);
0139         // TODO: is the call setModified of any use?
0140         // shouldn't there be only a setUnmodified(void) or else call?
0141         emit q->modifiedChanged(modified);
0142     }
0143 }
0144 
0145 inline int PieceTableByteArrayModelPrivate::versionIndex() const { return mPieceTable.appliedChangesCount(); }
0146 inline int PieceTableByteArrayModelPrivate::versionCount() const { return mPieceTable.changesCount() + 1; }
0147 inline QString PieceTableByteArrayModelPrivate::versionDescription(int versionIndex) const
0148 { return mPieceTable.changeDescription(versionIndex - 1); }
0149 
0150 inline void PieceTableByteArrayModelPrivate::addBookmarks(const QVector<Bookmark>& bookmarks)
0151 {
0152     Q_Q(PieceTableByteArrayModel);
0153 
0154     mBookmarks.addBookmarks(bookmarks);
0155     emit q->bookmarksAdded(bookmarks);
0156 }
0157 inline void PieceTableByteArrayModelPrivate::removeBookmarks(const QVector<Bookmark>& bookmarks)
0158 {
0159     Q_Q(PieceTableByteArrayModel);
0160 
0161     mBookmarks.removeBookmarks(bookmarks);
0162     emit q->bookmarksRemoved(bookmarks);
0163 }
0164 
0165 inline void PieceTableByteArrayModelPrivate::removeAllBookmarks()
0166 {
0167     Q_Q(PieceTableByteArrayModel);
0168 
0169     const QVector<Bookmark> bookmarks = mBookmarks.list();
0170     mBookmarks.clear();
0171     emit q->bookmarksRemoved(bookmarks);
0172 }
0173 inline void PieceTableByteArrayModelPrivate::setBookmark(unsigned int index, const Bookmark& bookmark)
0174 {
0175     Q_Q(PieceTableByteArrayModel);
0176 
0177     mBookmarks.setBookmark(index, bookmark);
0178 
0179     const QVector<int> changedBookmarkIndizes {
0180         static_cast<int>(index)
0181     };
0182     emit q->bookmarksModified(changedBookmarkIndizes);
0183 }
0184 
0185 inline BookmarksConstIterator PieceTableByteArrayModelPrivate::createBookmarksConstIterator() const
0186 {
0187     return BookmarksConstIterator(new BookmarkListConstIteratorAdapter(mBookmarks));
0188 }
0189 
0190 inline const Bookmark& PieceTableByteArrayModelPrivate::bookmarkAt(unsigned int index) const
0191 {
0192     return mBookmarks.at(index);
0193 }
0194 inline const Bookmark& PieceTableByteArrayModelPrivate::bookmarkFor(int offset) const
0195 {
0196     return mBookmarks.bookmark(offset);
0197 }
0198 inline bool PieceTableByteArrayModelPrivate::containsBookmarkFor(int offset) const { return mBookmarks.contains(offset); }
0199 inline unsigned int PieceTableByteArrayModelPrivate::bookmarksCount() const { return mBookmarks.size(); }
0200 
0201 }
0202 
0203 #endif