#pragma implementation #include #include #include #include #include BufFile::BufFile() { io = 0; rewind(); } BufFile::BufFile(const char *name) { io = new bufio(::open(name,O_RDONLY)); rewind(); } void BufFile::open(int fd) { delete io; io = new bufio(fd); rewind(); } BufFile::~BufFile() { delete io; } void BufFile::rewind() { filesize = 0; eof = 0; pos.clear(); pos.add(0); if (io) io->seek(0); } long BufFile::offsetOf(int i) { if (i < 0 || !io) return 0; while (i >= pos.size()) { if (eof) return filesize; const char *p = (char *)io->read(filesize,0); int n = io->getcnt(); if (n <= 0) { // fprintf(stderr,"textfile::EOF\n"); eof = 1; return filesize; } const char *q = p; for (;;) { int len = n - (q - p); if (!len) break; if (*q != '\f' || q - p + filesize != pos[pos.size() - 1]) { q = (const char *)memchr(q,'\n',len); if (!q) break; } long bufoff = ++q - p + filesize; pos.add(bufoff); /* fprintf(stderr,"pos %ld\n",bufoff); */ } filesize += n; // fprintf(stderr,"textfile::filesize = %ld, idx = %d\n",filesize,i); } return pos[i]; } const char *BufFile::operator[](int i) { int offset = offsetOf(i); int size = offsetOf(i + 1) - offset; if (size == 0) return 0; char *p = (char *)io->read(offset,size); if (p) { if (*p == '\f') return "\f"; if (size > 1 && p[size - 2] == '\r') p[size - 2] = 0; // null terminate else p[size - 1] = 0; // null terminate } return p; } int BufFile::size() { if (eof) return pos.size(); (*this)[pos.size()]; int i = pos.size(); while (i > 0 && !(*this)[i-1]) --i; return i; } int BufFile::getfd() const { return io->getfd(); }