File indexing completed on 2024-04-21 05:52:58

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