2
This file is part of Konsole, an X terminal.
3
Copyright (C) 2000 by Stephan Kulow <coolo@kde.org>
5
Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
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.
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.
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
25
#include "BlockArray.h"
32
#include <sys/param.h>
37
static int blocksize = 0;
39
BlockArray::BlockArray()
44
lastmap_index(size_t(-1)),
45
lastblock(0), ion(-1),
48
// lastmap_index = index = current = size_t(-1);
50
blocksize = ((sizeof(Block) / getpagesize()) + 1) * getpagesize();
55
BlockArray::~BlockArray()
61
size_t BlockArray::append(Block * block)
68
if (current >= size) {
73
rc = lseek(ion, current * blocksize, SEEK_SET);
75
perror("HistoryBuffer::add.seek");
79
rc = write(ion, block, blocksize);
81
perror("HistoryBuffer::add.write");
97
size_t BlockArray::newBlock()
104
lastblock = new Block();
108
Block * BlockArray::lastBlock() const
113
bool BlockArray::has(size_t i) const
115
if (i == index + 1) {
122
if (index - i >= length) {
128
const Block * BlockArray::at(size_t i)
130
if (i == index + 1) {
134
if (i == lastmap_index) {
139
qDebug() << "BlockArray::at() i > index\n";
143
// if (index - i >= length) {
144
// kDebug(1211) << "BlockArray::at() index - i >= length\n";
148
size_t j = i; // (current - (index - i) + (index/size+1)*size) % size ;
153
Block * block = (Block *)mmap(0, blocksize, PROT_READ, MAP_PRIVATE, ion, j * blocksize);
155
if (block == (Block *)-1) {
166
void BlockArray::unmap()
169
int res = munmap((char *)lastmap, blocksize);
175
lastmap_index = size_t(-1);
178
bool BlockArray::setSize(size_t newsize)
180
return setHistorySize(newsize * 1024 / blocksize);
183
bool BlockArray::setHistorySize(size_t newsize)
185
// kDebug(1211) << "setHistorySize " << size << " " << newsize;
187
if (size == newsize) {
200
current = size_t(-1);
205
FILE * tmp = tmpfile();
207
perror("konsole: cannot open temp file.\n");
209
ion = dup(fileno(tmp));
211
perror("konsole: cannot dup temp file.\n");
221
lastblock = new Block();
226
if (newsize > size) {
231
decreaseBuffer(newsize);
232
ftruncate(ion, length*blocksize);
239
void moveBlock(FILE * fion, int cursor, int newpos, char * buffer2)
241
int res = fseek(fion, cursor * blocksize, SEEK_SET);
245
res = fread(buffer2, blocksize, 1, fion);
250
res = fseek(fion, newpos * blocksize, SEEK_SET);
254
res = fwrite(buffer2, blocksize, 1, fion);
258
// printf("moving block %d to %d\n", cursor, newpos);
261
void BlockArray::decreaseBuffer(size_t newsize)
263
if (index < newsize) { // still fits in whole
267
int offset = (current - (newsize - 1) + size) % size;
273
// The Block constructor could do somthing in future...
274
char * buffer1 = new char[blocksize];
276
FILE * fion = fdopen(dup(ion), "w+b");
279
perror("fdopen/dup");
284
if (current <= newsize) {
285
firstblock = current + 1;
291
for (size_t i = 0, cursor=firstblock; i < newsize; i++) {
292
oldpos = (size + cursor + offset) % size;
293
moveBlock(fion, oldpos, cursor, buffer1);
294
if (oldpos < newsize) {
301
current = newsize - 1;
310
void BlockArray::increaseBuffer()
312
if (index < size) { // not even wrapped once
316
int offset = (current + size + 1) % size;
317
if (!offset) { // no moving needed
321
// The Block constructor could do somthing in future...
322
char * buffer1 = new char[blocksize];
323
char * buffer2 = new char[blocksize];
326
int bpr = size; // blocks per run
328
if (size % offset == 0) {
333
FILE * fion = fdopen(dup(ion), "w+b");
335
perror("fdopen/dup");
342
for (int i = 0; i < runs; i++) {
343
// free one block in chain
344
int firstblock = (offset + i) % size;
345
res = fseek(fion, firstblock * blocksize, SEEK_SET);
349
res = fread(buffer1, blocksize, 1, fion);
354
for (int j = 1, cursor=firstblock; j < bpr; j++) {
355
cursor = (cursor + offset) % size;
356
newpos = (cursor - offset + size) % size;
357
moveBlock(fion, cursor, newpos, buffer2);
359
res = fseek(fion, i * blocksize, SEEK_SET);
363
res = fwrite(buffer1, blocksize, 1, fion);