Skip to content

Commit 73e86da

Browse files
author
pcav
committedApr 27, 2009
Adding qtermwidget
git-svn-id: http://svn.osgeo.org/qgis/trunk@10665 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent ef0dd11 commit 73e86da

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+21494
-0
lines changed
 
Lines changed: 337 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
/*
2+
This file is part of Konsole, an X terminal.
3+
Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
4+
5+
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
6+
7+
This program is free software; you can redistribute it and/or modify
8+
it under the terms of the GNU General Public License as published by
9+
the Free Software Foundation; either version 2 of the License, or
10+
(at your option) any later version.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with this program; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20+
02110-1301 USA.
21+
22+
*/
23+
24+
// Own
25+
#include "BlockArray.h"
26+
27+
#include <QtCore>
28+
29+
// System
30+
#include <assert.h>
31+
#include <sys/mman.h>
32+
#include <sys/param.h>
33+
#include <unistd.h>
34+
#include <stdio.h>
35+
36+
37+
using namespace Konsole;
38+
39+
static int blocksize = 0;
40+
41+
BlockArray::BlockArray()
42+
: size(0),
43+
current(size_t(-1)),
44+
index(size_t(-1)),
45+
lastmap(0),
46+
lastmap_index(size_t(-1)),
47+
lastblock(0), ion(-1),
48+
length(0)
49+
{
50+
// lastmap_index = index = current = size_t(-1);
51+
if (blocksize == 0)
52+
blocksize = ((sizeof(Block) / getpagesize()) + 1) * getpagesize();
53+
54+
}
55+
56+
BlockArray::~BlockArray()
57+
{
58+
setHistorySize(0);
59+
assert(!lastblock);
60+
}
61+
62+
size_t BlockArray::append(Block *block)
63+
{
64+
if (!size)
65+
return size_t(-1);
66+
67+
++current;
68+
if (current >= size) current = 0;
69+
70+
int rc;
71+
rc = lseek(ion, current * blocksize, SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setHistorySize(0); return size_t(-1); }
72+
rc = write(ion, block, blocksize); if (rc < 0) { perror("HistoryBuffer::add.write"); setHistorySize(0); return size_t(-1); }
73+
74+
length++;
75+
if (length > size) length = size;
76+
77+
++index;
78+
79+
delete block;
80+
return current;
81+
}
82+
83+
size_t BlockArray::newBlock()
84+
{
85+
if (!size)
86+
return size_t(-1);
87+
append(lastblock);
88+
89+
lastblock = new Block();
90+
return index + 1;
91+
}
92+
93+
Block *BlockArray::lastBlock() const
94+
{
95+
return lastblock;
96+
}
97+
98+
bool BlockArray::has(size_t i) const
99+
{
100+
if (i == index + 1)
101+
return true;
102+
103+
if (i > index)
104+
return false;
105+
if (index - i >= length)
106+
return false;
107+
return true;
108+
}
109+
110+
const Block* BlockArray::at(size_t i)
111+
{
112+
if (i == index + 1)
113+
return lastblock;
114+
115+
if (i == lastmap_index)
116+
return lastmap;
117+
118+
if (i > index) {
119+
qDebug() << "BlockArray::at() i > index\n";
120+
return 0;
121+
}
122+
123+
// if (index - i >= length) {
124+
// kDebug(1211) << "BlockArray::at() index - i >= length\n";
125+
// return 0;
126+
// }
127+
128+
size_t j = i; // (current - (index - i) + (index/size+1)*size) % size ;
129+
130+
assert(j < size);
131+
unmap();
132+
133+
Block *block = (Block*)mmap(0, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize);
134+
135+
if (block == (Block*)-1) { perror("mmap"); return 0; }
136+
137+
lastmap = block;
138+
lastmap_index = i;
139+
140+
return block;
141+
}
142+
143+
void BlockArray::unmap()
144+
{
145+
if (lastmap) {
146+
int res = munmap((char*)lastmap, blocksize);
147+
if (res < 0) perror("munmap");
148+
}
149+
lastmap = 0;
150+
lastmap_index = size_t(-1);
151+
}
152+
153+
bool BlockArray::setSize(size_t newsize)
154+
{
155+
return setHistorySize(newsize * 1024 / blocksize);
156+
}
157+
158+
bool BlockArray::setHistorySize(size_t newsize)
159+
{
160+
// kDebug(1211) << "setHistorySize " << size << " " << newsize;
161+
162+
if (size == newsize)
163+
return false;
164+
165+
unmap();
166+
167+
if (!newsize) {
168+
delete lastblock;
169+
lastblock = 0;
170+
if (ion >= 0) close(ion);
171+
ion = -1;
172+
current = size_t(-1);
173+
return true;
174+
}
175+
176+
if (!size) {
177+
FILE* tmp = tmpfile();
178+
if (!tmp) {
179+
perror("konsole: cannot open temp file.\n");
180+
} else {
181+
ion = dup(fileno(tmp));
182+
if (ion<0) {
183+
perror("konsole: cannot dup temp file.\n");
184+
fclose(tmp);
185+
}
186+
}
187+
if (ion < 0)
188+
return false;
189+
190+
assert(!lastblock);
191+
192+
lastblock = new Block();
193+
size = newsize;
194+
return false;
195+
}
196+
197+
if (newsize > size) {
198+
increaseBuffer();
199+
size = newsize;
200+
return false;
201+
} else {
202+
decreaseBuffer(newsize);
203+
ftruncate(ion, length*blocksize);
204+
size = newsize;
205+
206+
return true;
207+
}
208+
}
209+
210+
void moveBlock(FILE *fion, int cursor, int newpos, char *buffer2)
211+
{
212+
int res = fseek(fion, cursor * blocksize, SEEK_SET);
213+
if (res)
214+
perror("fseek");
215+
res = fread(buffer2, blocksize, 1, fion);
216+
if (res != 1)
217+
perror("fread");
218+
219+
res = fseek(fion, newpos * blocksize, SEEK_SET);
220+
if (res)
221+
perror("fseek");
222+
res = fwrite(buffer2, blocksize, 1, fion);
223+
if (res != 1)
224+
perror("fwrite");
225+
// printf("moving block %d to %d\n", cursor, newpos);
226+
}
227+
228+
void BlockArray::decreaseBuffer(size_t newsize)
229+
{
230+
if (index < newsize) // still fits in whole
231+
return;
232+
233+
int offset = (current - (newsize - 1) + size) % size;
234+
235+
if (!offset)
236+
return;
237+
238+
// The Block constructor could do somthing in future...
239+
char *buffer1 = new char[blocksize];
240+
241+
FILE *fion = fdopen(dup(ion), "w+b");
242+
if (!fion) {
243+
delete [] buffer1;
244+
perror("fdopen/dup");
245+
return;
246+
}
247+
248+
int firstblock;
249+
if (current <= newsize) {
250+
firstblock = current + 1;
251+
} else {
252+
firstblock = 0;
253+
}
254+
255+
size_t oldpos;
256+
for (size_t i = 0, cursor=firstblock; i < newsize; i++) {
257+
oldpos = (size + cursor + offset) % size;
258+
moveBlock(fion, oldpos, cursor, buffer1);
259+
if (oldpos < newsize) {
260+
cursor = oldpos;
261+
} else
262+
cursor++;
263+
}
264+
265+
current = newsize - 1;
266+
length = newsize;
267+
268+
delete [] buffer1;
269+
270+
fclose(fion);
271+
272+
}
273+
274+
void BlockArray::increaseBuffer()
275+
{
276+
if (index < size) // not even wrapped once
277+
return;
278+
279+
int offset = (current + size + 1) % size;
280+
if (!offset) // no moving needed
281+
return;
282+
283+
// The Block constructor could do somthing in future...
284+
char *buffer1 = new char[blocksize];
285+
char *buffer2 = new char[blocksize];
286+
287+
int runs = 1;
288+
int bpr = size; // blocks per run
289+
290+
if (size % offset == 0) {
291+
bpr = size / offset;
292+
runs = offset;
293+
}
294+
295+
FILE *fion = fdopen(dup(ion), "w+b");
296+
if (!fion) {
297+
perror("fdopen/dup");
298+
delete [] buffer1;
299+
delete [] buffer2;
300+
return;
301+
}
302+
303+
int res;
304+
for (int i = 0; i < runs; i++)
305+
{
306+
// free one block in chain
307+
int firstblock = (offset + i) % size;
308+
res = fseek(fion, firstblock * blocksize, SEEK_SET);
309+
if (res)
310+
perror("fseek");
311+
res = fread(buffer1, blocksize, 1, fion);
312+
if (res != 1)
313+
perror("fread");
314+
int newpos = 0;
315+
for (int j = 1, cursor=firstblock; j < bpr; j++)
316+
{
317+
cursor = (cursor + offset) % size;
318+
newpos = (cursor - offset + size) % size;
319+
moveBlock(fion, cursor, newpos, buffer2);
320+
}
321+
res = fseek(fion, i * blocksize, SEEK_SET);
322+
if (res)
323+
perror("fseek");
324+
res = fwrite(buffer1, blocksize, 1, fion);
325+
if (res != 1)
326+
perror("fwrite");
327+
}
328+
current = size - 1;
329+
length = size;
330+
331+
delete [] buffer1;
332+
delete [] buffer2;
333+
334+
fclose(fion);
335+
336+
}
337+
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
This file is part of Konsole, an X terminal.
3+
Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
4+
5+
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
6+
7+
This program is free software; you can redistribute it and/or modify
8+
it under the terms of the GNU General Public License as published by
9+
the Free Software Foundation; either version 2 of the License, or
10+
(at your option) any later version.
11+
12+
This program is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
GNU General Public License for more details.
16+
17+
You should have received a copy of the GNU General Public License
18+
along with this program; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20+
02110-1301 USA.
21+
*/
22+
23+
#ifndef BLOCKARRAY_H
24+
#define BLOCKARRAY_H
25+
26+
#include <unistd.h>
27+
28+
//#error Do not use in KDE 2.1
29+
30+
#define BlockSize (1 << 12)
31+
#define ENTRIES ((BlockSize - sizeof(size_t) ) / sizeof(unsigned char))
32+
33+
namespace Konsole
34+
{
35+
36+
struct Block {
37+
Block() { size = 0; }
38+
unsigned char data[ENTRIES];
39+
size_t size;
40+
};
41+
42+
// ///////////////////////////////////////////////////////
43+
44+
class BlockArray {
45+
public:
46+
/**
47+
* Creates a history file for holding
48+
* maximal size blocks. If more blocks
49+
* are requested, then it drops earlier
50+
* added ones.
51+
*/
52+
BlockArray();
53+
54+
/// destructor
55+
~BlockArray();
56+
57+
/**
58+
* adds the Block at the end of history.
59+
* This may drop other blocks.
60+
*
61+
* The ownership on the block is transfered.
62+
* An unique index number is returned for accessing
63+
* it later (if not yet dropped then)
64+
*
65+
* Note, that the block may be dropped completely
66+
* if history is turned off.
67+
*/
68+
size_t append(Block *block);
69+
70+
/**
71+
* gets the block at the index. Function may return
72+
* 0 if the block isn't available any more.
73+
*
74+
* The returned block is strictly readonly as only
75+
* maped in memory - and will be invalid on the next
76+
* operation on this class.
77+
*/
78+
const Block *at(size_t index);
79+
80+
/**
81+
* reorders blocks as needed. If newsize is null,
82+
* the history is emptied completely. The indices
83+
* returned on append won't change their semantic,
84+
* but they may not be valid after this call.
85+
*/
86+
bool setHistorySize(size_t newsize);
87+
88+
size_t newBlock();
89+
90+
Block *lastBlock() const;
91+
92+
/**
93+
* Convenient function to set the size in KBytes
94+
* instead of blocks
95+
*/
96+
bool setSize(size_t newsize);
97+
98+
size_t len() const { return length; }
99+
100+
bool has(size_t index) const;
101+
102+
size_t getCurrent() const { return current; }
103+
104+
private:
105+
void unmap();
106+
void increaseBuffer();
107+
void decreaseBuffer(size_t newsize);
108+
109+
size_t size;
110+
// current always shows to the last inserted block
111+
size_t current;
112+
size_t index;
113+
114+
Block *lastmap;
115+
size_t lastmap_index;
116+
Block *lastblock;
117+
118+
int ion;
119+
size_t length;
120+
121+
};
122+
123+
}
124+
125+
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.