00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <assert.h>
00032
00033 #include "fblock.hpp"
00034 #include "xalloc.h"
00035 #include "uti.h"
00036
00037
00038
00039 FBlock::FBlock( VOID )
00040 {
00041 f = NULL;
00042 bTotSize = bPos = 0;
00043 borderpolicy = 0;
00044 stdinout=FALSE;
00045 }
00046
00047
00048
00049 VOID FBlock::setPos( LONG pos )
00050 {
00051 if (bPos==pos) return;
00052 bPos=pos;
00053 if (bPos<0) xfseek(f,bPos0,SEEK_SET);
00054 else if ((bPos>=bTotSize)&&(!stdinout)) xfseek(f,bPos0+bTotSize,SEEK_SET);
00055 else xfseek(f,bPos+bPos0,SEEK_SET);
00056 }
00057
00058
00059
00060
00061 VOID FBlock::attach( FILE* fBin, LONG N, UINT bp )
00062 {
00063 LONG l;
00064
00065 f = fBin;
00066 bTotSize = bPos = 0;
00067 stdinout=FALSE;
00068
00069 if (!f) return;
00070
00071 borderpolicy=bp;
00072 bPos0 = xftell(f);
00073 if (N!=-2) {
00074 xfseek(f,0,SEEK_END);
00075 l = xftell(f)-bPos0;
00076 }
00077 else l=0;
00078
00079 if (N==-1) {
00080 bTotSize = l;
00081 bTail = 0;
00082 } else if (N==-2) {
00083 bTotSize=0;
00084 bTail=0;
00085 stdinout=TRUE;
00086 } else {
00087 bTotSize = N;
00088 bTail = l - bTotSize;
00089
00090
00091 cdie_beep(bTail<0,"FBlock: invalid file size");
00092 }
00093
00094 if (!stdinout) xfseek(f,bPos0,SEEK_SET);
00095 bPos = 0;
00096 writeMode = FALSE;
00097 }
00098
00099
00100
00101 VOID FBlock::setRW( BOOL write )
00102 {
00103 if (writeMode!=write) {
00104 writeMode = write;
00105 if (!stdinout) xfseek(f,0,SEEK_CUR);
00106 }
00107 }
00108
00109
00110
00111 UINT FBlock::get( BYTE& byte )
00112 {
00113 if ((bPos>=0) && ((bPos<bTotSize)||stdinout)) {
00114 setRW(FALSE);
00115 xfread(&byte, sizeof(byte), 1, f);
00116 bPos++;
00117 return 1;
00118 }
00119 else {
00120 byte = 0;
00121 bPos++;
00122 return 0;
00123 }
00124 }
00125
00126
00127 #ifdef ORI
00128 UINT FBlock::get( BYTE* block, UINT len )
00129 {
00130 UINT n;
00131
00132 if ((bPos>=0) && (bPos<bTotSize)) {
00133 n = len;
00134 if (bPos+n>bTotSize)
00135 n = (UINT)(bTotSize-bPos);
00136 if (block) {
00137 setRW(FALSE);
00138 xfread(block, sizeof(BYTE), n, f);
00139 if (n<len)
00140 memset(block+n,0,len-n);
00141 }
00142 else
00143 xfseek(f,n,SEEK_CUR);
00144 bPos+=len;
00145 return n;
00146 }
00147
00148 if ((bPos<0)&&(-bPos<len)) {
00149 n = (UINT)(len+bPos);
00150 if (block) {
00151 setRW(FALSE);
00152 memset(block,0,len-n);
00153 xfread(block+len-n, sizeof(BYTE), n, f);
00154 }
00155 else
00156 xfseek(f,n,SEEK_CUR);
00157 bPos+=len;
00158 return n;
00159 }
00160
00161 bPos+=len;
00162 if (block)
00163 memset(block,0,len);
00164 return 0;
00165 }
00166 #endif
00167
00168
00169 UINT FBlock::get( BYTE* block, UINT len )
00170 {
00171 if ( ((bPos<0)&&(-bPos>=(LONG)len)) || ((bPos>=bTotSize)&&(!stdinout)) ) {
00172 bPos+=len;
00173 if (block) memset(block,0,len);
00174 return 0;
00175 }
00176
00177 if (bPos<0) {
00178 if (block) { memset(block,0,(UINT)(-bPos)); block+=(UINT)(-bPos); }
00179 len -= (UINT)(-bPos);
00180 bPos = 0;
00181 }
00182
00183 UINT n = len;
00184 if (!stdinout && (bPos+(LONG)n>bTotSize))
00185 n = (UINT)(bTotSize-bPos);
00186 if (block) {
00187 setRW(FALSE);
00188 UINT nn=fread(block, sizeof(BYTE), n, f);
00189 if ((!stdinout)&&(nn<n)) xfile_error("fread");
00190 if (nn<len) memset(block+nn,0,len-nn);
00191 if (nn<n) { len-=(n-nn); n=nn; };
00192 }
00193 else
00194 xfseek(f,n,SEEK_CUR);
00195 bPos+=len;
00196 if ((stdinout)&&(bPos>bTotSize)) bTotSize=bPos;
00197 return n;
00198 }
00199
00200
00201
00202 UINT FBlock::set( const BYTE* block, UINT len )
00203 {
00204 UINT n=0;
00205
00206 if (bPos<0) {
00207 if (-bPos>=(LONG)len) { bPos += (LONG)len; return 0; }
00208 len -= (UINT)(-bPos);
00209 if (block) block += (UINT)(-bPos);
00210 bPos = 0;
00211 }
00212
00213 if (bPos<bTotSize) {
00214 n=len;
00215 if (bPos+(LONG)n>bTotSize) n = (UINT)(bTotSize-bPos);
00216 setRW(TRUE);
00217 if (block)
00218 xfwrite(block,sizeof(BYTE),n,f);
00219 else {
00220 UINT i;
00221 BYTE bb=0;
00222 for (i=0; i<n; i++) xfwrite(&bb,sizeof(BYTE),1,f);
00223 }
00224 bPos+=n;
00225 len-=n;
00226 block+=n;
00227 }
00228 if (!len) return n;
00229
00230 if ((bPos>bTotSize)&&(!(borderpolicy&FBLOCK_BP_AFTER))&&(!stdinout)) {
00231 bPos+=len;
00232 return n;
00233 }
00234
00235 BYTE bb=0;
00236 LONG i;
00237 if (bTail>0) {
00238 xfinsn(f,bPos0+bTotSize,(bPos-bTotSize+len));
00239 xfseek(f,bPos0+bTotSize,SEEK_SET);
00240 writeMode = TRUE;
00241 }
00242 else
00243 setRW(TRUE);
00244
00245 for (i=bTotSize; i<bPos; i++) xfwrite(&bb,sizeof(bb),1,f);
00246
00247 if (block) xfwrite(block,sizeof(BYTE),len,f);
00248 else for (UINT j=0; j<len; j++) xfwrite(&bb,sizeof(BYTE),1,f);
00249
00250 bPos+=len;
00251 bTotSize = bPos;
00252
00253 return len+n;
00254 }
00255
00256
00257
00258 UINT FBlock::ins( const BYTE* block, UINT len )
00259 {
00260 BYTE bb=0;
00261 UINT i, p;
00262
00263 if (stdinout) {
00264 if (bPos>=bTotSize) return set(block,len);
00265 else return 0;
00266 }
00267
00268 if (bPos<0) {
00269 if (borderpolicy&FBLOCK_BP_BEFORE) {
00270 xfinsn(f,bPos0,len);
00271 xfseek(f,bPos0,SEEK_SET);
00272 if (bPos+len>0) {
00273 p = (UINT)(len+bPos);
00274 if (block) xfwrite(block+(UINT)(-bPos),sizeof(BYTE),p,f);
00275 else for ( i=0; i<p; i++) xfwrite(&bb,sizeof(bb),1,f);
00276 }
00277 else p=0;
00278 for ( i=p; i<len; i++) xfwrite(&bb,sizeof(bb),1,f);
00279 xfseek(f,bPos0+p,SEEK_SET);
00280 writeMode = TRUE;
00281 bTotSize+=len;
00282 bPos+=len;
00283 return len;
00284 }
00285 else {
00286 if (bPos+len>0) {
00287 p = (UINT)(len+bPos);
00288 xfinsn(f,bPos0,p);
00289 xfseek(f,bPos0,SEEK_SET);
00290 if (block) xfwrite(block+(UINT)(-bPos),sizeof(BYTE),p,f);
00291 else for ( i=0; i<p; i++) xfwrite(&bb,sizeof(bb),1,f);
00292 bTotSize+=p;
00293 bPos+=len;
00294 return p;
00295 }
00296 bPos+=len;
00297 return 0;
00298 }
00299 }
00300
00301 if (bPos<=bTotSize) {
00302 if (((bPos<bTotSize)||(bTail>0))) {
00303 xfinsn(f,bPos0+bPos,len);
00304 xfseek(f,bPos0+bPos,SEEK_SET);
00305 writeMode = TRUE;
00306 }
00307 else
00308 setRW(TRUE);
00309 if (block) xfwrite(block,sizeof(BYTE),len,f);
00310 else for (i=0; i<len; i++) xfwrite(&bb,sizeof(bb),1,f);
00311 bTotSize+=len;
00312 bPos+=len;
00313 return len;
00314 }
00315
00316 if (borderpolicy&FBLOCK_BP_AFTER) {
00317 LONG j;
00318 if (bTail>0) xfinsn(f,bPos0+bTotSize,(bPos-bTotSize+len));
00319 xfseek(f,bPos0+bTotSize,SEEK_SET);
00320 for (j=bTotSize; j<bPos; j++) xfwrite(&bb,sizeof(bb),1,f);
00321 writeMode = TRUE;
00322 if (block) xfwrite(block,sizeof(BYTE),len,f);
00323 else for (i=0; i<len; i++) xfwrite(&bb,sizeof(bb),1,f);
00324 bPos+=len;
00325 bTotSize=bPos;
00326 return len;
00327 }
00328 bPos+=len;
00329 return 0;
00330 }
00331
00332
00333
00334 UINT FBlock::del( UINT len )
00335 {
00336 if (bPos>=bTotSize) return 0;
00337 if (stdinout) return 0;
00338 if ((bPos<0)&&(!(borderpolicy&FBLOCK_BP_BEFORE))) return 0;
00339
00340 LONG pos=bPos;
00341 if (pos<0) pos=0;
00342
00343 if (pos+(LONG)len>bTotSize) len = (UINT)(bTotSize-pos);
00344
00345 xfdeln(f,bPos0+pos,len);
00346 xfseek(f,bPos0+pos,SEEK_SET);
00347 bTotSize-=len;
00348 return len;
00349 }
00350
00351
00352
00353
00354 VOID FBlock::toggleRW( VOID )
00355 {
00356 xfseek(f,0,SEEK_CUR);
00357 }
00358
00359
00360
00361 BOOL FBlock::OK( VOID ) const
00362 {
00363 long pos;
00364 long len;
00365
00366 if (!f) return TRUE;
00367 if (stdinout) return TRUE;
00368
00369 pos = xftell(f);
00370 xfseek(f,0,SEEK_END);
00371 len = xftell(f);
00372 xfseek(f,pos,SEEK_SET);
00373
00374 if (bPos+bPos0!=pos) return FALSE;
00375 if (bPos0+bTotSize+bTail!=len) return FALSE;
00376
00377 return TRUE;
00378 }
00379
00380