00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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, 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
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
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
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
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
00098
00099
00100
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
00160
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
00215
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