File indexing completed on 2023-09-24 04:44:39
0001 /* 0002 This file is part of kdev-pg 0003 Copyright 2002-2006 Roberto Raggi <roberto@kdevelop.org> 0004 Copyright 2009 Milian Wolff <mail@milianw.de> 0005 0006 Permission to use, copy, modify, distribute, and sell this software and its 0007 documentation for any purpose is hereby granted without fee, provided that 0008 the above copyright notice appear in all copies and that both that 0009 copyright notice and this permission notice appear in supporting 0010 documentation. 0011 0012 The above copyright notice and this permission notice shall be included in 0013 all copies or substantial portions of the Software. 0014 0015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 0016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 0017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 0018 KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 0019 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 0020 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 0021 */ 0022 0023 //krazy:excludeall=inline 0024 #ifndef KDEV_PG_LOCATION_TABLE_H 0025 #define KDEV_PG_LOCATION_TABLE_H 0026 0027 #include <QtGlobal> 0028 #include <QtAlgorithms> 0029 0030 namespace KDevPG 0031 { 0032 0033 class LocationTable 0034 { 0035 public: 0036 inline LocationTable(qint64 size = 1024) 0037 : lines(nullptr), lineCount(0), currentLine(0), lastLine(0) 0038 { 0039 resize(size); 0040 lines[currentLine++] = 0; 0041 } 0042 0043 inline ~LocationTable() 0044 { 0045 free(lines); 0046 } 0047 0048 inline qint64 size() const 0049 { return lineCount; } 0050 0051 void resize(qint64 size) 0052 { 0053 Q_ASSERT(size > 0); 0054 lines = (qint64*) ::realloc(lines, sizeof(qint64) * size); 0055 lineCount = size; 0056 } 0057 0058 /** 0059 * Returns the \a line and \a column of the given \a offset in this table. 0060 */ 0061 void positionAt(qint64 offset, qint64 *line, qint64 *column) const 0062 { 0063 if ( offset < 0 ) { 0064 // invalid offset 0065 *line = -1; 0066 *column = -1; 0067 return; 0068 } else if ( offset > lines[currentLine - 1] ) { 0069 // overflow 0070 *line = currentLine - 1; 0071 *column = offset - lines[currentLine - 1]; 0072 return; 0073 } 0074 0075 qint64 i = -1; 0076 // search relative to last line (next line and the one after that) 0077 if ( lastLine + 1 < currentLine && lines[lastLine] <= offset ) { 0078 if ( lines[lastLine + 1] > offset ) { 0079 // last matched line matches again 0080 i = lastLine; 0081 } else if ( lastLine + 2 < currentLine && lines[lastLine + 2] > offset ) { 0082 // next line relative to last matched matches 0083 i = lastLine + 1; 0084 } 0085 } 0086 if ( i == -1 ) { 0087 // fallback to binary search 0088 qint64 *it = std::lower_bound(lines, lines + currentLine, offset); 0089 Q_ASSERT(it != lines + currentLine); 0090 0091 if (*it != offset) { 0092 --it; 0093 } 0094 *line = it - lines; 0095 *column = offset - *it; 0096 } else { 0097 *line = i; 0098 *column = offset - lines[i]; 0099 } 0100 0101 lastLine = *line; 0102 } 0103 0104 /** 0105 * Marks an \a offset as the character before the first one in the next line. 0106 * The positionAt() function relies on newline() being called properly. 0107 */ 0108 inline void newline(qint64 offset) 0109 { 0110 if (currentLine == lineCount) 0111 resize(currentLine * 2); 0112 0113 lines[currentLine++] = offset+1; 0114 } 0115 0116 inline qint64 &operator[](int index) 0117 { return lines[index]; } 0118 0119 protected: 0120 /// An array of input buffer offsets 0121 qint64 *lines; 0122 /// The size of the allocated array 0123 qint64 lineCount; 0124 /// The index to the next index in the lines array 0125 qint64 currentLine; 0126 /// Last line as found by positionAt 0127 mutable qint64 lastLine; 0128 0129 private: 0130 LocationTable(LocationTable const &other); 0131 void operator=(LocationTable const &other); 0132 }; 0133 0134 } 0135 0136 #endif // KDEV_PG_LOCATION_TABLE_H 0137