From 1e2a8689199ca2d2a8051b83c7358bf225ff343c Mon Sep 17 00:00:00 2001 From: Ali Gholami Rudi Date: Thu, 22 Sep 2011 14:24:47 +0330 Subject: [PATCH] quran: don't use mmap() --- quran.c | 64 ++++++++++++++++++++++++++++++++++++---------------------------- quran.h | 5 ++--- 2 files changed, 38 insertions(+), 31 deletions(-) diff --git a/quran.c b/quran.c index 77309e4..01526df 100644 --- a/quran.c +++ b/quran.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -8,52 +7,61 @@ #include "util.h" #include "quran.h" -static size_t file_size(int fd) -{ - struct stat st; - if (!fstat(fd, &st)) - return st.st_size; - return 0; -} +static char abuf[1 << 16]; +static int apos = -1; +static int acur; +static int aaya; -static void init_ayas(struct quran *quran) +static int aya_offset(int fd, int aya) { - int i = 0; - char *s = quran->text; - quran->ayas[0] = quran->text; - while (i < NAYA && (s = strchr(s, '\n'))) - quran->ayas[++i] = ++s; + char *s; + if (aaya > aya || apos == -1) { + acur = 0; + aaya = 0; + apos = 0; + lseek(fd, apos, 0); + read(fd, abuf, sizeof(abuf)); + } + while (aaya < aya) { + while (!(s = memchr(abuf + acur, '\n', sizeof(abuf) - acur))) { + acur = 0; + apos += sizeof(abuf); + lseek(fd, apos, 0); + read(fd, abuf, sizeof(abuf)); + } + acur = s - abuf + 1; + aaya++; + } + return apos + acur; } struct quran *quran_alloc(char *path) { struct quran *quran = xmalloc(sizeof(struct quran)); + int i; memset(quran, 0, sizeof(quran)); quran->fd = open(path, O_RDONLY); if (quran->fd == -1) xerror(path); - quran->text = mmap(NULL, file_size(quran->fd), PROT_READ, - MAP_SHARED, quran->fd, 0); - if (quran->text == MAP_FAILED) - xerror("mmap"); - init_ayas(quran); + for (i = 0; i < NAYA + 1; i++) + quran->ayas[i] = aya_offset(quran->fd, i); return quran; } -void quran_aya(struct quran *quran, char *buf, size_t len, int aya) +void quran_aya(struct quran *quran, char *buf, int len, int aya) { - char *s = quran->ayas[aya]; - char *e = strchr(s, '\n'); - size_t n = e - s; - if (n > len - 1) - n = len - 1; - memcpy(buf, s, n); - buf[buf[n - 1] == '\r' ? n - 1 : n] = '\0'; + int n; + if (quran->ayas[aya] + len > quran->ayas[aya + 1]) + len = quran->ayas[aya + 1] - quran->ayas[aya] - 1; + lseek(quran->fd, quran->ayas[aya], 0); + n = read(quran->fd, buf, len); + while (n > 0 && (buf[n - 1] == '\r' || buf[n - 1] == '\n')) + n--; + buf[n] = '\0'; } void quran_free(struct quran *quran) { - munmap(quran->text, file_size(quran->fd)); close(quran->fd); free(quran); } diff --git a/quran.h b/quran.h index b99ad35..5ad0f12 100644 --- a/quran.h +++ b/quran.h @@ -6,13 +6,12 @@ #define SAJDA_OBLIG 2 struct quran { + long ayas[NAYA + 1]; int fd; - char *text; - char *ayas[NAYA]; }; struct quran *quran_alloc(char *path); -void quran_aya(struct quran *quran, char *buf, size_t len, int aya); +void quran_aya(struct quran *quran, char *buf, int len, int aya); void quran_free(struct quran *quran); int sura_start(int sura); -- 2.11.4.GIT