4
* All rights reserved. Copyright (C) 1996 by NARITA Tomio.
5
* $Id: fetch.c,v 1.7 2004/01/05 07:30:15 nrt Exp $
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 2 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38
* $B8=:_$N%U%!%$%k%]%$%s%?$+$i(B 1$B9T$r%m!<%I$7(B,
39
* $B%G%3!<%I$7$F(B (istr $B$KJQ49$7$F(B) $BJ*M}9T$K!X>v$_9~$_!Y(B,
40
* $B%5!<%A$,@_Dj$5$l$F$$$l$P%5!<%A$r<B9T$9$k(B.
41
* $B$9$Y$F$N7k2L$O%-%c%C%7%e$K=q$-9~$`(B.
43
* $BFI$_9~$`$Y$-%U%!%$%kFbMF$,$J$1$l$P(B FALSE $B$rJV$9(B.
45
* $BJ*M}9T$O(B fetch $B$K$h$C$F!X@8@.!Y$5$l$k(B.
48
private boolean_t LineDecode( file_t *f, int page, line_t *line )
50
int idx, w, width, hptr, line_size;
54
str = FileLoadLine( f, &idx, &simple );
58
line_size = idx / 16 + 1; /* physical lines per logical line */
61
IstrFree( line->istr );
65
line->head = (head_t *)Malloc( sizeof( head_t ) * line_size );
68
line->istr = DecodeSimple( IstrAlloc( page, idx + 1 ),
76
if( hptr >= line_size - 1 ){
79
line_truncated = TRUE;
82
line->head[ hptr ].width = f->width;
83
line->head[ hptr++ ].ptr = w;
88
line->istr = Decode( IstrAlloc( page, idx + 1 ),
89
f->inputCodingSystem, str, &idx );
94
for( idx = 0 ; NOSET != line->istr[ idx ].charset ; idx++ ){
95
if( HTAB == line->istr[ idx ].charset ){
96
w = HTAB_WIDTH - width % HTAB_WIDTH;
97
line->istr[ idx ].c &= 0x00ff;
98
line->istr[ idx ].c |= ( w << 8 );
99
if( width + w == f->width ){
100
if( hptr >= line_size - 1 ){
102
line_truncated = TRUE;
105
line->head[ hptr ].width = width;
106
line->head[ hptr++ ].ptr = idx + 1;
111
w = IcharWidth( line->istr[ idx ].charset, line->istr[ idx ].c );
113
if( width + w > f->width ){
114
if( hptr >= line_size - 1 ){
115
line_truncated = TRUE;
118
line->head[ hptr ].width = width;
119
line->head[ hptr++ ].ptr = idx;
127
line->head[ hptr ].width = width;
128
line->head[ hptr++ ].ptr = idx;
131
line->head = (head_t *)realloc( line->head, sizeof( head_t ) * hptr );
132
if( NULL == line->head ){
133
fprintf( stderr, "lv: realloc() failed\n" );
137
if( NULL != f->find.pattern )
138
(*find_func)( line );
144
* $B;XDj$5$l$?%U%!%$%k%]%$%s%?$+$i(B 1$B%Z!<%8$r%m!<%I$9$k(B.
146
* $BFI$_=P$7Cf$K(B EOF $B$r8+$D$1$?$i(B, $B$=$3$G%Z!<%8$N%m!<%I$rCfCG$7(B,
147
* $B9T?t$r%-%c%C%7%e$K3JG<$9$k(B.
150
private void PageLoad( file_t *f, int block, long ptr )
154
if( fseek( f->fp, ptr, SEEK_SET ) )
155
perror( "PageLoad()" ), exit( -1 );
158
for( i = 0 ; i < LV_PAGE_SIZE ; i++ ){
161
if( FALSE == LineDecode( f, block, &f->page[ block ].line[ i ] ) )
165
f->page[ block ].lines = i;
169
* $B;XDj$7$?%Z!<%8$,%Z!<%8%-%c%C%7%eFb$K$"$k$3$H$rJ]>Z$9$k(B.
170
* $B%Z!<%8%-%c%C%7%e$K$J$$>l9g(B, $B%U%!%$%k$+$i%-%c%C%7%e$X%m!<%I$7$J$*$9(B.
173
public boolean_t FetchLine( file_t *f, unsigned int segment, int offset )
177
if( segment >= f->lastSegment ){
178
if( FALSE == FileStretch( f, segment ) )
182
block = Block( segment );
184
if( FALSE == f->used[ block ] || segment != f->page[ block ].segment ){
185
if( TRUE == f->used[ block ] ){
186
for( line = 0 ; line < LV_PAGE_SIZE ; line++ ){
187
if( NULL != f->page[ block ].line[ line ].head ){
188
free( f->page[ block ].line[ line ].head );
189
f->page[ block ].line[ line ].head = NULL;
191
if( NULL != f->page[ block ].line[ line ].istr ){
192
IstrFree( f->page[ block ].line[ line ].istr );
193
f->page[ block ].line[ line ].istr = NULL;
196
IstrFreeZone( block );
198
PageLoad( f, block, f->slot[ Frame( segment ) ][ Slot( segment ) ] );
199
f->page[ block ].segment = segment;
200
f->used[ block ] = TRUE;
203
if( f->page[ block ].lines <= offset )