xref: /glogg/src/data/linepositionarray.h (revision e49f49227e3ac5228b59ac99ea5acc5e009950d9)
1 /*
2  * Copyright (C) 2015 Nicolas Bonnefon and other contributors
3  *
4  * This file is part of glogg.
5  *
6  * glogg is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * glogg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with glogg.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LINEPOSITIONARRAY_H
21 #define LINEPOSITIONARRAY_H
22 
23 #include <vector>
24 
25 #include "data/compressedlinestorage.h"
26 
27 typedef std::vector<uint64_t> SimpleLinePositionStorage;
28 
29 // This class is a list of end of lines position,
30 // in addition to a list of qint64 (positions within the files)
31 // it can keep track of whether the final LF was added (for non-LF terminated
32 // files) and remove it when more data are added.
33 template <typename Storage>
34 class LinePosition
35 {
36   public:
37     template <typename> friend class LinePosition;
38 
39     // Default constructor
40     LinePosition() : array()
41     { fakeFinalLF_ = false; }
42     // Copy constructor (slow: deleted)
43     LinePosition( const LinePosition& orig ) = delete;
44     // Move assignement
45     LinePosition& operator=( LinePosition&& orig )
46     { array = std::move( orig.array );
47       fakeFinalLF_ = orig.fakeFinalLF_;
48       return *this; }
49 
50     // Add a new line position at the given position
51     // Invariant: pos must be greater than the previous one
52     // (this is NOT checked!)
53     inline void append( qint64 pos )
54     {
55         if ( fakeFinalLF_ )
56             array.pop_back();
57 
58         array.push_back( pos );
59     }
60     // Size of the array
61     inline int size() const
62     { return array.size(); }
63     // Extract an element
64     inline qint64 at( int i ) const
65     { return array.at( i ); }
66     inline qint64 operator[]( int i ) const
67     { return array.at( i ); }
68     // Set the presence of a fake final LF
69     // Must be used after 'append'-ing a fake LF at the end.
70     void setFakeFinalLF( bool finalLF=true )
71     { fakeFinalLF_ = finalLF; }
72 
73     // Add another list to this one, removing any fake LF on this list.
74     // Invariant: all pos in other must be greater than any pos in this
75     // (this is NOT checked!)
76     void append_list( const LinePosition<SimpleLinePositionStorage>& other )
77     {
78         // If our final LF is fake, we remove it
79         if ( fakeFinalLF_ )
80             this->array.pop_back();
81 
82         // Append the arrays
83         this->array.append_list( other.array );
84         //array += other.array;
85 
86         // In case the 'other' object has a fake LF
87         this->fakeFinalLF_ = other.fakeFinalLF_;
88     }
89 
90   private:
91     Storage array;
92     bool fakeFinalLF_;
93 };
94 
95 // Use the non-optimised storage
96 typedef LinePosition<SimpleLinePositionStorage> FastLinePositionArray;
97 //typedef LinePosition<SimpleLinePositionStorage> LinePositionArray;
98 
99 typedef LinePosition<CompressedLinePositionStorage> LinePositionArray;
100 
101 #endif
102