Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

TEHistory.cpp

Go to the documentation of this file.
00001 /* -------------------------------------------------------------------------- */
00002 /*                                                                            */
00003 /* [TEHistory.C]                   History Buffer                             */
00004 /*                                                                            */
00005 /* -------------------------------------------------------------------------- */
00006 /*                                                                            */
00007 /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>            */
00008 /*                                                                            */
00009 /* This file is part of Konsole - an X terminal for KDE                       */
00010 /*                                                                            */
00011 /* -------------------------------------------------------------------------- */
00012 /*                                                                            */
00013 /* Ported Konsole to Qt/Embedded                                              */
00014 /*                                                                            */
00015 /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com>                  */
00016 /*                                                                            */
00017 /* -------------------------------------------------------------------------- */
00018 
00019 #include "TEHistory.h"
00020 #include <stdlib.h>
00021 #include <assert.h>
00022 #include <stdio.h>
00023 #include <sys/types.h>
00024 #include <unistd.h>
00025 #include <errno.h>
00026 
00027 #define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
00028 
00029 /*
00030    An arbitrary long scroll.
00031 
00032    One can modify the scroll only by adding either cells
00033    or newlines, but access it randomly.
00034 
00035    The model is that of an arbitrary wide typewriter scroll
00036    in that the scroll is a serie of lines and each line is
00037    a serie of cells with no overwriting permitted.
00038 
00039    The implementation provides arbitrary length and numbers
00040    of cells and line/column indexed read access to the scroll
00041    at constant costs.
00042 
00043 FIXME: some complain about the history buffer comsuming the
00044        memory of their machines. This problem is critical
00045        since the history does not behave gracefully in cases
00046        where the memory is used up completely.
00047 
00048        I put in a workaround that should handle it problem
00049        now gracefully. I'm not satisfied with the solution.
00050 
00051 FIXME: Terminating the history is not properly indicated
00052        in the menu. We should throw a signal.
00053 
00054 FIXME: There is noticable decrease in speed, also. Perhaps,
00055        there whole feature needs to be revisited therefore.
00056        Disadvantage of a more elaborated, say block-oriented
00057        scheme with wrap around would be it's complexity.
00058 */
00059 
00060 //FIXME: tempory replacement for tmpfile
00061 //       this is here one for debugging purpose.
00062 
00063 //#define tmpfile xTmpFile
00064 
00065 FILE* xTmpFile()
00066 {
00067   static int fid = 0;
00068   char fname[80];
00069   sprintf(fname,"TmpFile.%d",fid++);
00070   return fopen(fname,"w");
00071 }
00072 
00073 
00074 // History Buffer ///////////////////////////////////////////
00075 
00076 /*
00077    A Row(X) data type which allows adding elements to the end.
00078 */
00079 
00080 HistoryBuffer::HistoryBuffer()
00081 {
00082   ion    = -1;
00083   length = 0;
00084 }
00085 
00086 HistoryBuffer::~HistoryBuffer()
00087 {
00088   setScroll(FALSE);
00089 }
00090 
00091 void HistoryBuffer::setScroll(bool on)
00092 {
00093   if (on == hasScroll()) return;
00094 
00095   if (on)
00096   {
00097     assert( ion < 0 );
00098     assert( length == 0);
00099     FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; }
00100     ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
00101     fclose(tmp);
00102   }
00103   else
00104   {
00105     assert( ion >= 0 );
00106     close(ion);
00107     ion    = -1;
00108     length = 0;
00109   }
00110 }
00111 
00112 bool HistoryBuffer::hasScroll()
00113 {
00114   return ion >= 0;
00115 }
00116 
00117 void HistoryBuffer::add(const unsigned char* bytes, int len)
00118 { int rc;
00119   assert(hasScroll());
00120   rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; }
00121   rc = write(ion,bytes,len);       if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; }
00122   length += rc;
00123 }
00124 
00125 void HistoryBuffer::get(unsigned char* bytes, int len, int loc)
00126 { int rc;
00127   assert(hasScroll());
00128   if (loc < 0 || len < 0 || loc + len > length)
00129     fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
00130   rc = lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; }
00131   rc = read(ion,bytes,len);     if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; }
00132 }
00133 
00134 int HistoryBuffer::len()
00135 {
00136   return length;
00137 }
00138 
00139 // History Scroll //////////////////////////////////////
00140 
00141 /* 
00142    The history scroll makes a Row(Row(Cell)) from
00143    two history buffers. The index buffer contains
00144    start of line positions which refere to the cells
00145    buffer.
00146 
00147    Note that index[0] addresses the second line
00148    (line #1), while the first line (line #0) starts
00149    at 0 in cells.
00150 */
00151 
00152 HistoryScroll::HistoryScroll()
00153 {
00154 }
00155 
00156 HistoryScroll::~HistoryScroll()
00157 {
00158 }
00159  
00160 void HistoryScroll::setScroll(bool on)
00161 {
00162   index.setScroll(on);
00163   cells.setScroll(on);
00164 }
00165  
00166 bool HistoryScroll::hasScroll()
00167 {
00168   return index.hasScroll() && cells.hasScroll();
00169 }
00170 
00171 int HistoryScroll::getLines()
00172 {
00173   if (!hasScroll()) return 0;
00174   return index.len() / sizeof(int);
00175 }
00176 
00177 int HistoryScroll::getLineLen(int lineno)
00178 {
00179   if (!hasScroll()) return 0;
00180   return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca);
00181 }
00182 
00183 int HistoryScroll::startOfLine(int lineno)
00184 {
00185   if (lineno <= 0) return 0;
00186   if (!hasScroll()) return 0;
00187   if (lineno <= getLines())
00188   { int res;
00189     index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
00190     return res;
00191   }
00192   return cells.len();
00193 }
00194 
00195 void HistoryScroll::getCells(int lineno, int colno, int count, ca res[])
00196 {
00197   assert(hasScroll());
00198   cells.get((unsigned char*)res,count*sizeof(ca),startOfLine(lineno)+colno*sizeof(ca));
00199 }
00200 
00201 void HistoryScroll::addCells(ca text[], int count)
00202 {
00203   if (!hasScroll()) return;
00204   cells.add((unsigned char*)text,count*sizeof(ca));
00205 }
00206 
00207 void HistoryScroll::addLine()
00208 {
00209   if (!hasScroll()) return;
00210   int locn = cells.len();
00211   index.add((unsigned char*)&locn,sizeof(int));
00212 }

Generated on Sat Nov 5 16:15:27 2005 for OPIE by  doxygen 1.4.2