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

0001 /*
0002     This file is part of the Okteta Core library, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2007, 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 #include "bookmarklist.hpp"
0010 
0011 // Qt
0012 #include <QVector>
0013 
0014 namespace Okteta {
0015 
0016 BookmarkList::BookmarkList() = default;
0017 
0018 BookmarkList::~BookmarkList() = default;
0019 
0020 void BookmarkList::addBookmark(const Bookmark& bookmark)
0021 {
0022     if (!bookmark.isValid()) {
0023         return;
0024     }
0025 
0026     iterator B = begin();
0027     for (; B != end(); ++B) {
0028         // new bookmark before next bookmark?
0029         if (bookmark.offset() < B->offset()) {
0030             // put the new before it
0031             insert(B, bookmark);
0032             return;
0033         }
0034 
0035         // bookmark already present?
0036         if (bookmark.offset() == B->offset()) {
0037             *B = bookmark;
0038             return;
0039         }
0040     }
0041 
0042     // all others before the new?
0043     if (B == end()) {
0044         // add it at the end
0045         append(bookmark);
0046     }
0047 }
0048 
0049 void BookmarkList::addBookmarks(const QVector<Okteta::Bookmark>& bookmarks)
0050 {
0051     for (const Bookmark& bookmark : bookmarks) {
0052         addBookmark(bookmark);
0053     }
0054 }
0055 
0056 void BookmarkList::removeBookmark(const Bookmark& bookmark)
0057 {
0058     if (!bookmark.isValid()) {
0059         return;
0060     }
0061 
0062     iterator B = begin();
0063     for (; B != end(); ++B) {
0064         if (bookmark.offset() == B->offset()) {
0065             erase(B);
0066             break;
0067         }
0068     }
0069 }
0070 
0071 void BookmarkList::removeBookmarks(const QVector<Okteta::Bookmark>& bookmarks)
0072 {
0073     for (const Bookmark& bookmark : bookmarks) {
0074         removeBookmark(bookmark);
0075     }
0076 }
0077 
0078 void BookmarkList::setBookmark(unsigned int index, const Bookmark& bookmark)
0079 {
0080     const Iterator endIt = end();
0081     unsigned int i = 0;
0082     for (Iterator it = begin(); it != endIt; ++it, ++i) {
0083         if (i == index) {
0084             *it = bookmark;
0085             break;
0086         }
0087     }
0088 }
0089 
0090 bool BookmarkList::adjustToReplaced(Address offset, Size removedLength, Size insertedLength)
0091 {
0092     bool result = false;
0093 
0094     iterator bIt = begin();
0095     while (bIt != end() && bIt->offset() < offset) {
0096         ++bIt;
0097     }
0098     // remove bookmarks in removed section
0099     while (bIt != end() && bIt->offset() < offset + removedLength) {
0100         bIt = erase(bIt);
0101         result = true;
0102     }
0103     // adjust bookmarks in moved section
0104     const Size diff = insertedLength - removedLength;
0105     if (diff != 0) {
0106         for (; bIt != end(); ++bIt) {
0107             (*bIt).move(diff);
0108             result = true;
0109         }
0110     }
0111 
0112     return result;
0113 }
0114 
0115 bool BookmarkList::adjustToSwapped(Address firstPartStart, Address secondPartStart, Size secondPartLength)
0116 {
0117     bool result = false;
0118 
0119     iterator bIt = begin();
0120     while (bIt != end() && bIt->offset() < firstPartStart) {
0121         ++bIt;
0122     }
0123     QVector<Okteta::Bookmark> bookmarksInFirstPart;
0124     // take bookmarks from first part
0125     while (bIt != end() && bIt->offset() < secondPartStart) {
0126         bookmarksInFirstPart.append(*bIt);
0127         bIt = erase(bIt);
0128     }
0129     // move bookmarks from second to first
0130     const Size diff = firstPartStart - secondPartStart;
0131     const Address behindLast = secondPartStart + secondPartLength;
0132     for (; bIt != end() && bIt->offset() < behindLast; ++bIt) {
0133         (*bIt).move(diff);
0134         result = true;
0135     }
0136 
0137     // append bookmarks from first part as second
0138     if (!bookmarksInFirstPart.isEmpty()) {
0139         for (Bookmark bookmark : qAsConst(bookmarksInFirstPart)) { // krazy:exclude=foreach
0140             bookmark.move(secondPartLength);
0141             insert(bIt, bookmark);
0142         }
0143 
0144         result = true;
0145     }
0146 
0147     return result;
0148 }
0149 
0150 QVector<Okteta::Bookmark> BookmarkList::list() const
0151 {
0152     QVector<Okteta::Bookmark> result;
0153     result.reserve(size());
0154 
0155     for (const Bookmark& bookmark : *this) {
0156         result.append(bookmark);
0157     }
0158 
0159     return result;
0160 }
0161 
0162 const Bookmark& BookmarkList::bookmark(Address offset) const
0163 {
0164     const ConstIterator endIt = end();
0165     auto it = std::find_if(begin(), endIt, [offset](const Bookmark& bookmark) {
0166         return (bookmark.offset() == offset);
0167     });
0168     if (it != endIt) {
0169         return *it;
0170     }
0171 
0172     static const Bookmark* const noBookmark = nullptr;
0173 
0174     return (const Bookmark&)*noBookmark;
0175 }
0176 
0177 bool BookmarkList::contains(Address offset) const
0178 {
0179     return std::any_of(begin(), end(), [offset](const Bookmark& bookmark) {
0180         return (bookmark.offset() == offset);
0181     });
0182 }
0183 
0184 const Bookmark& BookmarkList::at(unsigned int index) const
0185 {
0186     Q_ASSERT_X((int)index < size(), "BookmarkList::at", "index out of range");
0187 
0188     const ConstIterator endIt = end();
0189     unsigned int i = 0;
0190     for (ConstIterator it = begin(); it != endIt; ++it, ++i) {
0191         if (i == index) {
0192             return *it;
0193         }
0194     }
0195 
0196     static const Bookmark* const noBookmark = nullptr;
0197     return (const Bookmark&)*noBookmark;
0198 }
0199 
0200 }