~larryprice/acolyterm/release-0.1

« back to all changes in this revision

Viewing changes to src/plugin/konsole/History.h

  • Committer: Larry Price
  • Date: 2016-06-15 14:47:59 UTC
  • Revision ID: larry.price@canonical.com-20160615144759-6wopn0gxwgta3x1n
Updating QMLTermWidget and removing unnecessary konsole codebase

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    This file is part of Konsole, an X terminal.
3
 
    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
4
 
 
5
 
    This program is free software; you can redistribute it and/or modify
6
 
    it under the terms of the GNU General Public License as published by
7
 
    the Free Software Foundation; either version 2 of the License, or
8
 
    (at your option) any later version.
9
 
 
10
 
    This program is distributed in the hope that it will be useful,
11
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
    GNU General Public License for more details.
14
 
 
15
 
    You should have received a copy of the GNU General Public License
16
 
    along with this program; if not, write to the Free Software
17
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18
 
    02110-1301  USA.
19
 
*/
20
 
 
21
 
#ifndef TEHISTORY_H
22
 
#define TEHISTORY_H
23
 
 
24
 
// Qt
25
 
#include <QtCore/QBitRef>
26
 
#include <QtCore/QHash>
27
 
#include <QtCore/QVector>
28
 
#include <QTemporaryFile>
29
 
 
30
 
// KDE
31
 
//#include <ktemporaryfile.h>
32
 
 
33
 
// Konsole
34
 
#include "BlockArray.h"
35
 
#include "Character.h"
36
 
 
37
 
// map
38
 
#include <sys/mman.h>
39
 
 
40
 
 
41
 
#if 1
42
 
/*
43
 
   An extendable tmpfile(1) based buffer.
44
 
*/
45
 
 
46
 
class HistoryFile
47
 
{
48
 
public:
49
 
  HistoryFile();
50
 
  virtual ~HistoryFile();
51
 
 
52
 
  virtual void add(const unsigned char* bytes, int len);
53
 
  virtual void get(unsigned char* bytes, int len, int loc);
54
 
  virtual int  len();
55
 
 
56
 
  //mmaps the file in read-only mode
57
 
  void map();
58
 
  //un-mmaps the file
59
 
  void unmap();
60
 
  //returns true if the file is mmap'ed
61
 
  bool isMapped();
62
 
 
63
 
 
64
 
private:
65
 
  int  ion;
66
 
  int  length;
67
 
  QTemporaryFile tmpFile;
68
 
 
69
 
  //pointer to start of mmap'ed file data, or 0 if the file is not mmap'ed
70
 
  char* fileMap;
71
 
 
72
 
  //incremented whenver 'add' is called and decremented whenever
73
 
  //'get' is called.
74
 
  //this is used to detect when a large number of lines are being read and processed from the history
75
 
  //and automatically mmap the file for better performance (saves the overhead of many lseek-read calls).
76
 
  int readWriteBalance;
77
 
 
78
 
  //when readWriteBalance goes below this threshold, the file will be mmap'ed automatically
79
 
  static const int MAP_THRESHOLD = -1000;
80
 
};
81
 
#endif
82
 
 
83
 
//////////////////////////////////////////////////////////////////////
84
 
 
85
 
//////////////////////////////////////////////////////////////////////
86
 
// Abstract base class for file and buffer versions
87
 
//////////////////////////////////////////////////////////////////////
88
 
class HistoryType;
89
 
 
90
 
class HistoryScroll
91
 
{
92
 
public:
93
 
  HistoryScroll(HistoryType*);
94
 
 virtual ~HistoryScroll();
95
 
 
96
 
  virtual bool hasScroll();
97
 
 
98
 
  // access to history
99
 
  virtual int  getLines() = 0;
100
 
  virtual int  getLineLen(int lineno) = 0;
101
 
  virtual void getCells(int lineno, int colno, int count, Character res[]) = 0;
102
 
  virtual bool isWrappedLine(int lineno) = 0;
103
 
 
104
 
  // backward compatibility (obsolete)
105
 
  Character   getCell(int lineno, int colno) { Character res; getCells(lineno,colno,1,&res); return res; }
106
 
 
107
 
  // adding lines.
108
 
  virtual void addCells(const Character a[], int count) = 0;
109
 
  // convenience method - this is virtual so that subclasses can take advantage
110
 
  // of QVector's implicit copying
111
 
  virtual void addCellsVector(const QVector<Character>& cells)
112
 
  {
113
 
    addCells(cells.data(),cells.size());
114
 
  }
115
 
 
116
 
  virtual void addLine(bool previousWrapped=false) = 0;
117
 
 
118
 
  //
119
 
  // FIXME:  Passing around constant references to HistoryType instances
120
 
  // is very unsafe, because those references will no longer
121
 
  // be valid if the history scroll is deleted.
122
 
  //
123
 
  const HistoryType& getType() { return *m_histType; }
124
 
 
125
 
protected:
126
 
  HistoryType* m_histType;
127
 
 
128
 
};
129
 
 
130
 
