File indexing completed on 2024-04-21 16:34:01

0001 /*
0002     This file is part of the Okteta Gui library, made within the KDE community.
0003 
0004     SPDX-FileCopyrightText: 2003, 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 #include "bytearraytablelayout.hpp"
0010 
0011 namespace Okteta {
0012 
0013 static constexpr LineSize DefaultNoOfLinesPerPage = 1;
0014 
0015 ByteArrayTableLayout::ByteArrayTableLayout(Size noOfBytesPerLine, Address firstLineOffset, Address startOffset,
0016                                            Address byteArrayOffset, Size byteArrayLength)
0017     : mNoOfBytesPerLine(noOfBytesPerLine)
0018     , mFirstLineOffset(firstLineOffset)
0019     , mStartOffset(startOffset)
0020     , mRelativeStartOffset(startOffset - firstLineOffset)
0021     , mByteArrayOffset(byteArrayOffset)
0022     , mLastByteArrayOffset(byteArrayOffset + byteArrayLength - 1)
0023     , mNoOfLinesPerPage(DefaultNoOfLinesPerPage)
0024 {
0025     calcStart();
0026     calcEnd();
0027 }
0028 
0029 ByteArrayTableLayout::~ByteArrayTableLayout() = default;
0030 
0031 bool ByteArrayTableLayout::setStartOffset(Address startOffset)
0032 {
0033     // rejecting <0
0034     if (startOffset < 0) {
0035         startOffset = 0;
0036     }
0037 
0038     if (mStartOffset == startOffset) {
0039         return false;
0040     }
0041 
0042     mStartOffset = startOffset;
0043     mRelativeStartOffset = mStartOffset - mFirstLineOffset;
0044 
0045     calcStart();
0046     calcEnd();
0047     return true;
0048 }
0049 
0050 bool ByteArrayTableLayout::setFirstLineOffset(Address firstLineOffset)
0051 {
0052     // rejecting <0
0053     if (firstLineOffset < 0) {
0054         firstLineOffset = 0;
0055     }
0056 
0057     if (mFirstLineOffset == firstLineOffset) {
0058         return false;
0059     }
0060 
0061     mFirstLineOffset = firstLineOffset;
0062     mRelativeStartOffset = mStartOffset - mFirstLineOffset;
0063 
0064     calcStart();
0065     calcEnd();
0066     return true;
0067 }
0068 
0069 bool ByteArrayTableLayout::setNoOfBytesPerLine(LineSize noOfBytesPerLine)
0070 {
0071     // rejecting <1
0072     if (noOfBytesPerLine < 1) {
0073         noOfBytesPerLine = 1;
0074     }
0075 
0076     // no changes?
0077     if (mNoOfBytesPerLine == noOfBytesPerLine) {
0078         return false;
0079     }
0080 
0081     mNoOfBytesPerLine = noOfBytesPerLine;
0082 
0083     calcStart();
0084     calcEnd();
0085     return true;
0086 }
0087 
0088 bool ByteArrayTableLayout::setByteArrayOffset(Address byteArrayOffset)
0089 {
0090     // rejecting < 0
0091     if (byteArrayOffset < 0) {
0092         byteArrayOffset = 0;
0093     }
0094 
0095     // no changes?
0096     if (mByteArrayOffset == byteArrayOffset) {
0097         return false;
0098     }
0099 
0100     const Size l = length();
0101 
0102     mByteArrayOffset = byteArrayOffset;
0103     mLastByteArrayOffset = mByteArrayOffset + l - 1;
0104 
0105     calcEnd();
0106     return true;
0107 }
0108 
0109 bool ByteArrayTableLayout::setLength(Size length)
0110 {
0111     // rejecting < 0
0112     if (length < 0) {
0113         length = 0;
0114     }
0115 
0116     const Address newLastByteArrayOffset = mByteArrayOffset + length - 1;
0117 
0118     // no changes?
0119     if (mLastByteArrayOffset == newLastByteArrayOffset) {
0120         return false;
0121     }
0122 
0123     mLastByteArrayOffset = newLastByteArrayOffset;
0124 
0125     calcEnd();
0126     return true;
0127 }
0128 
0129 void ByteArrayTableLayout::setNoOfLinesPerPage(LineSize noOfLinesPerPage)
0130 {
0131     mNoOfLinesPerPage = noOfLinesPerPage;
0132 }
0133 
0134 void ByteArrayTableLayout::calcStart()
0135 {
0136     mCoordRange.setStart(Coord::fromIndex(mRelativeStartOffset, mNoOfBytesPerLine));
0137 }
0138 
0139 void ByteArrayTableLayout::calcEnd()
0140 {
0141     const Size l = length();
0142     mCoordRange.setEnd((l > 0) ?
0143                        Coord::fromIndex(l - 1 + mRelativeStartOffset, mNoOfBytesPerLine) :
0144                        Coord(-1, mCoordRange.start().line()));
0145 }
0146 
0147 Address ByteArrayTableLayout::indexAtCFirstLinePosition(Line line) const
0148 {
0149     return (line <= mCoordRange.start().line()) ? mByteArrayOffset :
0150            (line > mCoordRange.end().line()) ?    mLastByteArrayOffset :
0151                                                   line* mNoOfBytesPerLine - mRelativeStartOffset + mByteArrayOffset;
0152 }
0153 
0154 Address ByteArrayTableLayout::indexAtCLastLinePosition(Line line) const
0155 {
0156     return (line < mCoordRange.start().line()) ? mByteArrayOffset :
0157            (line >= mCoordRange.end().line()) ?  mLastByteArrayOffset :
0158                                                  (line + 1) * mNoOfBytesPerLine - mRelativeStartOffset - 1 + mByteArrayOffset;
0159 }
0160 
0161 Address ByteArrayTableLayout::indexAtCCoord(const Coord& coord) const
0162 {
0163     const Address index = indexAtCoord(coord);
0164 
0165     return (index <= mByteArrayOffset) ?     mByteArrayOffset :
0166            (index >= mLastByteArrayOffset) ? mLastByteArrayOffset :
0167                                              index;
0168 }
0169 
0170 Line ByteArrayTableLayout::lineAtCIndex(Address index) const
0171 {
0172     return (index <= mByteArrayOffset) ?     mCoordRange.start().line() :
0173            (index >= mLastByteArrayOffset) ? mCoordRange.end().line() :
0174                                              lineAtIndex(index);
0175 }
0176 
0177 Coord ByteArrayTableLayout::coordOfCIndex(Address index) const
0178 {
0179     return (index <= mByteArrayOffset) ?     mCoordRange.start() :
0180            (index >= mLastByteArrayOffset) ? mCoordRange.end() :
0181                                              coordOfIndex(index);
0182 }
0183 
0184 Address ByteArrayTableLayout::indexAtFirstLinePosition(Line line) const
0185 {
0186     return (line == mCoordRange.start().line()) ? mByteArrayOffset : line* mNoOfBytesPerLine - mRelativeStartOffset + mByteArrayOffset;
0187 }
0188 
0189 Address ByteArrayTableLayout::indexAtLastLinePosition(Line line) const
0190 {
0191     return (line == mCoordRange.end().line()) ? mLastByteArrayOffset : (line + 1) * mNoOfBytesPerLine - mRelativeStartOffset + mByteArrayOffset - 1;
0192 }
0193 
0194 Address ByteArrayTableLayout::indexAtCoord(const Coord& coord) const
0195 {
0196     return coord.indexByLineWidth(mNoOfBytesPerLine) - mRelativeStartOffset + mByteArrayOffset;
0197 }
0198 
0199 Line ByteArrayTableLayout::lineAtIndex(Address index) const
0200 {
0201     return (index + mRelativeStartOffset - mByteArrayOffset) / mNoOfBytesPerLine;
0202 }
0203 
0204 Coord ByteArrayTableLayout::coordOfIndex(Address index) const
0205 {
0206     return Coord::fromIndex(index + mRelativeStartOffset - mByteArrayOffset, mNoOfBytesPerLine);
0207 }
0208 
0209 CoordRange ByteArrayTableLayout::coordRangeOfIndizes(const AddressRange& indizes) const
0210 {
0211     return CoordRange(
0212         Coord::fromIndex(indizes.start() + mRelativeStartOffset - mByteArrayOffset, mNoOfBytesPerLine),
0213         Coord::fromIndex(indizes.end() + mRelativeStartOffset - mByteArrayOffset,   mNoOfBytesPerLine));
0214 }
0215 
0216 Address ByteArrayTableLayout::correctIndex(Address index) const
0217 {
0218     return (index <= mByteArrayOffset) ?     mByteArrayOffset :
0219            (index >= mLastByteArrayOffset) ? mLastByteArrayOffset :
0220                                              index;
0221 }
0222 
0223 Coord ByteArrayTableLayout::correctCoord(const Coord& coord) const
0224 {
0225     return (coord <= mCoordRange.start()) ?     mCoordRange.start() :
0226            (coord >= mCoordRange.end()) ?       mCoordRange.end() :
0227            (coord.pos() >= mNoOfBytesPerLine) ? Coord(mNoOfBytesPerLine - 1, coord.line()) :
0228                                                 coord;
0229 }
0230 
0231 bool ByteArrayTableLayout::atFirstLinePosition(const Coord& coord) const
0232 {
0233     return (coord.line() == mCoordRange.start().line()) ? coord.pos() == mCoordRange.start().pos() :
0234                                                           coord.pos() == 0;
0235 }
0236 
0237 bool ByteArrayTableLayout::atLastLinePosition(const Coord& coord) const
0238 {
0239     return (coord.line() == mCoordRange.end().line()) ? coord.pos() == mCoordRange.end().pos() :
0240                                                         coord.pos() == mNoOfBytesPerLine - 1;
0241 }
0242 
0243 LinePositionRange ByteArrayTableLayout::linePositions(Line line) const
0244 {
0245     return LinePositionRange(firstLinePosition(line), lastLinePosition(line));
0246 }
0247 
0248 LinePosition ByteArrayTableLayout::firstLinePosition(const Coord& coord) const
0249 {
0250     return (mCoordRange.start().isLaterInLineThan(coord)) ? mCoordRange.start().pos() : coord.pos();
0251 }
0252 
0253 LinePosition ByteArrayTableLayout::lastLinePosition(const Coord& coord) const
0254 {
0255     return (mCoordRange.end().isPriorInLineThan(coord)) ? mCoordRange.end().pos() : coord.pos();
0256 }
0257 
0258 LinePosition ByteArrayTableLayout::firstLinePosition(Line line) const
0259 {
0260     return line == mCoordRange.start().line() ? mCoordRange.start().pos() : 0;
0261 }
0262 
0263 LinePosition ByteArrayTableLayout::lastLinePosition(Line line) const
0264 {
0265     return (line == mCoordRange.end().line()) ? mCoordRange.end().pos() : mNoOfBytesPerLine - 1;
0266 }
0267 
0268 bool ByteArrayTableLayout::hasContent(Line line) const
0269 {
0270     return mCoordRange.includesLine(line);
0271 }
0272 
0273 }