1 /** \file hist.h
2     \brief file history and bookmarks container
3 
4     CoolReader Engine
5 
6     (c) Vadim Lopatin, 2000-2007
7     This source code is distributed under the terms of
8     GNU General Public License
9     See LICENSE file for details
10 */
11 
12 #ifndef HIST_H_INCLUDED
13 #define HIST_H_INCLUDED
14 
15 #include "lvptrvec.h"
16 #include "lvstring.h"
17 #include <time.h>
18 
19 enum bmk_type {
20     bmkt_lastpos,
21     bmkt_pos,
22     bmkt_comment,
23     bmkt_correction
24 };
25 
26 class CRBookmark {
27 private:
28     lString32 _startpos;
29     lString32 _endpos;
30     int       _percent;
31     int       _type;
32 	int       _shortcut;
33     lString32 _postext;
34     lString32 _titletext;
35     lString32 _commenttext;
36     time_t    _timestamp;
37     int       _page;
38 public:
39 	static lString32 getChapterName( ldomXPointer p );
40 
41     // fake bookmark for range
CRBookmark(lString32 startPos,lString32 endPos)42     CRBookmark(lString32 startPos,lString32 endPos)
43                 : _startpos(startPos)
44     , _endpos(endPos)
45     , _percent(0)
46     , _type(0)
47         , _shortcut(0)
48     , _postext(lString32::empty_str)
49     , _titletext(lString32::empty_str)
50     , _commenttext(lString32::empty_str)
51     , _timestamp(time_t(0))
52     ,_page(0)
53     {
54     }
CRBookmark(const CRBookmark & v)55     CRBookmark(const CRBookmark & v )
56     : _startpos(v._startpos)
57     , _endpos(v._endpos)
58     , _percent(v._percent)
59     , _type(v._type)
60 	, _shortcut(v._shortcut)
61     , _postext(v._postext)
62     , _titletext(v._titletext)
63     , _commenttext(v._commenttext)
64     , _timestamp(v._timestamp)
65     , _page(v._page)
66     {
67     }
68     CRBookmark & operator = (const CRBookmark & v )
69     {
70         _startpos = v._startpos;
71         _endpos = v._endpos;
72         _percent = v._percent;
73         _type = v._type;
74 		_shortcut = v._shortcut;
75         _postext = v._postext;
76         _titletext = v._titletext;
77         _commenttext = v._commenttext;
78         _timestamp = v._timestamp;
79         _page = v._page;
80         return *this;
81     }
CRBookmark()82     CRBookmark() : _percent(0), _type(0), _shortcut(0), _timestamp(0), _page(0) { }
83     CRBookmark ( ldomXPointer ptr );
getStartPos()84     lString32 getStartPos() { return _startpos; }
getEndPos()85     lString32 getEndPos() { return _endpos; }
getPosText()86     lString32 getPosText() { return _postext; }
getTitleText()87     lString32 getTitleText() { return _titletext; }
getCommentText()88     lString32 getCommentText() { return _commenttext; }
getShortcut()89     int getShortcut() { return _shortcut; }
getType()90     int getType() { return _type; }
getPercent()91     int getPercent() { return _percent; }
getTimestamp()92     time_t getTimestamp() { return _timestamp; }
setStartPos(const lString32 & s)93     void setStartPos(const lString32 & s ) { _startpos = s; }
setEndPos(const lString32 & s)94     void setEndPos(const lString32 & s ) { _endpos = s; }
setPosText(const lString32 & s)95     void setPosText(const lString32 & s ) { _postext= s; }
setTitleText(const lString32 & s)96     void setTitleText(const lString32 & s ) { _titletext = s; }
setCommentText(const lString32 & s)97     void setCommentText(const lString32 & s ) { _commenttext = s; }
setType(int n)98     void setType( int n ) { _type = n; }
setShortcut(int n)99     void setShortcut( int n ) { _shortcut = n; }
setPercent(int n)100     void setPercent( int n ) { _percent = n; }
setTimestamp(time_t t)101     void setTimestamp( time_t t ) { _timestamp = t; }
setBookmarkPage(int page)102     void setBookmarkPage( int page ) { _page = page; }
getBookmarkPage()103     int getBookmarkPage() { return _page; }
isValid()104     bool isValid() {
105         if (_type < bmkt_lastpos || _type >bmkt_correction)
106             return false;
107         if (_startpos.empty())
108             return false;
109         if ((_type == bmkt_comment || _type == bmkt_correction) && _endpos.empty())
110             return false;
111         return true;
112     }
113 };
114 
115 /// bookmark/position change info for synchronization/replication
116 class ChangeInfo {
117     CRBookmark * _bookmark;
118     lString32 _fileName;
119     bool _deleted;
120     time_t _timestamp;
121 
122 public:
ChangeInfo()123     ChangeInfo() : _bookmark(NULL), _deleted(false), _timestamp(0) {
124     }
125 
126     ChangeInfo(CRBookmark * bookmark, lString32 fileName, bool deleted);
127 
~ChangeInfo()128     ~ChangeInfo() {
129         if (_bookmark)
130             delete _bookmark;
131     }
132 
getBookmark()133     CRBookmark * getBookmark() { return _bookmark; }
134 
getFileName()135     lString32 getFileName() { return _fileName; }
136 
isDeleted()137     bool isDeleted() { return _deleted; }
138 
getTimestamp()139     time_t getTimestamp() { return _timestamp; }
140 
141     lString8 toString();
142 
143     static ChangeInfo * fromString(lString8 s);
144 
145     static ChangeInfo * fromBytes(lChar8 * buf, int start, int end);
146 
147     static bool findNextRecordBounds(lChar8 * buf, int start, int end, int & recordStart, int & recordEnd);
148 };
149 
150 class ChangeInfoList : public LVPtrVector<ChangeInfo> {
151 
152 };
153 
154 class CRFileHistRecord {
155 private:
156     lString32 _fname;
157     lString32 _fpath;
158     lString32 _title;
159     lString32 _author;
160     lString32 _series;
161     lvpos_t   _size;
162     int       _domVersion;
163     LVPtrVector<CRBookmark> _bookmarks;
164     CRBookmark _lastpos;
165 public:
166     /// returns first available placeholder for new bookmark, -1 if no more space
167     int getLastShortcutBookmark();
168     /// returns first available placeholder for new bookmark, -1 if no more space
169     int getFirstFreeShortcutBookmark();
170     CRBookmark * setShortcutBookmark( int shortcut, ldomXPointer ptr );
171     CRBookmark * getShortcutBookmark( int shortcut );
getLastTime()172     time_t getLastTime() { return _lastpos.getTimestamp(); }
173     lString32 getLastTimeString( bool longFormat=false );
setLastTime(time_t t)174     void setLastTime( time_t t ) { _lastpos.setTimestamp(t); }
getBookmarks()175     LVPtrVector<CRBookmark>  & getBookmarks() { return _bookmarks; }
getLastPos()176     CRBookmark * getLastPos() { return &_lastpos; }
177     void setLastPos( CRBookmark * bmk );
getTitle()178     lString32 getTitle() { return _title; }
getAuthor()179     lString32 getAuthor() { return _author; }
getSeries()180     lString32 getSeries() { return _series; }
getFileName()181     lString32 getFileName() { return _fname; }
getFilePath()182     lString32 getFilePath() { return _fpath; }
getFilePathName()183     lString32 getFilePathName() { return _fpath + _fname; }
getFileSize()184     lvpos_t   getFileSize() const { return _size; }
getDOMversion()185     int getDOMversion() const { return _domVersion; }
setTitle(const lString32 & s)186     void setTitle( const lString32 & s ) { _title = s; }
setAuthor(const lString32 & s)187     void setAuthor( const lString32 & s ) { _author = s; }
setSeries(const lString32 & s)188     void setSeries( const lString32 & s ) { _series = s; }
setFileName(const lString32 & s)189     void setFileName( const lString32 & s ) { _fname = s; }
setFilePath(const lString32 & s)190     void setFilePath( const lString32 & s ) { _fpath = s; }
setFileSize(lvsize_t sz)191     void setFileSize( lvsize_t sz ) { _size = sz; }
setDOMversion(int v)192     void setDOMversion( int v ) { _domVersion = v; }
193     void convertBookmarks(ldomDocument * doc, int newDOMversion);
CRFileHistRecord()194     CRFileHistRecord()
195         : _size(0), _domVersion(20171225)
196     {
197     }
CRFileHistRecord(const CRFileHistRecord & v)198     CRFileHistRecord( const CRFileHistRecord & v)
199         : _fname(v._fname)
200         , _fpath(v._fpath)
201         , _title(v._title)
202         , _author(v._author)
203         , _series(v._series)
204         , _size(v._size)
205         , _bookmarks(v._bookmarks)
206         , _lastpos(v._lastpos)
207         , _domVersion(v._domVersion)
208     {
209     }
~CRFileHistRecord()210     ~CRFileHistRecord()
211     {
212     }
213 };
214 
215 
216 class CRFileHist {
217 private:
218     LVPtrVector<CRFileHistRecord> _records;
219     int findEntry( const lString32 & fname, const lString32 & fpath, lvsize_t sz ) const;
220     void makeTop( int index );
221 public:
limit(int maxItems)222     void limit( int maxItems )
223     {
224         for ( int i=_records.length()-1; i>maxItems; i-- ) {
225             _records.erase( i, 1 );
226         }
227     }
getRecords()228     LVPtrVector<CRFileHistRecord> & getRecords() { return _records; }
229     CRFileHistRecord* getRecord(const lString32 & fileName, size_t fileSize );
230     bool loadFromStream( LVStreamRef stream );
231     bool saveToStream( LVStream * stream );
232     CRFileHistRecord * savePosition( lString32 fpathname, size_t sz,
233         const lString32 & title,
234         const lString32 & author,
235         const lString32 & series,
236         ldomXPointer ptr );
237     ldomXPointer restorePosition(  ldomDocument * doc, lString32 fpathname, size_t sz );
CRFileHist()238     CRFileHist()
239     {
240     }
~CRFileHist()241     ~CRFileHist()
242     {
243         clear();
244     }
245     void clear();
246 };
247 
248 #endif //HIST_H_INCLUDED
249