bseek.c 986 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. vlong
  5. Bseek(Biobufhdr *bp, vlong offset, int base)
  6. {
  7. vlong n, d;
  8. switch(bp->state) {
  9. default:
  10. fprint(2, "Bseek: unknown state %d\n", bp->state);
  11. return Beof;
  12. case Bracteof:
  13. bp->state = Bractive;
  14. bp->icount = 0;
  15. bp->gbuf = bp->ebuf;
  16. case Bractive:
  17. n = offset;
  18. if(base == 1) {
  19. n += Boffset(bp);
  20. base = 0;
  21. }
  22. /*
  23. * try to seek within buffer
  24. */
  25. if(base == 0) {
  26. /*
  27. * if d is too large for an int, icount may wrap,
  28. * so we need to ensure that icount hasn't wrapped
  29. * and points within the buffer's valid data.
  30. */
  31. d = n - Boffset(bp);
  32. bp->icount += d;
  33. if(d <= bp->bsize && bp->icount <= 0 &&
  34. bp->ebuf - bp->gbuf >= -bp->icount)
  35. return n;
  36. }
  37. /*
  38. * reset the buffer
  39. */
  40. n = seek(bp->fid, n, base);
  41. bp->icount = 0;
  42. bp->gbuf = bp->ebuf;
  43. break;
  44. case Bwactive:
  45. Bflush(bp);
  46. n = seek(bp->fid, offset, base);
  47. break;
  48. }
  49. bp->offset = n;
  50. return n;
  51. }