quran: don't use mmap()
[cnoor.git] / quran.c
blob01526dfd0f45b75a91d05b49ef2bdfd61656e585
1 #include <fcntl.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <sys/stat.h>
5 #include <sys/types.h>
6 #include <unistd.h>
7 #include "util.h"
8 #include "quran.h"
10 static char abuf[1 << 16];
11 static int apos = -1;
12 static int acur;
13 static int aaya;
15 static int aya_offset(int fd, int aya)
17 char *s;
18 if (aaya > aya || apos == -1) {
19 acur = 0;
20 aaya = 0;
21 apos = 0;
22 lseek(fd, apos, 0);
23 read(fd, abuf, sizeof(abuf));
25 while (aaya < aya) {
26 while (!(s = memchr(abuf + acur, '\n', sizeof(abuf) - acur))) {
27 acur = 0;
28 apos += sizeof(abuf);
29 lseek(fd, apos, 0);
30 read(fd, abuf, sizeof(abuf));
32 acur = s - abuf + 1;
33 aaya++;
35 return apos + acur;
38 struct quran *quran_alloc(char *path)
40 struct quran *quran = xmalloc(sizeof(struct quran));
41 int i;
42 memset(quran, 0, sizeof(quran));
43 quran->fd = open(path, O_RDONLY);
44 if (quran->fd == -1)
45 xerror(path);
46 for (i = 0; i < NAYA + 1; i++)
47 quran->ayas[i] = aya_offset(quran->fd, i);
48 return quran;
51 void quran_aya(struct quran *quran, char *buf, int len, int aya)
53 int n;
54 if (quran->ayas[aya] + len > quran->ayas[aya + 1])
55 len = quran->ayas[aya + 1] - quran->ayas[aya] - 1;
56 lseek(quran->fd, quran->ayas[aya], 0);
57 n = read(quran->fd, buf, len);
58 while (n > 0 && (buf[n - 1] == '\r' || buf[n - 1] == '\n'))
59 n--;
60 buf[n] = '\0';
63 void quran_free(struct quran *quran)
65 close(quran->fd);
66 free(quran);
69 static struct suras {
70 char *name;
71 int ayas;
72 } suras[] = {
73 {"Al-Faatiha", 7}, {"Al-Baqara", 286}, {"Aal-i-Imraan", 200},
74 {"An-Nisaa", 176}, {"Al-Maaida", 120}, {"Al-An'aam", 165},
75 {"Al-A'raaf", 206}, {"Al-Anfaal", 75}, {"At-Tawba", 129},
76 {"Yunus", 109}, {"Hud", 123}, {"Yusuf", 111},
77 {"Ar-Ra'd", 43}, {"Ibrahim", 52}, {"Al-Hijr", 99},
78 {"An-Nahl", 128}, {"Al-Israa", 111}, {"Al-Kahf", 110},
79 {"Maryam", 98}, {"Taa-Haa", 135}, {"Al-Anbiyaa", 112},
80 {"Al-Hajj", 78}, {"Al-Muminoon", 118}, {"An-Noor", 64},
81 {"Al-Furqaan", 77}, {"Ash-Shu'araa", 227}, {"An-Naml", 93},
82 {"Al-Qasas", 88}, {"Al-Ankaboot", 69}, {"Ar-Room", 60},
83 {"Luqman", 34}, {"As-Sajda", 30}, {"Al-Ahzaab", 73},
84 {"Saba", 54}, {"Faatir", 45}, {"Yaseen", 83},
85 {"As-Saaffaat", 182}, {"Saad", 88}, {"Az-Zumar", 75},
86 {"Al-Ghaafir", 85}, {"Fussilat", 54}, {"Ash-Shura", 53},
87 {"Az-Zukhruf", 89}, {"Ad-Dukhaan", 59}, {"Al-Jaathiya", 37},
88 {"Al-Ahqaf", 35}, {"Muhammad", 38}, {"Al-Fath", 29},
89 {"Al-Hujuraat", 18}, {"Qaaf", 45}, {"Adh-Dhaariyat", 60},
90 {"At-Tur", 49}, {"An-Najm", 62}, {"Al-Qamar", 55},
91 {"Ar-Rahmaan", 78}, {"Al-Waaqia", 96}, {"Al-Hadid", 29},
92 {"Al-Mujaadila", 22}, {"Al-Hashr", 24}, {"Al-Mumtahana", 13},
93 {"As-Saff", 14}, {"Al-Jumu'a", 11}, {"Al-Munaafiqoon", 11},
94 {"At-Taghaabun", 18}, {"At-Talaaq", 12}, {"At-Tahrim", 12},
95 {"Al-Mulk", 30}, {"Al-Qalam", 52}, {"Al-Haaqqa", 52},
96 {"Al-Ma'aarij", 44}, {"Nooh", 28}, {"Al-Jinn", 28},
97 {"Al-Muzzammil", 20}, {"Al-Muddaththir", 56}, {"Al-Qiyaama", 40},
98 {"Al-Insaan", 31}, {"Al-Mursalaat", 50}, {"An-Naba", 40},
99 {"An-Naazi'aat", 46}, {"Abasa", 42}, {"At-Takwir", 29},
100 {"Al-Infitaar", 19}, {"Al-Mutaffifin", 36}, {"Al-Inshiqaaq", 25},
101 {"Al-Burooj", 22}, {"At-Taariq", 17}, {"Al-A'laa", 19},
102 {"Al-Ghaashiya", 26}, {"Al-Fajr", 30}, {"Al-Balad", 20},
103 {"Ash-Shams", 15}, {"Al-Lail", 21}, {"Ad-Dhuhaa", 11},
104 {"Ash-Sharh", 8}, {"At-Tin", 8}, {"Al-Alaq", 19},
105 {"Al-Qadr", 5}, {"Al-Bayyina", 8}, {"Az-Zalzala", 8},
106 {"Al-Aadiyaat", 11}, {"Al-Qaari'a", 11}, {"At-Takaathur", 8},
107 {"Al-Asr", 3}, {"Al-Humaza", 9}, {"Al-Fil", 5},
108 {"Quraish", 4}, {"Al-Maa'un", 7}, {"Al-Kawthar", 3},
109 {"Al-Kaafiroon", 6}, {"An-Nasr", 3}, {"Al-Masad", 5},
110 {"Al-Ikhlaas", 4}, {"Al-Falaq", 5}, {"An-Naas", 6}
113 int sura_ayas(int sura)
115 return suras[sura - 1].ayas;
118 char *sura_name(int sura)
120 return suras[sura - 1].name;
123 int sura_start(int sura)
125 int i;
126 int n = 0;
127 for (i = 0; i < sura - 1; i++)
128 n += suras[i].ayas;
129 return n;
132 int aya_num(int sura, int aya)
134 return sura_start(sura) + aya;
137 #define AYAHASH(sura, aya) (((sura) << 10) | (aya))
139 int juz_start(int sura, int aya)
141 switch (AYAHASH(sura, aya)) {
142 case AYAHASH(1, 1):
143 return 1;
144 case AYAHASH(2, 142):
145 return 2;
146 case AYAHASH(2, 253):
147 return 3;
148 case AYAHASH(3, 93):
149 return 4;
150 case AYAHASH(4, 24):
151 return 5;
152 case AYAHASH(4, 148):
153 return 6;
154 case AYAHASH(5, 82):
155 return 7;
156 case AYAHASH(6, 111):
157 return 8;
158 case AYAHASH(7, 88):
159 return 9;
160 case AYAHASH(8, 41):
161 return 10;
162 case AYAHASH(9, 93):
163 return 11;
164 case AYAHASH(11, 6):
165 return 12;
166 case AYAHASH(12, 53):
167 return 13;
168 case AYAHASH(15, 1):
169 return 14;
170 case AYAHASH(17, 1):
171 return 15;
172 case AYAHASH(18, 75):
173 return 16;
174 case AYAHASH(21, 1):
175 return 16;
176 case AYAHASH(23, 1):
177 return 18;
178 case AYAHASH(25, 21):
179 return 19;
180 case AYAHASH(27, 56):
181 return 20;
182 case AYAHASH(29, 46):
183 return 21;
184 case AYAHASH(33, 31):
185 return 22;
186 case AYAHASH(36, 28):
187 return 23;
188 case AYAHASH(39, 32):
189 return 24;
190 case AYAHASH(41, 47):
191 return 25;
192 case AYAHASH(46, 1):
193 return 26;
194 case AYAHASH(51, 31):
195 return 27;
196 case AYAHASH(58, 1):
197 return 28;
198 case AYAHASH(67, 1):
199 return 29;
200 case AYAHASH(78, 1):
201 return 30;
203 return 0;
206 int sajda_kind(int sura, int aya)
208 switch (AYAHASH(sura, aya)) {
209 case AYAHASH(7, 206):
210 return SAJDA_RECOM;
211 case AYAHASH(13, 15):
212 return SAJDA_RECOM;
213 case AYAHASH(16, 50):
214 return SAJDA_RECOM;
215 case AYAHASH(17, 109):
216 return SAJDA_RECOM;
217 case AYAHASH(19, 58):
218 return SAJDA_RECOM;
219 case AYAHASH(22, 18):
220 return SAJDA_RECOM;
221 case AYAHASH(22, 77):
222 return SAJDA_RECOM;
223 case AYAHASH(25, 60):
224 return SAJDA_RECOM;
225 case AYAHASH(27, 26):
226 return SAJDA_RECOM;
227 case AYAHASH(32, 15):
228 return SAJDA_OBLIG;
229 case AYAHASH(38, 24):
230 return SAJDA_RECOM;
231 case AYAHASH(41, 38):
232 return SAJDA_OBLIG;
233 case AYAHASH(53, 62):
234 return SAJDA_OBLIG;
235 case AYAHASH(84, 21):
236 return SAJDA_RECOM;
237 case AYAHASH(96, 19):
238 return SAJDA_OBLIG;
239 default:
240 return SAJDA_NONE;