#if 1
131
 
 
132
 
//////////////////////////////////////////////////////////////////////
133
 
// File-based history (e.g. file log, no limitation in length)
134
 
//////////////////////////////////////////////////////////////////////
135
 
 
136
 
class HistoryScrollFile : public HistoryScroll
137
 
{
138
 
public:
139
 
  HistoryScrollFile(const QString &logFileName);
140
 
  virtual ~HistoryScrollFile();
141
 
 
142
 
  virtual int  getLines();
143
 
  virtual int  getLineLen(int lineno);
144
 
  virtual void getCells(int lineno, int colno, int count, Character res[]);
145
 
  virtual bool isWrappedLine(int lineno);
146
 
 
147
 
  virtual void addCells(const Character a[], int count);
148
 
  virtual void addLine(bool previousWrapped=false);
149
 
 
150
 
private:
151
 
  int startOfLine(int lineno);
152
 
 
153
 
  QString m_logFileName;
154
 
  HistoryFile index; // lines Row(int)
155
 
  HistoryFile cells; // text  Row(Character)
156
 
  HistoryFile lineflags; // flags Row(unsigned char)
157
 
};
158
 
 
159
 
 
160
 
//////////////////////////////////////////////////////////////////////
161
 
// Buffer-based history (limited to a fixed nb of lines)
162
 
//////////////////////////////////////////////////////////////////////
163
 
class HistoryScrollBuffer : public HistoryScroll
164
 
{
165
 
public:
166
 
  typedef QVector<Character> HistoryLine;
167
 
 
168
 
  HistoryScrollBuffer(unsigned int maxNbLines = 1000);
169
 
  virtual ~HistoryScrollBuffer();
170
 
 
171
 
  virtual int  getLines();
172
 
  virtual int  getLineLen(int lineno);
173
 
  virtual void getCells(int lineno, int colno, int count, Character res[]);
174
 
  virtual bool isWrappedLine(int lineno);
175
 
 
176
 
  virtual void addCells(const Character a[], int count);
177
 
  virtual void addCellsVector(const QVector<Character>& cells);
178
 
  virtual void addLine(bool previousWrapped=false);
179
 
 
180
 
  void setMaxNbLines(unsigned int nbLines);
181
 
  unsigned int maxNbLines() { return _maxLineCount; }
182
 
 
183
 
 
184
 
private:
185
 
  int bufferIndex(int lineNumber);
186
 
 
187
 
  HistoryLine* _historyBuffer;
188
 
  QBitArray _wrappedLine;
189
 
  int _maxLineCount;
190
 
  int _usedLines;
191
 
  int _head;
192
 
 
193
 
  //QVector<histline*> m_histBuffer;
194
 
  //QBitArray m_wrappedLine;
195
 
  //unsigned int m_maxNbLines;
196
 
  //unsigned int m_nbLines;
197
 
  //unsigned int m_arrayIndex;
198
 
  //bool         m_buffFilled;
199
 
};
200
 
 
201
 
/*class HistoryScrollBufferV2 : public HistoryScroll
202
 
{
203
 
public:
204
 
  virtual int  getLines();
205
 
  virtual int  getLineLen(int lineno);
206
 
  virtual void getCells(int lineno, int colno, int count, Character res[]);
207
 
  virtual bool isWrappedLine(int lineno);
208
 
 
209
 
  virtual void addCells(const Character a[], int count);
210
 
  virtual void addCells(const QVector<Character>& cells);
211
 
  virtual void addLine(bool previousWrapped=false);
212
 
 
213
 
};*/
214
 
 
215
 
#endif
216
 
 
217
 
//////////////////////////////////////////////////////////////////////
218
 
// Nothing-based history (no history :-)
219
 
//////////////////////////////////////////////////////////////////////
220
 
class HistoryScrollNone : public HistoryScroll
221
 
{
222
 
public:
223
 
  HistoryScrollNone();
224
 
  virtual ~HistoryScrollNone();
225
 
 
226
 
  virtual bool hasScroll();
227
 
 
228
 
  virtual int  getLines();
229
 
  virtual int  getLineLen(int lineno);
230
 
  virtual void getCells(int lineno, int colno, int count, Character res[]);
231
 
  virtual bool isWrappedLine(int lineno);
232
 
 
233
 
  virtual void addCells(const Character a[], int count);
234
 
  virtual void addLine(bool previousWrapped=false);
235
 
};
236
 
 
237
 
//////////////////////////////////////////////////////////////////////
238
 
// BlockArray-based history
239
 
//////////////////////////////////////////////////////////////////////
240
 
