int linear_search_item_iterator::next(const linear_searcher &searcher, const char **startp, int *lengthp, reference_id *ridp) { const char *bufstart = lsi->fbuf.get_start(); const char *bufend = lsi->fbuf.get_end(); const char *ptr = bufstart + pos; if (ptr < bufend && searcher.search(ptr, bufend, startp, lengthp)) { pos = *startp + *lengthp - bufstart; if (ridp) *ridp = reference_id(lsi->filename_id, *startp - bufstart); return 1; } else return 0; }
int index_search_item_iterator::get_tag(int tagno, const linear_searcher &searchr, const char **pp, int *lenp, reference_id *ridp) { if (tagno < 0 || tagno >= indx->header.tags_size) { error("bad tag number"); return 0; } tag *tp = indx->tags + tagno; const char *filename = indx->munge_filename(indx->pool + tp->filename_index); int fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { error("can't open `%1': %2", filename, strerror(errno)); return 0; } struct stat sb; if (fstat(fd, &sb) < 0) { error("can't fstat: %1", strerror(errno)); close(fd); return 0; } time_t mtime = sb.st_mtime; if (mtime > indx->mtime) { indx->add_out_of_date_file(fd, filename, indx->filename_id + tp->filename_index); return 0; } int res = 0; FILE *fp = fdopen(fd, FOPEN_RB); if (!fp) { error("fdopen failed"); close(fd); return 0; } if (tp->start != 0 && fseek(fp, long(tp->start), 0) < 0) error("can't seek on `%1': %2", filename, strerror(errno)); else { int length = tp->length; int err = 0; if (length == 0) { if (fstat(fileno(fp), &sb) < 0) { error("can't stat `%1': %2", filename, strerror(errno)); err = 1; } else if (!S_ISREG(sb.st_mode)) { error("`%1' is not a regular file", filename); err = 1; } else length = int(sb.st_size); } if (!err) { if (length + 2 > buflen) { a_delete buf; buflen = length + 2; buf = new char[buflen]; } if (fread(buf + 1, 1, length, fp) != (size_t)length) error("fread on `%1' failed: %2", filename, strerror(errno)); else { buf[0] = '\n'; // Remove the CR characters from CRLF pairs. int sidx = 1, didx = 1; for ( ; sidx < length + 1; sidx++, didx++) { if (buf[sidx] == '\r') { if (buf[++sidx] != '\n') buf[didx++] = '\r'; else length--; } if (sidx != didx) buf[didx] = buf[sidx]; } buf[length + 1] = '\n'; res = searchr.search(buf + 1, buf + 2 + length, pp, lenp); if (res && ridp) *ridp = reference_id(indx->filename_id + tp->filename_index, tp->start); } } } fclose(fp); return res; }