~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Frontier Kernel
Frontier/Common/source/findinfile.c

Version: ~ [ 10.0 ] ~

** Warning: Cannot open xref database.

1 2 /* $Id: findinfile.c,v 1.4 2005/01/11 22:48:05 andreradke Exp $ */ 3 4 /****************************************************************************** 5 6 UserLand Frontier(tm) -- High performance Web content management, 7 object database, system-level and Internet scripting environment, 8 including source code editing and debugging. 9 10 Copyright (C) 1992-2004 UserLand Software, Inc. 11 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; either version 2 of the License, or 15 (at your option) any later version. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software 24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 26 ******************************************************************************/ 27 28 #include "frontier.h" 29 #include "standard.h" 30 31 #include "error.h" 32 #include "memory.h" 33 #include "strings.h" 34 #include "file.h" 35 #include "lang.h" 36 #include "langinternal.h" 37 38 39 40 #define filebuffersize 1024 41 42 43 typedef struct tyopenfile { 44 45 tyfilespec fs; /*the file specifier*/ 46 47 hdlfilenum fnum; /*the file refnum*/ 48 49 Handle hbuffer; /*holds the file data*/ 50 51 long ixbuffer; /*points at the next character in the file*/ 52 53 long ctbufferbytes; /*number of valid chars in buffer*/ 54 55 long ctbytesleft; /*number of valid characters left unread*/ 56 57 long fpos; /*current file position*/ 58 59 struct tyopenfile **nextfile; 60 61 long refcon; 62 } tyopenfile, *ptropenfile, **hdlopenfile; 63 64 65 hdlopenfile hfirstfile = nil; /*header of file list*/ 66 67 68 69 static boolean loadbufferfromfile (hdlfilenum fnum, Handle hbuffer, long *ctbytes) { 70 71 boolean fl; 72 long ctread; 73 74 ctread = gethandlesize (hbuffer); 75 76 lockhandle (hbuffer); 77 78 fl = filereaddata (fnum, ctread, ctbytes, *hbuffer); 79 80 unlockhandle (hbuffer); 81 82 return (fl); 83 } /*loadbufferfromfile*/ 84 85 86 static boolean backupfilepos (hdlfilenum fnum, long ctbytes) { 87 88 long origfpos, newfpos; 89 boolean fl; 90 91 filegetposition (fnum, &origfpos); 92 93 if (origfpos >= ctbytes) 94 newfpos = origfpos - ctbytes; 95 else 96 newfpos = 0L; 97 98 fl = filesetposition (fnum, newfpos); 99 100 /* filegetposition (fnum, &newfpos); */ 101 102 return (fl); 103 } /*backupfilepos*/ 104 105 106 static void lowercasehandle (Handle h) { 107 108 lowertext ((ptrbyte) *h, gethandlesize (h)); 109 } /*lowercasehandle*/ 110 111 112 static boolean findopenfile (const tyfilespec *fs, hdlopenfile *hfile, hdlopenfile *hprev) { 113 114 register hdlopenfile x = hfirstfile; 115 116 *hfile = nil; 117 118 *hprev = nil; 119 120 while (true) { 121 122 if (x == nil) /*fell off list*/ 123 return (false); 124 125 if (equalfilespecs (fs, &(**x).fs)) { 126 127 *hfile = x; 128 129 return (true); 130 } 131 132 *hprev = x; 133 134 x = (**x).nextfile; 135 } /*while*/ 136 } /*findopenfile*/ 137 138 139 static void fifopenfileerror (const tyfilespec *fs) { 140 141 /* 142 5.0.1 dmb: new, additional error reporting 143 */ 144 145 bigstring bsfile; 146 147 getfsfile (fs, bsfile); 148 149 lang2paramerror (filenotopenederror, bsfunctionname, bsfile); 150 } /*fifopenfileerror*/ 151 152 153 #if 0 154 static OSErr openforkperm (const tyfilespec *fs, boolean flresource, short perm, hdlfilenum *fnum) { 155 156 OSErr errcode; 157 158 if (flresource) 159 errcode = FSpOpenRF (fs, perm, fnum); 160 else 161 errcode = FSpOpenDF (fs, perm, fnum); 162 163 return (errcode); 164 } /*openforkperm*/ 165 #endif 166 167 static boolean fileopener (const tyfilespec *fs, hdlopenfile *hfile, hdlfilenum *fnum) { 168 169 /* 170 2/13/92 dmb: changed fldontclose logic to something that actually works; 171 we no longer ignore opWrErr errors. instead, we try to open read/write, 172 but settle for read only. 173 174 1/25/93 dmb: instead of using fldontclose boolean, we return the hdlopenfile 175 if found. the new filecloser uses this to restore things properly 176 177 2.1b6 dmb: generate an oserror when a file can't be opened 178 */ 179 180 boolean fl; 181 hdlopenfile hprev; 182 183 if (findopenfile (fs, hfile, &hprev)) { /*file was already opened by us*/ 184 185 register hdlopenfile hf = *hfile; 186 long position; 187 188 filegetposition ((**hf).fnum, &position); 189 190 (**hf).fpos = position; 191 192 *fnum = (**hf).fnum; 193 194 return (true); 195 } 196 197 *hfile = nil; 198 199 disablelangerror (); 200 201 fl = openfile (fs, fnum, false); 202 203 enablelangerror(); 204 205 if (!fl) 206 fl = openfile (fs, fnum, true); 207 208 #ifdef NEWFILESPECTYPE 209 setoserrorparam ((ptrstring) (*fs).fullSpecifier); 210 #else 211 setoserrorparam ((ptrstring) (*fs).name); 212 #endif 213 214 return (fl); 215 } /*fileopener*/ 216 217 218 static boolean fileloadbuffer (hdlopenfile hf) { 219 220 /* 221 5.1.4 dmb: broke this out of fifread 222 */ 223 224 long ctbytes; 225 226 if (!loadbufferfromfile ((**hf).fnum, (**hf).hbuffer, &ctbytes)) { /*non-EOF error*/ 227 228 (**hf).ctbytesleft = 0; 229 230 return (false); 231 } 232 233 (**hf).ctbufferbytes = ctbytes; 234 235 (**hf).ixbuffer = 0; 236 237 return (true); 238 } /*fileloadbuffer*/ 239 240 241 static void filecloser (hdlopenfile hfile, hdlfilenum fnum) { 242 243 if (fnum != 0) { 244 245 if (hfile == nil) /*file wasn't already open*/ 246 closefile (fnum); 247 248 else /*need to restor file position*/ 249 filesetposition (fnum, (**hfile).fpos); 250 } 251 } /*filecloser*/ 252 253 254 boolean fiffindinfile (const tyfilespec *fs, bigstring pattern, long *index) { 255 256 /* 257 search for the indicated pattern in the file. return the index that the 258 match was found at, -1 if not found. 259 260 returns false if there was an error. 261 262 2/2/93 dmb: fixed off-by-one error; last character in string wasn't checked. 263 264 2.1b6 dmb: fixed infinite looping when partial matches were found 265 */ 266 267 hdlfilenum fnum = 0; 268 short lenpattern; 269 Handle hbuffer = nil; 270 long ctbytes; 271 long fpos = 0; 272 long oldctbytes; 273 boolean flreturned = false; 274 hdlopenfile hfile = nil; 275 276 *index = -1; /*indicate an error*/ 277 278 lenpattern = stringlength (pattern); 279 280 if (lenpattern == 0) { /*no error, but it wasn't found*/ 281 282 flreturned = true; 283 284 goto exit; 285 } 286 287 alllower (pattern); /*search is unicase*/ 288 289 if (!fileopener (fs, &hfile, &fnum)) 290 goto exit; 291 292 if (!largefilebuffer (&hbuffer)) /*couldn't allocate minimum buffer*/ 293 goto exit; 294 295 if (!loadbufferfromfile (fnum, hbuffer, &ctbytes)) 296 goto exit; 297 298 if (ctbytes == 0) { /*it's an empty file*/ 299 300 flreturned = true; 301 302 goto exit; 303 } 304 305 oldctbytes = ctbytes; 306 307 while (true) { 308 309 register char *pbuffer = *hbuffer; 310 register char *pbufferend = pbuffer + ctbytes; 311 register char chfirst = pattern [1]; 312 313 //lockhandle (hbuffer); 314 315 lowercasehandle (hbuffer); /*search is unicase*/ 316 317 while (pbuffer < pbufferend) { 318 319 if (*pbuffer++ == chfirst) { /*matched first character*/ 320 321 register short ixpattern; 322 register char *p = pbuffer; 323 324 for (ixpattern = 2; ixpattern <= lenpattern; ixpattern++) { 325 326 if (p >= pbufferend) { /*ran out of chars in the buffer*/ 327 328 --ixpattern; /*make it the number of chars already matched*/ 329 330 backupfilepos (fnum, (long) ixpattern); 331 332 fpos -= ixpattern; 333 334 goto reloadbuffer; 335 } 336 337 if (*p++ != pattern [ixpattern]) 338 goto fastloop; 339 340 } /*for*/ 341 342 *index = fpos + (pbuffer - *hbuffer - 1); 343 344 flreturned = true; 345 346 goto exit; 347 } /*first character matched*/ 348 349 fastloop: 350 ; 351 } /*for*/ 352 353 reloadbuffer: 354 355 //unlockhandle (hbuffer); 356 357 if (!loadbufferfromfile (fnum, hbuffer, &ctbytes)) 358 goto exit; 359 360 if (ctbytes < lenpattern) { /*not enough chars to look at*/ 361 362 flreturned = false; 363 364 goto exit; 365 } 366 367 fpos += oldctbytes; /*for computing returned value*/ 368 369 oldctbytes = ctbytes; 370 } /*while*/ 371 372 exit: 373 374 disposehandle (hbuffer); 375 376 filecloser (hfile, fnum); 377 378 return (flreturned); 379 } /*fiffindinfile*/ 380 381 382 boolean fifcomparefiles (const tyfilespec *fs1, const tyfilespec *fs2) { 383 384 /* 385 compare the two files byte-by-byte and return true if they are exactly 386 equal. only compares the data forks of the files. 387 */ 388 389 hdlfilenum fnum1 = 0, fnum2 = 0; 390 Handle hbuffer1 = nil, hbuffer2 = nil; 391 long ctbytes1, ctbytes2; 392 boolean flreturned = false; 393 hdlopenfile hfile1, hfile2; 394 395 if (!fileopener (fs1, &hfile1, &fnum1)) 396 goto exit; 397 398 if (!fileopener (fs2, &hfile2, &fnum2)) 399 goto exit; 400 401 if (!newclearhandle ((long) filebuffersize, &hbuffer1)) 402 goto exit; 403 404 if (!newclearhandle ((long) filebuffersize, &hbuffer2)) 405 goto exit; 406 407 while (true) { 408 409 register long ix; 410 register char *p1, *p2; 411 412 if (!loadbufferfromfile (fnum1, hbuffer1, &ctbytes1)) 413 goto exit; 414 415 if (!loadbufferfromfile (fnum2, hbuffer2, &ctbytes2)) 416 goto exit; 417 418 if (ctbytes1 == 0) { /**no more chars to look at*/ 419 420 flreturned = ctbytes2 == 0; /*true if it's also empty*/ 421 422 goto exit; 423 } 424 425 if (ctbytes1 != ctbytes2) { 426 427 flreturned = false; 428 429 goto exit; 430 } 431 432 //lockhandle (hbuffer1); 433 434 p1 = *hbuffer1; /*copy into register*/ 435 436 //lockhandle (hbuffer2); 437 438 p2 = *hbuffer2; /*copy into register*/ 439 440 for (ix = 0; ix < ctbytes1; ix++) { 441 442 if (*p1++ != *p2++) { 443 444 flreturned = false; 445 446 goto exit; 447 } 448 } /*for*/ 449 450 //unlockhandle (hbuffer1); 451 452 //unlockhandle (hbuffer2); 453 } /*while*/ 454 455 exit: 456 457 disposehandle (hbuffer1); 458 459 disposehandle (hbuffer2); 460 461 filecloser (hfile1, fnum1); 462 463 filecloser (hfile2, fnum2); 464 465 return (flreturned); 466 } /*fifcomparefiles*/ 467 468 469 boolean fifcharcounter (const tyfilespec *fs, char chlookfor, long *count) { 470 471 /* 472 searches the indicated file for the character. count returns with the number 473 of matches. set chlookfor to (char) 13 to get the number of carriage returns 474 or number of lines in the file. 475 */ 476 477 register long ctmatches = 0; 478 hdlfilenum fnum = 0; 479 Handle hbuffer = nil; 480 long ctbytes; 481 boolean flreturned = false; 482 hdlopenfile hfile = nil; 483 484 if (!fileopener (fs, &hfile, &fnum)) 485 goto exit; 486 487 if (!largefilebuffer (&hbuffer)) /*couldn't allocate minimum buffer*/ 488 goto exit; 489 490 if (!loadbufferfromfile (fnum, hbuffer, &ctbytes)) 491 goto exit; 492 493 if (ctbytes == 0) { /*it's an empty file*/ 494 495 flreturned = true; 496 497 goto exit; 498 } 499 500 while (true) { 501 502 register long ct = ctbytes; 503 register long ix; 504 register char *pbuffer; 505 register char ch = chlookfor; 506 507 //lockhandle (hbuffer); 508 509 pbuffer = *hbuffer; /*copy into register*/ 510 511 for (ix = 0; ix < ct; ix++) { 512 513 if (*pbuffer++ == ch) 514 ctmatches++; 515 } /*for*/ 516 517 //unlockhandle (hbuffer); 518 519 if (!loadbufferfromfile (fnum, hbuffer, &ctbytes)) 520 goto exit; 521 522 if (ctbytes == 0) { /*no more chars to look at*/ 523 524 flreturned = true; 525 526 goto exit; 527 } 528 } /*while*/ 529 530 exit: 531 532 *count = ctmatches; 533 534 disposehandle (hbuffer); 535 536 filecloser (hfile, fnum); 537 538 return (flreturned); 539 } /*fifcharcounter*/ 540 541 542 boolean fifclosefile (const tyfilespec *fs) { 543 544 /* 545 close the file indicated by fs. deallocate the record and buffer. close 546 it if it wasn't open when openfile was called. 547 */ 548 549 hdlopenfile hfile, hprev; 550 register hdlopenfile hf; 551 552 if (!findopenfile (fs, &hfile, &hprev)) { /*file isn't open*/ 553 554 fifopenfileerror (fs); 555 556 return (false); 557 } 558 559 hf = hfile; /*copy into register*/ 560 561 closefile ((**hf).fnum); 562 563 if (hprev == nil) 564 hfirstfile = (**hf).nextfile; 565 else 566 (**hprev).nextfile = (**hf).nextfile; 567 568 disposehandle ((**hf).hbuffer); 569 570 disposehandle ((Handle) hf); 571 572 return (true); 573 } /*fifclosefile*/ 574 575 576 boolean fifcloseallfiles (long refcon) { 577 578 register hdlopenfile x = hfirstfile; 579 register hdlopenfile hnext; 580 tyfilespec fs; 581 582 while (x != nil) { 583 584 hnext = (**x).nextfile; 585 586 if ((**x).refcon == refcon) { 587 588 fs = (**x).fs; 589 590 fifclosefile (&fs); 591 } 592 593 x = hnext; 594 } /*while*/ 595 596 return (true); 597 } /*fifcloseallfiles*/ 598 599 600 boolean fifopenfile (const tyfilespec *fs, long refcon) { 601 602 /* 603 open the indicated file, allocating a record and linking it into the list. 604 allocate a buffer. return true if the file could be opened. 605 606 10/31/91 dmb: check for eof when file is first opened 607 */ 608 609 hdlfilenum fnum; 610 hdlopenfile hfile = nil; 611 hdlopenfile hprev; 612 register hdlopenfile hf; 613 Handle hbuffer; 614 long eof; 615 616 if (findopenfile (fs, &hfile, &hprev)) /*file was already opened by us*/ 617 fifclosefile (fs); 618 619 if (!fileopener (fs, &hfile, &fnum)) 620 return (false); 621 622 if (!newclearhandle (sizeof (tyopenfile), (Handle *) &hfile)) 623 goto error; 624 625 if (!newclearhandle ((long) filebuffersize, &hbuffer)) 626 goto error; 627 628 hf = hfile; /*copy into register*/ 629 630 if (!filegeteof (fnum, &eof)) 631 goto error; 632 633 (**hf).ctbytesleft = eof; 634 635 (**hf).fnum = fnum; 636 637 (**hf).fs = *fs; 638 639 (**hf).nextfile = hfirstfile; /*insert at the head of the file list*/ 640 641 hfirstfile = hf; 642 643 (**hf).hbuffer = hbuffer; 644 645 (**hf).ixbuffer = filebuffersize; /*force file read on first getline/char*/ 646 647 (**hf).ctbufferbytes = filebuffersize; //do getposition will work 648 649 (**hf).refcon = refcon; 650 651 return (true); 652 653 error: 654 655 disposehandle ((**hfile).hbuffer); 656 657 disposehandle ((Handle) hfile); 658 659 return (false); 660 } /*fifopenfile*/ 661 662 663 boolean fifendoffile (const tyfilespec *fs) { 664 665 /* 666 return true if there's no more info in the file to be read. 667 */ 668 669 hdlopenfile h1, h2; 670 671 if (!findopenfile (fs, &h1, &h2)) 672 return (true); 673 674 return ((**h1).ctbytesleft <= 0); 675 } /*fifendoffile*/ 676 677 678 static boolean fifread (const tyfilespec *fs, byte eolmarker, long ctmax, Handle *hdata) { 679 680 /* 681 read a chunk of data from the indicated file to a maximum of ctmax bytes. 682 683 if eolmarker is non-zero, stop when a matching character is encountered. 684 685 5.0.2b3 dmb: ignore actual value of eolmarker; it's either chnul or not. If not, 686 look for any kind of line ending. 687 688 5.1.4 dmb: flstriplf handling gets smart about buffer boundaries. 689 */ 690 691 register Handle *x = hdata; 692 hdlopenfile hfile, hprev; 693 register hdlopenfile hf; 694 register long ctread = ctmax; 695 byte ch; 696 boolean flstriplf = false; 697 698 *x = nil; 699 700 if (!findopenfile (fs, &hfile, &hprev)) { /*file isn't open*/ 701 702 fifopenfileerror (fs); 703 704 return (false); 705 } 706 707 hf = hfile; /*copy into register*/ 708 709 while (true) { 710 711 register long ixbuffer = (**hf).ixbuffer; 712 register long ixend = (**hf).ctbufferbytes; 713 714 if (ixbuffer >= ixend) { /*ran out of chars in buffer*/ 715 716 if (!fileloadbuffer (hf)) { 717 718 disposehandle (*x); 719 720 *x = nil; 721 722 return (false); 723 } 724 725 ixbuffer = (**hf).ixbuffer; 726 727 ixend = (**hf).ctbufferbytes; 728 } 729 730 /* 731 first, see if first character is linefeed following previous cr 732 */ 733 734 /* 735 first, extract what we want out of current buffer 736 */ 737 738 ctread -= ixend - ixbuffer; /*start by planning to read entire buffer*/ 739 740 if (ctread < 0) /*too many bytes; bring ixend in to match*/ 741 ixend += ctread; 742 743 if (eolmarker != chnul) { /*see if eol is within range we're about to read*/ 744 745 register long ix; 746 register byte *buf = (byte *) *(**hf).hbuffer; 747 748 for (ix = ixbuffer; ix < ixend; ++ix) { 749 750 ch = buf [ix]; 751 752 if (ch == chreturn || ch == chlinefeed) { /*found it*/ 753 754 if (ch == chreturn) 755 flstriplf = true; 756 757 ixend = ix; /*shorten range*/ 758 759 ctread = 0; /*don't read no mo'*/ 760 761 break; 762 } 763 } 764 } 765 766 bundle { /*move the data*/ 767 768 register Handle buf = (**hf).hbuffer; 769 register long ct = ixend - ixbuffer; 770 771 if (*x == nil) { /*first time thru loop*/ 772 773 long ix = ixbuffer; 774 775 if (!loadfromhandletohandle (buf, &ix, ct, false, x)) 776 return (false); 777 } 778 else { 779 780 long ctbytes = gethandlesize (*x); 781 782 if (!sethandlesize (*x, ctbytes + ct)) { 783 784 disposehandle (*x); 785 786 *x = nil; 787 788 return (false); 789 } 790 791 moveleft (*buf + ixbuffer, **x + ctbytes, ct); 792 } 793 794 (**hf).ctbytesleft -= ct; 795 } 796 797 (**hf).ixbuffer = ixend; /*where we left off*/ 798 799 if (ctread <= 0) { /*we're done!*/ 800 801 if (eolmarker != chnul) { /*make sure we skip past the marker*/ 802 803 ++(**hf).ixbuffer; 804 805 --(**hf).ctbytesleft; 806 807 if (flstriplf) { // strip next character if it's a linefeed 808 809 if (((**hf).ixbuffer < (**hf).ctbufferbytes) || fileloadbuffer (hf)) { // more chars 810 811 if ((*(**hf).hbuffer) [(**hf).ixbuffer] == chlinefeed) { 812 813 ++(**hf).ixbuffer; 814 815 --(**hf).ctbytesleft; 816 } 817 } 818 } 819 } 820 821 return (true); 822 } 823 824 /* 825 buffer is now depleted; try to move on to next 826 */ 827 828 if ((**hf).ctbytesleft <= 0) /*we've emptied last buffer*/ 829 return (true); 830 } /*while*/ 831 } /*fifread*/ 832 833 834 835 boolean fifreadline (const tyfilespec *fs, Handle *linestring) { 836 837 /* 838 read a line of text from the indicated file. 839 */ 840 841 return (fifread (fs, chreturn, longinfinity, linestring)); 842 } /*fifreadline*/ 843 844 845 boolean fifreadhandle (const tyfilespec *fs, long ctbytes, Handle *x) { 846 847 /* 848 read a chunk of data from the indicated file. 849 */ 850 851 return (fifread (fs, chnul, ctbytes, x)); 852 } /*fifreadhandle*/ 853 854 855 boolean fifwritehandle (const tyfilespec *fs, Handle x) { 856 857 /* 858 write some data at the end of the indicated file. it may be slow, but it's 859 very easy to use! then again it might not be slow. 860 */ 861 862 boolean fl; 863 hdlopenfile hfile; 864 hdlfilenum fnum; 865 long ctbytes = gethandlesize (x); 866 long eofPos; 867 868 if (ctbytes == 0) /*nothing to write*/ 869 return (true); 870 871 if (!fileopener (fs, &hfile, &fnum)) 872 return (false); 873 874 filegeteof (fnum, &eofPos); 875 876 filesetposition (fnum, eofPos); /*position at the end of the file*/ 877 878 fl = filewrite (fnum, ctbytes, *x); /*this call does not move memory*/ 879 880 filecloser (hfile, fnum); 881 882 return (fl); 883 } /*fifwritehandle*/ 884 885 886 boolean fifwriteline (const tyfilespec *fs, Handle linestring) { 887 888 /* 889 write a line at the end of the indicated file. 890 */ 891 892 #ifdef WIN95VERSION 893 byte bseol [] = "\002\r\n"; 894 #endif 895 #ifdef MACVERSION 896 byte bseol [] = "\001\r"; 897 #endif 898 899 if (!pushtexthandle (bseol, linestring)) 900 return (false); 901 902 return (fifwritehandle (fs, linestring)); 903 } /*fifwriteline*/ 904 905 906 boolean fifsetposition (const tyfilespec *fs, long pos) { 907 908 /* 909 5.0.1 dmb: new function. don't bother optimizing case where we're 910 repositioning withing the current buffer. In most cases, we'll be 911 called once, before any read operations. 912 */ 913 914 hdlopenfile hfile, hprev; 915 register hdlopenfile hf; 916 long eof; 917 918 if (!findopenfile (fs, &hfile, &hprev)) { /*file isn't open*/ 919 920 fifopenfileerror (fs); 921 922 return (false); 923 } 924 925 hf = hfile; /*copy into register*/ 926 927 if (!filesetposition ((**hf).fnum, pos)) 928 return (false); 929 930 if (filegeteof ((**hf).fnum, &eof)) 931 (**hf).ctbytesleft = eof - pos; 932 933 (**hf).ixbuffer = filebuffersize; /*force file read on first getline/char*/ 934 935 (**hf).ctbufferbytes = filebuffersize; //so getposition will work 936 937 return (true); 938 } /*fifsetposition*/ 939 940 941 boolean fifgetposition (const tyfilespec *fs, long *pos) { 942 943 /* 944 5.0.1 dmb: new function 945 946 5.1.5 dmb: account for unread buffer bytes 947 */ 948 949 hdlopenfile hfile, hprev; 950 register hdlopenfile hf; 951 952 if (!findopenfile (fs, &hfile, &hprev)) { /*file isn't open*/ 953 954 fifopenfileerror (fs); 955 956 return (false); 957 } 958 959 hf = hfile; /*copy into register*/ 960 961 if (!filegetposition ((**hf).fnum, pos)) // next read will go from current file pos 962 return (false); 963 964 *pos -= (**hf).ctbufferbytes - (**hf).ixbuffer; // virtual pos is within already-read buffer 965 966 return (true); 967 } /*fifgetposition*/ 968 969 970 boolean fifsetendoffile (const tyfilespec *fs, long eof) { 971 972 /* 973 set the eof for the file, opening & closing it if necessary 974 975 5.0.1 dmb: reset ctbytesleft after changing the eof 976 977 5.0.2 dmb: pin fpos after changing eof 978 979 2003-05-26 AR: only update ctbytesleft and fpos if hfile is not nil. 980 It can be nil if the file was not already open. 981 */ 982 983 boolean fl; 984 hdlopenfile hfile; 985 hdlfilenum fnum; 986 987 if (!fileopener (fs, &hfile, &fnum)) 988 return (false); 989 990 fl = fileseteof (fnum, eof); 991 992 if (fl && hfile != nil) { 993 994 (**hfile).ctbytesleft = max (0, eof - (**hfile).fpos); 995 996 (**hfile).fpos = min ((**hfile).fpos, eof); 997 } 998 999 filecloser (hfile, fnum); 1000 1001 return (fl); 1002 } /*fifseteof*/ 1003 1004 1005 boolean fifgetendoffile (const tyfilespec *fs, long *eof) { 1006 1007 /* 1008 set the eof for the file, opening & closing it if necessary 1009 1010 5.0.1 dmb: reset ctbytesleft after changing the eof 1011 */ 1012 1013 boolean fl; 1014 hdlopenfile hfile; 1015 hdlfilenum fnum; 1016 1017 if (!fileopener (fs, &hfile, &fnum)) 1018 return (false); 1019 1020 fl = filegeteof (fnum, eof); 1021 1022 filecloser (hfile, fnum); 1023 1024 return (fl); 1025 } /*fifseteof*/ 1026 1027 1028 1029 1030 1031

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.