class HistoryScrollBlockArray : public HistoryScroll
241
 
{
242
 
public:
243
 
  HistoryScrollBlockArray(size_t size);
244
 
  virtual ~HistoryScrollBlockArray();
245
 
 
246
 
  virtual int  getLines();
247
 
  virtual int  getLineLen(int lineno);
248
 
  virtual void getCells(int lineno, int colno, int count, Character res[]);
249
 
  virtual bool isWrappedLine(int lineno);
250
 
 
251
 
  virtual void addCells(const Character a[], int count);
252
 
  virtual void addLine(bool previousWrapped=false);
253
 
 
254
 
protected:
255
 
  BlockArray m_blockArray;
256
 
  QHash<int,size_t> m_lineLengths;
257
 
};
258
 
 
259
 
//////////////////////////////////////////////////////////////////////
260
 
// History using compact storage
261
 
// This implementation uses a list of fixed-sized blocks
262
 
// where history lines are allocated in (avoids heap fragmentation)
263
 
//////////////////////////////////////////////////////////////////////
264
 
typedef QVector<Character> TextLine;
265
 
 
266
 
class CharacterFormat
267
 
{
268
 
public:
269
 
  bool equalsFormat(const CharacterFormat &other) const {
270
 
    return other.rendition==rendition && other.fgColor==fgColor && other.bgColor==bgColor;
271
 
  }
272
 
 
273
 
  bool equalsFormat(const Character &c) const {
274
 
    return c.rendition==rendition && c.foregroundColor==fgColor && c.backgroundColor==bgColor;
275
 
  }
276
 
 
277
 
  void setFormat(const Character& c) {
278
 
    rendition=c.rendition;
279
 
    fgColor=c.foregroundColor;
280
 
    bgColor=c.backgroundColor;
281
 
  }
282
 
 
283
 
  CharacterColor fgColor, bgColor;
284
 
  quint16 startPos;
285
 
  quint8 rendition;
286
 
};
287
 
 
288
 
class CompactHistoryBlock
289
 
