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

history.cpp

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

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