Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

httext.cc

Go to the documentation of this file.
00001 /* 
00002  *      HT Editor
00003  *      httext.cc
00004  *
00005  *      Copyright (C) 1999-2002 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "htsearch.h"
00022 #include "httext.h"
00023 #include "stream.h"
00024 
00025 #include <string.h>
00026 
00027 ht_view *httext_init(bounds *b, ht_streamfile *file, ht_format_group *group)
00028 {
00029         ht_text_viewer2 *v=new ht_text_viewer2();
00030         v->init(b, TEXT_DESC, 0/*VC_EDIT | VC_GOTO | VC_SEARCH | VC_BLOCKOP | VC_TRUNCATE*/, file, group);
00031 
00032         v->search_caps|=SEARCHMODE_BIN | SEARCHMODE_EVALSTR;
00033 
00034         ht_text_sub *t=new ht_text_sub();
00035         t->init(file, 0x0, file->get_size());
00036         v->insertsub(t);
00037         return v;
00038 }
00039 
00040 format_viewer_if httext_if = {
00041         httext_init,
00042         0
00043 };
00044 
00045 /*
00046  *      CLASS ht_text_viewer2
00047  */
00048 
00049 /*bool ht_text_viewer2::offset_to_pos(FILEOFS ofs, viewer_pos *pos)
00050 {
00051         pos->u.sub = first_sub;
00052         pos->u.line_id.id1 = ofs;
00053         pos->u.line_id.id2 = 0;
00054         pos->u.tag_idx = 0;
00055         pos->u.tag_group = 0;
00056         return true;
00057 }
00058 
00059 bool ht_text_viewer2::pos_to_offset(viewer_pos pos, FILEOFS *ofs)
00060 {
00061         *ofs = pos.u.line_id.id1;
00062         return true;
00063 }*/
00064 
00065 void ht_text_viewer2::handlemsg(htmsg *msg)
00066 {
00067         switch (msg->msg) {
00068                 case msg_keypressed:
00069                         switch (msg->data1.integer) {
00070                                 case K_Left: {
00071                                         // FIXME: send cmd_bla when available
00072                                         htmsg m;
00073                                         m.msg = msg_keypressed;
00074                                         m.type = mt_empty;
00075                                         m.data1.integer = K_Control_Left;
00076                                         sendmsg(&m);
00077                                         clearmsg(msg);
00078                                         return;
00079                                 }
00080                                 case K_Right: {
00081                                         // FIXME: send cmd_bla when available
00082                                         htmsg m;
00083                                         m.msg = msg_keypressed;
00084                                         m.type = mt_empty;
00085                                         m.data1.integer = K_Control_Right;
00086                                         sendmsg(&m);
00087                                         clearmsg(msg);
00088                                         return;
00089                                 }
00090                         }
00091                         break;
00092         }
00093         return ht_uformat_viewer::handlemsg(msg);
00094 }
00095 
00096 /*
00097  *      CLASS ht_text_sub
00098  */
00099 
00100 /* FIXME: put it somewhere else..., why ain't this a POSIX function ? */
00101 void *memrchr(const void *string, int ch, size_t num)
00102 {
00103         while (num--) {
00104                 if (((char*)string)[num]==ch) return ((char*)string)+num;
00105         }
00106         return NULL;
00107 }
00108  
00109 
00110 #define TEXT_SUB_READSIZE               256
00111 #define TEXT_SUB_MAX_LINELEN            512
00112 
00113 #define TEXT_SUB_MAX_LINEENDLEN 2
00114 
00115 #define TEXT_SUB_TABSIZE                        5
00116 
00117 byte ht_text_sub_line[TEXT_SUB_MAX_LINELEN];
00118 
00119 void ht_text_sub::init(ht_streamfile *file, FILEOFS offset, int size)
00120 {
00121         ht_linear_sub::init(file, offset, size);
00122 }
00123 
00124 void ht_text_sub::done()
00125 {
00126         ht_linear_sub::done();
00127 }
00128 
00129 bool ht_text_sub::convert_ofs_to_id(const FILEOFS offset, LINE_ID *line_id)
00130 {
00131         clear_line_id(line_id);
00132         line_id->id1 = offset;
00133         prev_line_id(line_id, 1);
00134         return true;
00135 }
00136 
00137 bool ht_text_sub::convert_id_to_ofs(const LINE_ID line_id, FILEOFS *offset)
00138 {
00139         return false;
00140 }
00141 
00142 UINT ht_text_sub::find_linelen_backwd(byte *buf, UINT maxbuflen, FILEOFS ofs, int *le_len)
00143 {
00144         UINT readlen=(maxbuflen>TEXT_SUB_READSIZE) ? TEXT_SUB_READSIZE : maxbuflen;
00145         UINT oreadlen=readlen;
00146         FILEOFS oofs=ofs;
00147         byte *bufp;
00148         UINT s;
00149         UINT len=0;
00150         UINT lineends=0;
00151 
00152         if (le_len) *le_len=0;
00153         do {
00154                 if (ofs==fofs) break;
00155                 if (readlen>ofs) readlen=ofs;
00156                 if (ofs-readlen<fofs) readlen=ofs-fofs;
00157                 ofs-=readlen;
00158                 file->seek(ofs);
00159 /* make sure current and next read overlap
00160    to guarantee proper lineend-matching */
00161                 if (readlen==oreadlen) ofs+=TEXT_SUB_MAX_LINEENDLEN-1; else
00162                         if (ofs+readlen+TEXT_SUB_MAX_LINEENDLEN-1<=oofs)
00163                                 readlen+=TEXT_SUB_MAX_LINEENDLEN-1;
00164                 s=file->read(buf, readlen);
00165                 int l;
00166                 bufp=match_lineend_backwd(buf, s, &l);
00167                 if (bufp) {
00168                         lineends++;
00169                         if (lineends==1) {
00170                                 bufp=match_lineend_backwd(buf, bufp-buf, &l);
00171                                 if (bufp) lineends++;
00172                         }
00173                         if (lineends==2) {
00174                                 len+=buf+s-bufp-1;
00175                                 if (len>TEXT_SUB_MAX_LINELEN) {
00176                                         len=TEXT_SUB_MAX_LINELEN;
00177                                         break;
00178                                 }
00179                                 if (le_len) *le_len=l;
00180                                 break;
00181                         }
00182                 }
00183                 len+=s;
00184                 if (len>TEXT_SUB_MAX_LINELEN) {
00185                         len=TEXT_SUB_MAX_LINELEN;
00186                         break;
00187                 }
00188         } while (s);
00189         return len;
00190 }
00191 
00192 UINT ht_text_sub::find_linelen_forwd(byte *buf, UINT maxbuflen, FILEOFS ofs, int *le_len)
00193 {
00194         UINT readlen=(maxbuflen>TEXT_SUB_READSIZE) ? TEXT_SUB_READSIZE : maxbuflen;
00195         byte *bufp;
00196         UINT s;
00197         UINT len = 0;
00198 
00199         if (le_len) *le_len = 0;
00200         do {
00201                 file->seek(ofs);
00202                 s = file->read(buf, readlen);
00203                 int l;
00204                 bufp = match_lineend_forwd(buf, s, &l);
00205                 if (bufp) {
00206                         len += bufp-buf+l;
00207                         if (le_len) *le_len = l;
00208                         break;
00209                 }
00210                 if (s != readlen) {
00211                         len += s;
00212                         break;
00213                 }
00214                 /* make sure current and next read overlap
00215                    to guarantee proper lineend-matching */
00216                 if (s > (TEXT_SUB_MAX_LINEENDLEN-1)) {
00217                         len += s-(TEXT_SUB_MAX_LINEENDLEN-1);
00218                 }
00219                 ofs += s-(TEXT_SUB_MAX_LINEENDLEN-1);
00220         } while (s == readlen);
00221         if (len > TEXT_SUB_MAX_LINELEN) {
00222                 len = TEXT_SUB_MAX_LINELEN;
00223                 if (le_len) *le_len = 0;
00224         }
00225         return len;
00226 }
00227 
00228 void ht_text_sub::first_line_id(LINE_ID *line_id)
00229 {
00230         clear_line_id(line_id);
00231         line_id->id1 = 0;
00232 }
00233 
00234 bool ht_text_sub::getline(char *line, const LINE_ID line_id)
00235 {
00236         byte *bufp = (byte*)line;
00237         FILEOFS ofs = line_id.id1;
00238         int ll;
00239         UINT l=find_linelen_forwd(ht_text_sub_line, sizeof ht_text_sub_line, ofs, &ll);
00240         if (l) {
00241                 l-=ll;
00242                 if (l>255) l=255;
00243                 file->seek(ofs);
00244                 l=file->read(line, l);
00245                 while (l--) {
00246                         if ((*bufp=='\e') || (*bufp==0)) *bufp='.';
00247                         bufp++;
00248                 }
00249                 *bufp=0;
00250                 return true;
00251         }
00252         return false;
00253 }
00254 
00255 void ht_text_sub::last_line_id(LINE_ID *line_id)
00256 {
00257         clear_line_id(line_id);
00258         FILEOFS ofs = fofs+fsize;
00259         UINT l = find_linelen_backwd(ht_text_sub_line, sizeof ht_text_sub_line, ofs, NULL);
00260         line_id->id1 = ofs-l;
00261 }
00262 
00263 byte *ht_text_sub::match_lineend_forwd(byte *buf, UINT buflen, int *le_len)
00264 {
00265         byte *result=NULL;
00266         
00267         byte *n=(byte*)memchr(buf, '\n', buflen);
00268         if (n) {
00269                 if ((n>buf) && (n[-1] == '\r')) {
00270                         *le_len=2;
00271                         result=n-1;
00272                 } else {
00273                         *le_len=1;
00274                         result=n;
00275                 }
00276         }
00277         return result;
00278 }
00279 
00280 byte *ht_text_sub::match_lineend_backwd(byte *buf, UINT buflen, int *le_len)
00281 {
00282         byte *result=NULL;
00283         
00284         byte *n=(byte*)memrchr(buf, '\n', buflen);
00285         if (n) {
00286                 if ((n>buf) && (n[-1] == '\r')) {
00287                         *le_len=2;
00288                         result=n-1;
00289                 } else {
00290                         *le_len=1;
00291                         result=n;
00292                 }
00293         }
00294         return result;
00295 }
00296 
00297 int ht_text_sub::next_line_id(LINE_ID *line_id, int n)
00298 {
00299         FILEOFS ofs = line_id->id1;
00300         int r=0;
00301         while (n--) {
00302                 UINT l=find_linelen_forwd(ht_text_sub_line, sizeof ht_text_sub_line, ofs, NULL);
00303                 ofs+=l;
00304                 if (!l) break;
00305                 r++;
00306         }
00307         line_id->id1 = ofs;
00308         return r;
00309 }
00310 
00311 int ht_text_sub::prev_line_id(LINE_ID *line_id, int n)
00312 {
00313         FILEOFS ofs = line_id->id1;
00314         int r=0;
00315         while (n--) {
00316                 UINT l=find_linelen_backwd(ht_text_sub_line, sizeof ht_text_sub_line, ofs, NULL);
00317                 ofs-=l;
00318                 if (!l) break;
00319                 r++;
00320         }
00321         line_id->id1 = ofs;
00322         return r;
00323 }
00324 

Generated on Fri May 7 21:15:37 2004 by doxygen 1.3.5