{
290
 
public:
291
 
 
292
 
  CompactHistoryBlock(){
293
 
    blockLength = 4096*64; // 256kb
294
 
    head = (quint8*) mmap(0, blockLength, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
295
 
    //head = (quint8*) malloc(blockLength);
296
 
    Q_ASSERT(head != MAP_FAILED);
297
 
    tail = blockStart = head;
298
 
    allocCount=0;
299
 
  }
300
 
 
301
 
  virtual ~CompactHistoryBlock(){
302
 
    //free(blockStart);
303
 
    munmap(blockStart, blockLength);
304
 
  }
305
 
 
306
 
  virtual unsigned int remaining(){ return blockStart+blockLength-tail;}
307
 
  virtual unsigned  length() { return blockLength; }
308
 
  virtual void* allocate(size_t length);
309
 
  virtual bool contains(void *addr) {return addr>=blockStart && addr<(blockStart+blockLength);}
310
 
  virtual void deallocate();
311
 
  virtual bool isInUse(){ return allocCount!=0; } ;
312
 
 
313
 
private:
314
 
  size_t blockLength;
315
 
  quint8* head;
316
 
  quint8* tail;
317
 
  quint8* blockStart;
318
 
  int allocCount;
319
 
};
320
 
 
321
 
class CompactHistoryBlockList {
322
 
public:
323
 
  CompactHistoryBlockList() {};
324
 
  ~CompactHistoryBlockList();
325
 
 
326
 
  void *allocate( size_t size );
327
 
  void deallocate(void *);
328
 
  int length() {return list.size();}
329
 
private:
330
 
  QList<CompactHistoryBlock*> list;
331
 
};
332
 
 
333
 
class CompactHistoryLine
334
 
{
335
 
public:
336
 
  CompactHistoryLine(const TextLine&, CompactHistoryBlockList& blockList);
337
 
  virtual ~CompactHistoryLine();
338
 
 
339
 
  // custom new operator to allocate memory from custom pool instead of heap
340
 
  static void *operator new( size_t size, CompactHistoryBlockList& blockList);
341
 
  static void operator delete( void *) { /* do nothing, deallocation from pool is done in destructor*/ } ;
342
 
 
343
 
  virtual void getCharacters(Character* array, int length, int startColumn) ;
344
 
  virtual void getCharacter(int index, Character &r) ;
345
 
  virtual bool isWrapped() const {return wrapped;};
346
 
  virtual void setWrapped(bool isWrapped) { wrapped=isWrapped;};
347
 
  virtual unsigned int getLength() const {return length;};
348
 
 
349
 
protected:
350
 
  CompactHistoryBlockList& blockList;
351
 
  CharacterFormat* formatArray;
352
 
  quint16 length;
353
 
  quint16* text;
354
 
  quint16 formatLength;
355
 
  bool wrapped;
356
 
};
357
 
 
358
 
class CompactHistoryScroll : public HistoryScroll
359
 
{
360
 
  typedef QList<CompactHistoryLine*> HistoryArray;
361
 
 
362
 
public:
363
 
  CompactHistoryScroll(unsigned int maxNbLines = 1000);
364
 
  virtual ~CompactHistoryScroll();
365
 
 
366
 
  virtual int  getLines();
367
 
  virtual int  getLineLen(int lineno);
368
 
  virtual void getCells(int lineno, int colno, int count, Character res[]);
369
 
  virtual bool isWrappedLine(int lineno);
370
 
 
371
 
  virtual void addCells(const Character a[], int count);
372
 
  virtual void addCellsVector(const TextLine& cells);
373
 
  virtual void addLine(bool previousWrapped=false);
374
 
 
375
 
  void setMaxNbLines(unsigned int nbLines);
376
 
  unsigned int maxNbLines() const { return _maxLineCount; }
377
 
 
378
 
private:
379
 
  bool hasDifferentColors(const TextLine& line) const;
380
 
  HistoryArray lines;
381
 
  CompactHistoryBlockList blockList;
382
 
 
383
 
  unsigned int _maxLineCount;
384
 
};
385
 
 
386
 
//////////////////////////////////////////////////////////////////////
387
 
// History type
388
 
//////////////////////////////////////////////////////////////////////
389
 
 
390
 
class HistoryType
391
 
{
392
 
public:
393
 
  HistoryType();
394
 
  virtual ~HistoryType();
395
 
 
396
 
  /**
397
 
   * Returns true if the history is enabled ( can store lines of output )
398
 
   * or false otherwise.
399
 
   */
400
 
  virtual bool isEnabled()           const = 0;
401
 
  /**
402
 
   * Returns true if the history size is unlimited.
403
 
   */
404
 
  bool isUnlimited() const { return maximumLineCount() == 0; }
405
 
  /**
406
 
   * Returns the maximum number of lines which this history type
407
 
   * can store or 0 if the history can store an unlimited number of lines.
408
 
   */
409
 
  virtual int maximumLineCount()    const = 0;
410
 
 
411
 
  virtual HistoryScroll* scroll(HistoryScroll *) const = 0;
412
 
};
413
 
 
414
 
class HistoryTypeNone : public HistoryType
415
 
{
416
 
public:
417
 
  HistoryTypeNone();
418
 
 
419
 
  virtual bool isEnabled() const;
420
 
  virtual int maximumLineCount() const;
421
 
 
422
 
  virtual HistoryScroll* scroll(HistoryScroll *) const;
423
 
};
424
 
 
425
 
class HistoryTypeBlockArray : public HistoryType
426
 
{
427
 
public:
428
 
  HistoryTypeBlockArray(size_t size);
429
 
 
430
 
  virtual bool isEnabled() const;
431
 
  virtual int maximumLineCount() const;
432
 
 
433
 
  virtual HistoryScroll* scroll(HistoryScroll *) const;
434
 
 
435
 
protected:
436
 
  size_t m_size;
437
 
};
438
 
 
439
 
#if 1
440
 
class HistoryTypeFile : public HistoryType
441
 
{
442
 
public:
443
 
  HistoryTypeFile(const QString& fileName=QString());
444
 
 
445
 
  virtual bool isEnabled() const;
446
 
  virtual const QString& getFileName() const;
447
 
  virtual int maximumLineCount() const;
448
 
 
449
 
  virtual HistoryScroll* scroll(HistoryScroll *) const;
450
 
 
451
 
protected:
452
 
  QString m_fileName;
453
 
};
454
 
 
455
 
 
456
 
class HistoryTypeBuffer : public HistoryType
457
 
{
458
 
    friend class HistoryScrollBuffer;
459
 
 
460
 
public:
461
 
  HistoryTypeBuffer(unsigned int nbLines);
462
 
 
463
 
  virtual bool isEnabled() const;
464
 
  virtual int maximumLineCount() const;
465
 
 
466
 
  virtual HistoryScroll* scroll(HistoryScroll *) const;
467
 
 
468
 
protected:
469
 
  unsigned int m_nbLines;
470
 
};
471
 
 
472
 
class CompactHistoryType : public HistoryType
473
 
{
474
 
public:
475
 
  CompactHistoryType(unsigned int size);
476
 
 
477
 
  virtual bool isEnabled() const;
478
 
  virtual int maximumLineCount() const;
479
 
 
480
 
  virtual HistoryScroll* scroll(HistoryScroll *) const;
481
 
 
482
 
protected:
483
 
  unsigned int m_nbLines;
484
 
};
485
 
 
486
 
 
487
 
#endif
488
 
 
489
 
 
490
 
#endif // TEHISTORY_H