Bible text I/O library, for retrieving and navigating text in KJV Bible More details at: http://mbed.org/users/davervw/notebook/ebible-abstract/

Dependents:   eBible

Committer:
davervw
Date:
Sun Feb 27 18:49:23 2011 +0000
Revision:
0:1f3d069211cd

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
davervw 0:1f3d069211cd 1 /* Bible I/O Class Implementation
davervw 0:1f3d069211cd 2 *
davervw 0:1f3d069211cd 3 * Copyright (c) 2011 David R. Van Wagner davervw@yahoo.com
davervw 0:1f3d069211cd 4 *
davervw 0:1f3d069211cd 5 * Permission is hereby granted, free of charge, to any person obtaining a copy
davervw 0:1f3d069211cd 6 * of this software and associated documentation files (the "Software"), to deal
davervw 0:1f3d069211cd 7 * in the Software without restriction, including without limitation the rights
davervw 0:1f3d069211cd 8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
davervw 0:1f3d069211cd 9 * copies of the Software, and to permit persons to whom the Software is
davervw 0:1f3d069211cd 10 * furnished to do so, subject to the following conditions:
davervw 0:1f3d069211cd 11 *
davervw 0:1f3d069211cd 12 * The above copyright notice and this permission notice shall be included in
davervw 0:1f3d069211cd 13 * all copies or substantial portions of the Software.
davervw 0:1f3d069211cd 14 *
davervw 0:1f3d069211cd 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
davervw 0:1f3d069211cd 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
davervw 0:1f3d069211cd 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
davervw 0:1f3d069211cd 18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
davervw 0:1f3d069211cd 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
davervw 0:1f3d069211cd 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
davervw 0:1f3d069211cd 21 * THE SOFTWARE.
davervw 0:1f3d069211cd 22 */
davervw 0:1f3d069211cd 23
davervw 0:1f3d069211cd 24 /*
davervw 0:1f3d069211cd 25 * This class assumes bible text file is present and in a specific format extracted from source such as:
davervw 0:1f3d069211cd 26 * http://printkjv.ifbweb.com/AV_txt.zip
davervw 0:1f3d069211cd 27 */
davervw 0:1f3d069211cd 28
davervw 0:1f3d069211cd 29 #include <mbed.h> // mkdir
davervw 0:1f3d069211cd 30 #include <stdio.h>
davervw 0:1f3d069211cd 31 #include <string.h>
davervw 0:1f3d069211cd 32 #include <stdlib.h>
davervw 0:1f3d069211cd 33 #include <locale>
davervw 0:1f3d069211cd 34 #include "BibleIO.h"
davervw 0:1f3d069211cd 35
davervw 0:1f3d069211cd 36 //extern Serial console;
davervw 0:1f3d069211cd 37
davervw 0:1f3d069211cd 38 BibleIO::BibleIO(char* filename, void (*indexing_callback)(int, void*), void* indexing_context)
davervw 0:1f3d069211cd 39 {
davervw 0:1f3d069211cd 40 name = 0;
davervw 0:1f3d069211cd 41 num_books = 0;
davervw 0:1f3d069211cd 42 books = 0;
davervw 0:1f3d069211cd 43 bookmarks = 0;
davervw 0:1f3d069211cd 44 text_filename = filename;
davervw 0:1f3d069211cd 45 this->indexing_callback = indexing_callback;
davervw 0:1f3d069211cd 46 this->indexing_context = indexing_context;
davervw 0:1f3d069211cd 47
davervw 0:1f3d069211cd 48 fp = fopen(text_filename, "r");
davervw 0:1f3d069211cd 49 load_bookmarks();
davervw 0:1f3d069211cd 50
davervw 0:1f3d069211cd 51 if (!load_index())
davervw 0:1f3d069211cd 52 build_index();
davervw 0:1f3d069211cd 53 }
davervw 0:1f3d069211cd 54
davervw 0:1f3d069211cd 55 BibleIO::~BibleIO()
davervw 0:1f3d069211cd 56 {
davervw 0:1f3d069211cd 57 delete [] name;
davervw 0:1f3d069211cd 58 name = 0;
davervw 0:1f3d069211cd 59
davervw 0:1f3d069211cd 60 delete [] books;
davervw 0:1f3d069211cd 61 books = 0;
davervw 0:1f3d069211cd 62
davervw 0:1f3d069211cd 63 delete [] bookmarks;
davervw 0:1f3d069211cd 64 bookmarks = 0;
davervw 0:1f3d069211cd 65
davervw 0:1f3d069211cd 66 fclose(fp);
davervw 0:1f3d069211cd 67 }
davervw 0:1f3d069211cd 68
davervw 0:1f3d069211cd 69 void BibleIO::build_index()
davervw 0:1f3d069211cd 70 {
davervw 0:1f3d069211cd 71 read_name();
davervw 0:1f3d069211cd 72 read_preface();
davervw 0:1f3d069211cd 73 read_books();
davervw 0:1f3d069211cd 74 load_index();
davervw 0:1f3d069211cd 75 }
davervw 0:1f3d069211cd 76
davervw 0:1f3d069211cd 77 void BibleIO::read_name()
davervw 0:1f3d069211cd 78 {
davervw 0:1f3d069211cd 79 name = read_line();
davervw 0:1f3d069211cd 80
davervw 0:1f3d069211cd 81 //console.printf("name=%s\n", name);
davervw 0:1f3d069211cd 82 //lcd.printf("%s\n", name);
davervw 0:1f3d069211cd 83 }
davervw 0:1f3d069211cd 84
davervw 0:1f3d069211cd 85 void BibleIO::read_preface()
davervw 0:1f3d069211cd 86 {
davervw 0:1f3d069211cd 87 char* line = 0;
davervw 0:1f3d069211cd 88 long book_offset = ftell(fp);
davervw 0:1f3d069211cd 89 long line_offset = book_offset;
davervw 0:1f3d069211cd 90
davervw 0:1f3d069211cd 91 do
davervw 0:1f3d069211cd 92 {
davervw 0:1f3d069211cd 93 if (line != 0 && *line != 0)
davervw 0:1f3d069211cd 94 book_offset = line_offset;
davervw 0:1f3d069211cd 95 delete [] line;
davervw 0:1f3d069211cd 96 line_offset = ftell(fp);
davervw 0:1f3d069211cd 97 line = read_line();
davervw 0:1f3d069211cd 98 //console.printf("%s\n", line);
davervw 0:1f3d069211cd 99 } while (strcmp(line, "CHAPTER 1") != 0);
davervw 0:1f3d069211cd 100 delete [] line;
davervw 0:1f3d069211cd 101
davervw 0:1f3d069211cd 102 // read too far, reset file pointer
davervw 0:1f3d069211cd 103 fseek(fp, book_offset, SEEK_SET);
davervw 0:1f3d069211cd 104 }
davervw 0:1f3d069211cd 105
davervw 0:1f3d069211cd 106 void BibleIO::read_books()
davervw 0:1f3d069211cd 107 {
davervw 0:1f3d069211cd 108 char* path = index_path();
davervw 0:1f3d069211cd 109 mkdir(path, 0666);
davervw 0:1f3d069211cd 110 delete [] path;
davervw 0:1f3d069211cd 111 path = 0;
davervw 0:1f3d069211cd 112
davervw 0:1f3d069211cd 113 char* fn = index_path("books");
davervw 0:1f3d069211cd 114 FILE* index = fopen(fn, "w");
davervw 0:1f3d069211cd 115 delete [] fn;
davervw 0:1f3d069211cd 116 fn = 0;
davervw 0:1f3d069211cd 117
davervw 0:1f3d069211cd 118 long title_offset = 0;
davervw 0:1f3d069211cd 119 fwrite(&title_offset, sizeof(title_offset), 1, index);
davervw 0:1f3d069211cd 120
davervw 0:1f3d069211cd 121 short book = 0;
davervw 0:1f3d069211cd 122 //lcd.cls();
davervw 0:1f3d069211cd 123 if (indexing_callback != 0)
davervw 0:1f3d069211cd 124 (*indexing_callback)(0, indexing_context);
davervw 0:1f3d069211cd 125 //lcd.printf("Indexing0%%");
davervw 0:1f3d069211cd 126 long offset = ftell(fp);
davervw 0:1f3d069211cd 127 fseek(fp, 0, SEEK_END);
davervw 0:1f3d069211cd 128 long filesize = ftell(fp);
davervw 0:1f3d069211cd 129 fseek(fp, offset, SEEK_SET);
davervw 0:1f3d069211cd 130 while(read_book(index, book))
davervw 0:1f3d069211cd 131 {
davervw 0:1f3d069211cd 132 offset = ftell(fp);
davervw 0:1f3d069211cd 133 //lcd.printf("\n\n%d%%", offset*100/filesize);
davervw 0:1f3d069211cd 134 if (indexing_callback != 0)
davervw 0:1f3d069211cd 135 (*indexing_callback)(offset*100/filesize, indexing_context);
davervw 0:1f3d069211cd 136 ++book;
davervw 0:1f3d069211cd 137 }
davervw 0:1f3d069211cd 138 //lcd.cls();
davervw 0:1f3d069211cd 139 //lcd.printf("Complete100%%");
davervw 0:1f3d069211cd 140 if (indexing_callback != 0)
davervw 0:1f3d069211cd 141 (*indexing_callback)(100, indexing_context);
davervw 0:1f3d069211cd 142
davervw 0:1f3d069211cd 143 //printf("%hd books\n", book);
davervw 0:1f3d069211cd 144
davervw 0:1f3d069211cd 145 fclose(index);
davervw 0:1f3d069211cd 146 }
davervw 0:1f3d069211cd 147
davervw 0:1f3d069211cd 148 bool BibleIO::read_book(FILE* index, short book)
davervw 0:1f3d069211cd 149 {
davervw 0:1f3d069211cd 150 long offset = ftell(fp);
davervw 0:1f3d069211cd 151
davervw 0:1f3d069211cd 152 char *book_name = BibleIO::read_line();
davervw 0:1f3d069211cd 153 if (book_name == 0 || *(book_name) == 0 || strcmp(book_name, "THE END") == 0
davervw 0:1f3d069211cd 154 || (book_name[0] >= '0' && book_name[0] <= '9'))
davervw 0:1f3d069211cd 155 {
davervw 0:1f3d069211cd 156 delete [] book_name;
davervw 0:1f3d069211cd 157 return false;
davervw 0:1f3d069211cd 158 }
davervw 0:1f3d069211cd 159
davervw 0:1f3d069211cd 160 fwrite(&offset, sizeof(offset), 1, index);
davervw 0:1f3d069211cd 161
davervw 0:1f3d069211cd 162 format_book_name(book_name);
davervw 0:1f3d069211cd 163 //printf("book=%s\n", book_name);
davervw 0:1f3d069211cd 164 //lcd.cls();
davervw 0:1f3d069211cd 165 //lcd.printf("%s_\n", book_name);
davervw 0:1f3d069211cd 166
davervw 0:1f3d069211cd 167 delete [] book_name;
davervw 0:1f3d069211cd 168
davervw 0:1f3d069211cd 169 short chapter = 0;
davervw 0:1f3d069211cd 170 while (read_chapter(book, chapter))
davervw 0:1f3d069211cd 171 ++chapter;
davervw 0:1f3d069211cd 172
davervw 0:1f3d069211cd 173 //console.printf("%hd chapters\n", chapter);
davervw 0:1f3d069211cd 174
davervw 0:1f3d069211cd 175 long num_chapters = chapter;
davervw 0:1f3d069211cd 176 fwrite(&num_chapters, sizeof(num_chapters), 1, index);
davervw 0:1f3d069211cd 177
davervw 0:1f3d069211cd 178 return true;
davervw 0:1f3d069211cd 179 }
davervw 0:1f3d069211cd 180
davervw 0:1f3d069211cd 181 void BibleIO::format_book_name(char* &book_name)
davervw 0:1f3d069211cd 182 {
davervw 0:1f3d069211cd 183 char* last_word = strrchr(book_name, ' ');
davervw 0:1f3d069211cd 184 if (last_word != 0)
davervw 0:1f3d069211cd 185 {
davervw 0:1f3d069211cd 186 int number = 0;
davervw 0:1f3d069211cd 187 if (strstr(book_name, "MOSES") == 0)
davervw 0:1f3d069211cd 188 {
davervw 0:1f3d069211cd 189 if (strstr(book_name, " FIRST ") != 0)
davervw 0:1f3d069211cd 190 number = 1;
davervw 0:1f3d069211cd 191 else if (strstr(book_name, " SECOND ") != 0)
davervw 0:1f3d069211cd 192 number = 2;
davervw 0:1f3d069211cd 193 else if (strstr(book_name, " THIRD ") != 0)
davervw 0:1f3d069211cd 194 number = 3;
davervw 0:1f3d069211cd 195 }
davervw 0:1f3d069211cd 196 if (strstr(book_name, "SONG") != 0 || strstr(book_name, "ACTS ") != 0)
davervw 0:1f3d069211cd 197 last_word = book_name;
davervw 0:1f3d069211cd 198 if (strstr(book_name, "ECCLESIASTES") != 0
davervw 0:1f3d069211cd 199 || strstr(book_name, "LAMENTATIONS") != 0
davervw 0:1f3d069211cd 200 || strstr(book_name, "ACTS OF") != 0
davervw 0:1f3d069211cd 201 || strstr(book_name, "REVELATION") != 0)
davervw 0:1f3d069211cd 202 {
davervw 0:1f3d069211cd 203 last_word = book_name;
davervw 0:1f3d069211cd 204 if (strncmp(last_word, "THE ", 4) == 0)
davervw 0:1f3d069211cd 205 last_word += 4;
davervw 0:1f3d069211cd 206 char* next_word = strchr(last_word, ' ');
davervw 0:1f3d069211cd 207 if (next_word != 0)
davervw 0:1f3d069211cd 208 *next_word = 0;
davervw 0:1f3d069211cd 209 }
davervw 0:1f3d069211cd 210 if (strncmp(last_word, "THE ", 4) == 0)
davervw 0:1f3d069211cd 211 last_word += 4;
davervw 0:1f3d069211cd 212 if (*last_word == ' ')
davervw 0:1f3d069211cd 213 ++last_word;
davervw 0:1f3d069211cd 214 if (last_word[strlen(last_word)-1] < 'A' || last_word[strlen(last_word)-1] > 'Z')
davervw 0:1f3d069211cd 215 last_word[strlen(last_word)-1] = 0;
davervw 0:1f3d069211cd 216 char* new_name = new char[strlen(last_word)+((number==0)?1:3)];
davervw 0:1f3d069211cd 217 if (number == 0)
davervw 0:1f3d069211cd 218 strcpy(new_name, last_word);
davervw 0:1f3d069211cd 219 else
davervw 0:1f3d069211cd 220 sprintf(new_name, "%d %s", number, last_word);
davervw 0:1f3d069211cd 221 delete [] book_name;
davervw 0:1f3d069211cd 222 book_name = new_name;
davervw 0:1f3d069211cd 223 }
davervw 0:1f3d069211cd 224 }
davervw 0:1f3d069211cd 225
davervw 0:1f3d069211cd 226 bool BibleIO::read_chapter(short book, short chapter)
davervw 0:1f3d069211cd 227 {
davervw 0:1f3d069211cd 228 char* line = 0;
davervw 0:1f3d069211cd 229 long offset;
davervw 0:1f3d069211cd 230 do
davervw 0:1f3d069211cd 231 {
davervw 0:1f3d069211cd 232 delete [] line;
davervw 0:1f3d069211cd 233 offset = ftell(fp);
davervw 0:1f3d069211cd 234 line = BibleIO::read_line();
davervw 0:1f3d069211cd 235 } while (line != 0 && (*line == 0 || strstr(line, "CALLED,") != 0 || line[0]=='#'));
davervw 0:1f3d069211cd 236
davervw 0:1f3d069211cd 237 if (line != 0 && strcmp(line, "THE END OF THE OLD TESTAMENT")==0)
davervw 0:1f3d069211cd 238 {
davervw 0:1f3d069211cd 239 do
davervw 0:1f3d069211cd 240 {
davervw 0:1f3d069211cd 241 delete [] line;
davervw 0:1f3d069211cd 242 offset = ftell(fp);
davervw 0:1f3d069211cd 243 line = BibleIO::read_line();
davervw 0:1f3d069211cd 244 } while (line != 0 && strstr(line, "MATTHEW")==0);
davervw 0:1f3d069211cd 245 }
davervw 0:1f3d069211cd 246
davervw 0:1f3d069211cd 247 if (line == 0 || (strncmp(line, "CHAPTER ", 8) != 0 && strncmp(line, "PSALM ", 6) != 0)
davervw 0:1f3d069211cd 248 || (line[0] == 'P' && atoi(line+6) != chapter+1)
davervw 0:1f3d069211cd 249 || (line[0] == 'C' && atoi(line+8) != chapter+1))
davervw 0:1f3d069211cd 250 {
davervw 0:1f3d069211cd 251 delete [] line;
davervw 0:1f3d069211cd 252 fseek(fp, offset, SEEK_SET);
davervw 0:1f3d069211cd 253 return false;
davervw 0:1f3d069211cd 254 }
davervw 0:1f3d069211cd 255
davervw 0:1f3d069211cd 256 delete [] line;
davervw 0:1f3d069211cd 257
davervw 0:1f3d069211cd 258 char* path = index_path(book);
davervw 0:1f3d069211cd 259 mkdir(path, 0666);
davervw 0:1f3d069211cd 260 delete [] path;
davervw 0:1f3d069211cd 261 path = 0;
davervw 0:1f3d069211cd 262
davervw 0:1f3d069211cd 263 char* fn = index_path(book, chapter);
davervw 0:1f3d069211cd 264 FILE* index = fopen(fn, "wb");
davervw 0:1f3d069211cd 265 //console.printf("index file pointer=%08lx\n", (long)index);
davervw 0:1f3d069211cd 266 delete [] fn;
davervw 0:1f3d069211cd 267 fn = 0;
davervw 0:1f3d069211cd 268
davervw 0:1f3d069211cd 269 // chapter name
davervw 0:1f3d069211cd 270 fwrite(&offset, sizeof(offset), 1, index);
davervw 0:1f3d069211cd 271
davervw 0:1f3d069211cd 272 //console.printf("Chapter %d\n", chapter+1);
davervw 0:1f3d069211cd 273
davervw 0:1f3d069211cd 274 // support Psalms optional description of chapter
davervw 0:1f3d069211cd 275 long desc_offset = ftell(fp);
davervw 0:1f3d069211cd 276 char* chapter_desc = BibleIO::read_line();
davervw 0:1f3d069211cd 277 if (chapter_desc == 0 || (chapter_desc[0] >= '0' && chapter_desc[0] <= '9'))
davervw 0:1f3d069211cd 278 {
davervw 0:1f3d069211cd 279 delete [] chapter_desc;
davervw 0:1f3d069211cd 280 chapter_desc = 0;
davervw 0:1f3d069211cd 281 fseek(fp, desc_offset, SEEK_SET);
davervw 0:1f3d069211cd 282 }
davervw 0:1f3d069211cd 283 delete [] chapter_desc; // not currently used
davervw 0:1f3d069211cd 284
davervw 0:1f3d069211cd 285 short verse = 0;
davervw 0:1f3d069211cd 286 while (read_verse(index, book, chapter, verse))
davervw 0:1f3d069211cd 287 ++verse;
davervw 0:1f3d069211cd 288
davervw 0:1f3d069211cd 289 //console.printf("\n");
davervw 0:1f3d069211cd 290 //console.printf("%hd verses\n", verse);
davervw 0:1f3d069211cd 291
davervw 0:1f3d069211cd 292 fclose(index);
davervw 0:1f3d069211cd 293
davervw 0:1f3d069211cd 294 return true;
davervw 0:1f3d069211cd 295 }
davervw 0:1f3d069211cd 296
davervw 0:1f3d069211cd 297 char* BibleIO::read_line()
davervw 0:1f3d069211cd 298 {
davervw 0:1f3d069211cd 299 char* line;
davervw 0:1f3d069211cd 300 const int size = 4096;
davervw 0:1f3d069211cd 301 line = new char[size];
davervw 0:1f3d069211cd 302 fgets(line, size, fp);
davervw 0:1f3d069211cd 303
davervw 0:1f3d069211cd 304 // remove CR/LF
davervw 0:1f3d069211cd 305 while (strlen(line)>0 && (line[strlen(line)-1] == 0x0a || line[strlen(line)-1] == 0x0d))
davervw 0:1f3d069211cd 306 line[strlen(line)-1] = 0;
davervw 0:1f3d069211cd 307
davervw 0:1f3d069211cd 308 // resize line to actual size
davervw 0:1f3d069211cd 309 char* new_line = new char[strlen(line)+1];
davervw 0:1f3d069211cd 310 strcpy(new_line, line);
davervw 0:1f3d069211cd 311 delete [] line;
davervw 0:1f3d069211cd 312 line = 0;
davervw 0:1f3d069211cd 313
davervw 0:1f3d069211cd 314 //console.printf("%s\n", new_line);
davervw 0:1f3d069211cd 315
davervw 0:1f3d069211cd 316 return new_line;
davervw 0:1f3d069211cd 317 }
davervw 0:1f3d069211cd 318
davervw 0:1f3d069211cd 319 bool BibleIO::load_index()
davervw 0:1f3d069211cd 320 {
davervw 0:1f3d069211cd 321 char* fn = index_path("books");
davervw 0:1f3d069211cd 322 FILE* index = fopen(fn, "r");
davervw 0:1f3d069211cd 323 delete [] fn;
davervw 0:1f3d069211cd 324 fn = 0;
davervw 0:1f3d069211cd 325
davervw 0:1f3d069211cd 326 if (index == 0)
davervw 0:1f3d069211cd 327 return false;
davervw 0:1f3d069211cd 328
davervw 0:1f3d069211cd 329 fseek(index, 0, SEEK_END);
davervw 0:1f3d069211cd 330 long filesize = ftell(index);
davervw 0:1f3d069211cd 331 num_books = (filesize - sizeof(long)) / sizeof(book_index);
davervw 0:1f3d069211cd 332 delete [] books;
davervw 0:1f3d069211cd 333 books = (bible_index*)new char[filesize];
davervw 0:1f3d069211cd 334 fseek(index, 0, SEEK_SET);
davervw 0:1f3d069211cd 335
davervw 0:1f3d069211cd 336 fread(books, filesize, 1, index);
davervw 0:1f3d069211cd 337
davervw 0:1f3d069211cd 338 long save_offset = ftell(fp);
davervw 0:1f3d069211cd 339 fseek(fp, books->title_offset, SEEK_SET);
davervw 0:1f3d069211cd 340 delete [] name;
davervw 0:1f3d069211cd 341 name = read_line();
davervw 0:1f3d069211cd 342 fseek(fp, save_offset, SEEK_SET);
davervw 0:1f3d069211cd 343
davervw 0:1f3d069211cd 344 fclose(index);
davervw 0:1f3d069211cd 345 return true;
davervw 0:1f3d069211cd 346 }
davervw 0:1f3d069211cd 347
davervw 0:1f3d069211cd 348 short BibleIO::get_num_books()
davervw 0:1f3d069211cd 349 {
davervw 0:1f3d069211cd 350 return num_books;
davervw 0:1f3d069211cd 351 }
davervw 0:1f3d069211cd 352
davervw 0:1f3d069211cd 353 short BibleIO::get_num_chapters(short book)
davervw 0:1f3d069211cd 354 {
davervw 0:1f3d069211cd 355 return books->books[book].num_chapters;
davervw 0:1f3d069211cd 356 }
davervw 0:1f3d069211cd 357
davervw 0:1f3d069211cd 358 short BibleIO::get_num_verses(short book, short chapter)
davervw 0:1f3d069211cd 359 {
davervw 0:1f3d069211cd 360 char* fn = index_path(book, chapter);
davervw 0:1f3d069211cd 361 FILE* index = fopen(fn, "r");
davervw 0:1f3d069211cd 362 delete [] fn;
davervw 0:1f3d069211cd 363 fn = 0;
davervw 0:1f3d069211cd 364
davervw 0:1f3d069211cd 365 fseek(index, 0, SEEK_END);
davervw 0:1f3d069211cd 366 long filesize = ftell(index);
davervw 0:1f3d069211cd 367 short num_verses = (filesize - sizeof(long)) / sizeof(chapter_index);
davervw 0:1f3d069211cd 368 fclose(index);
davervw 0:1f3d069211cd 369 return num_verses;
davervw 0:1f3d069211cd 370 }
davervw 0:1f3d069211cd 371
davervw 0:1f3d069211cd 372 char* BibleIO::title()
davervw 0:1f3d069211cd 373 {
davervw 0:1f3d069211cd 374 char *t = new char[strlen(name)+1];
davervw 0:1f3d069211cd 375 strcpy(t, name);
davervw 0:1f3d069211cd 376 return t;
davervw 0:1f3d069211cd 377 }
davervw 0:1f3d069211cd 378
davervw 0:1f3d069211cd 379 char* BibleIO::title_book(short book)
davervw 0:1f3d069211cd 380 {
davervw 0:1f3d069211cd 381 if (book < 0 || book > num_books)
davervw 0:1f3d069211cd 382 return 0;
davervw 0:1f3d069211cd 383
davervw 0:1f3d069211cd 384 long offset = ftell(fp);
davervw 0:1f3d069211cd 385 long title_offset = books->books[book].title_offset;
davervw 0:1f3d069211cd 386 fseek(fp, title_offset, SEEK_SET);
davervw 0:1f3d069211cd 387 char* title = read_line();
davervw 0:1f3d069211cd 388 fseek(fp, offset, SEEK_SET);
davervw 0:1f3d069211cd 389 format_book_name(title);
davervw 0:1f3d069211cd 390 return title;
davervw 0:1f3d069211cd 391 }
davervw 0:1f3d069211cd 392
davervw 0:1f3d069211cd 393 char* BibleIO::title_chapter(short book, short chapter)
davervw 0:1f3d069211cd 394 {
davervw 0:1f3d069211cd 395 char* fn = index_path(book, chapter);
davervw 0:1f3d069211cd 396 FILE* index = fopen(fn, "r");
davervw 0:1f3d069211cd 397 delete [] fn;
davervw 0:1f3d069211cd 398 fn = 0;
davervw 0:1f3d069211cd 399
davervw 0:1f3d069211cd 400 long title_offset;
davervw 0:1f3d069211cd 401 fread(&title_offset, sizeof(title_offset), 1, index);
davervw 0:1f3d069211cd 402 fclose(index);
davervw 0:1f3d069211cd 403
davervw 0:1f3d069211cd 404 long offset = ftell(fp);
davervw 0:1f3d069211cd 405 fseek(fp, title_offset, SEEK_SET);
davervw 0:1f3d069211cd 406 char* title = read_line();
davervw 0:1f3d069211cd 407 fseek(fp, offset, SEEK_SET);
davervw 0:1f3d069211cd 408
davervw 0:1f3d069211cd 409 return title;
davervw 0:1f3d069211cd 410 }
davervw 0:1f3d069211cd 411
davervw 0:1f3d069211cd 412 char* BibleIO::text_chapter(short book, short chapter)
davervw 0:1f3d069211cd 413 {
davervw 0:1f3d069211cd 414 if (book < 0 || book > num_books)
davervw 0:1f3d069211cd 415 return 0;
davervw 0:1f3d069211cd 416
davervw 0:1f3d069211cd 417 char* fn = index_path(book, chapter);
davervw 0:1f3d069211cd 418 FILE* index = fopen(fn, "r");
davervw 0:1f3d069211cd 419 delete [] fn;
davervw 0:1f3d069211cd 420 fn = 0;
davervw 0:1f3d069211cd 421
davervw 0:1f3d069211cd 422 if (index == 0)
davervw 0:1f3d069211cd 423 return 0;
davervw 0:1f3d069211cd 424
davervw 0:1f3d069211cd 425 long title_offset;
davervw 0:1f3d069211cd 426 fread(&title_offset, sizeof(title_offset), 1, index);
davervw 0:1f3d069211cd 427 fseek(index, 0, SEEK_END);
davervw 0:1f3d069211cd 428 long filesize = ftell(index);
davervw 0:1f3d069211cd 429 short num_verses = (filesize - sizeof(long)) / sizeof(chapter_index);
davervw 0:1f3d069211cd 430 fseek(index, sizeof(long) + (num_verses-1)*sizeof(long), SEEK_SET);
davervw 0:1f3d069211cd 431 long verse_offset = -1;
davervw 0:1f3d069211cd 432 fread(&verse_offset, sizeof(verse_offset), 1, index);
davervw 0:1f3d069211cd 433 fclose(index);
davervw 0:1f3d069211cd 434
davervw 0:1f3d069211cd 435 long offset = ftell(fp);
davervw 0:1f3d069211cd 436 fseek(fp, verse_offset, SEEK_SET);
davervw 0:1f3d069211cd 437 char* last_verse = read_line();
davervw 0:1f3d069211cd 438 delete [] last_verse;
davervw 0:1f3d069211cd 439 verse_offset = ftell(fp);
davervw 0:1f3d069211cd 440 fseek(fp, title_offset, SEEK_SET);
davervw 0:1f3d069211cd 441 int size = verse_offset-title_offset+1;
davervw 0:1f3d069211cd 442 char* text = new char[size];
davervw 0:1f3d069211cd 443 fread(text, size-1, 1, fp);
davervw 0:1f3d069211cd 444 text[size-1] = 0;
davervw 0:1f3d069211cd 445 fseek(fp, offset, SEEK_SET);
davervw 0:1f3d069211cd 446
davervw 0:1f3d069211cd 447 return text;
davervw 0:1f3d069211cd 448 }
davervw 0:1f3d069211cd 449
davervw 0:1f3d069211cd 450 char* BibleIO::text_verse(short book, short chapter, short verse)
davervw 0:1f3d069211cd 451 {
davervw 0:1f3d069211cd 452 //console.printf("text_verse: book %hd, chapter %hd, verse %hd\n", book, chapter, verse);
davervw 0:1f3d069211cd 453 if (book > num_books)
davervw 0:1f3d069211cd 454 return 0;
davervw 0:1f3d069211cd 455
davervw 0:1f3d069211cd 456 char* fn = index_path(book, chapter);
davervw 0:1f3d069211cd 457 FILE* index = fopen(fn, "r");
davervw 0:1f3d069211cd 458 delete [] fn;
davervw 0:1f3d069211cd 459 fn = 0;
davervw 0:1f3d069211cd 460
davervw 0:1f3d069211cd 461 if (index == 0)
davervw 0:1f3d069211cd 462 return 0;
davervw 0:1f3d069211cd 463
davervw 0:1f3d069211cd 464 fseek(index, 0, SEEK_END);
davervw 0:1f3d069211cd 465 long filesize = ftell(index);
davervw 0:1f3d069211cd 466 short num_verses = (filesize - sizeof(long)) / sizeof(chapter_index);
davervw 0:1f3d069211cd 467 if (verse >= num_verses || verse < 0)
davervw 0:1f3d069211cd 468 {
davervw 0:1f3d069211cd 469 fclose(index);
davervw 0:1f3d069211cd 470 return 0;
davervw 0:1f3d069211cd 471 }
davervw 0:1f3d069211cd 472 fseek(index, sizeof(long) + verse*sizeof(long), SEEK_SET);
davervw 0:1f3d069211cd 473 long verse_offset = -1;
davervw 0:1f3d069211cd 474 fread(&verse_offset, sizeof(verse_offset), 1, index);
davervw 0:1f3d069211cd 475 fclose(index);
davervw 0:1f3d069211cd 476
davervw 0:1f3d069211cd 477 long offset = ftell(fp);
davervw 0:1f3d069211cd 478 fseek(fp, verse_offset, SEEK_SET);
davervw 0:1f3d069211cd 479 char* text = read_line();
davervw 0:1f3d069211cd 480 fseek(fp, offset, SEEK_SET);
davervw 0:1f3d069211cd 481
davervw 0:1f3d069211cd 482 //console.printf("text: %s\n", text);
davervw 0:1f3d069211cd 483 return text;
davervw 0:1f3d069211cd 484 }
davervw 0:1f3d069211cd 485
davervw 0:1f3d069211cd 486 bool BibleIO::read_verse(FILE* index, short book, short chapter, short verse)
davervw 0:1f3d069211cd 487 {
davervw 0:1f3d069211cd 488 long offset = ftell(fp);
davervw 0:1f3d069211cd 489 char* line = 0;
davervw 0:1f3d069211cd 490
davervw 0:1f3d069211cd 491 do
davervw 0:1f3d069211cd 492 {
davervw 0:1f3d069211cd 493 delete [] line;
davervw 0:1f3d069211cd 494 line = BibleIO::read_line();
davervw 0:1f3d069211cd 495 } while (line != 0 && (*line == 0 || line[0] >= 'A' && line[0] <= 'Z' && line[strlen(line)-1] == '.'));
davervw 0:1f3d069211cd 496
davervw 0:1f3d069211cd 497 if (line == 0 || *line == 0 || atoi(line) == 0)
davervw 0:1f3d069211cd 498 {
davervw 0:1f3d069211cd 499 delete [] line;
davervw 0:1f3d069211cd 500 fseek(fp, offset, SEEK_SET);
davervw 0:1f3d069211cd 501 return false;
davervw 0:1f3d069211cd 502 }
davervw 0:1f3d069211cd 503
davervw 0:1f3d069211cd 504 short verse_num = atoi(line);
davervw 0:1f3d069211cd 505 delete [] line;
davervw 0:1f3d069211cd 506
davervw 0:1f3d069211cd 507 // !!! NOTE: this test fails at Philemon 1:2 because verses 1 & 2 are on the same line, for now ignore this test. Workaround is to edit text file to avoid error.
davervw 0:1f3d069211cd 508 // if (verse+1 != verse_num)
davervw 0:1f3d069211cd 509 // return false;
davervw 0:1f3d069211cd 510
davervw 0:1f3d069211cd 511 //console.printf("%d ", verse_num);
davervw 0:1f3d069211cd 512
davervw 0:1f3d069211cd 513 fwrite(&offset, sizeof(offset), 1, index);
davervw 0:1f3d069211cd 514
davervw 0:1f3d069211cd 515 return true;
davervw 0:1f3d069211cd 516 }
davervw 0:1f3d069211cd 517
davervw 0:1f3d069211cd 518 bool BibleIO::load_bookmarks()
davervw 0:1f3d069211cd 519 {
davervw 0:1f3d069211cd 520 delete [] bookmarks;
davervw 0:1f3d069211cd 521 bookmarks = 0;
davervw 0:1f3d069211cd 522 num_bookmarks = 0;
davervw 0:1f3d069211cd 523
davervw 0:1f3d069211cd 524 char* fn = index_path("marks");
davervw 0:1f3d069211cd 525 FILE* index = fopen(fn, "r");
davervw 0:1f3d069211cd 526 delete [] fn;
davervw 0:1f3d069211cd 527 fn = 0;
davervw 0:1f3d069211cd 528
davervw 0:1f3d069211cd 529 if (index == 0)
davervw 0:1f3d069211cd 530 return true; // okay it is not present yet, empty
davervw 0:1f3d069211cd 531
davervw 0:1f3d069211cd 532 fseek(index, 0, SEEK_END);
davervw 0:1f3d069211cd 533 long filesize = ftell(index);
davervw 0:1f3d069211cd 534 num_bookmarks = filesize / sizeof(position);
davervw 0:1f3d069211cd 535 fseek(index, 0, SEEK_SET);
davervw 0:1f3d069211cd 536 bookmarks = new position[num_bookmarks];
davervw 0:1f3d069211cd 537 fread(bookmarks, sizeof(position), num_bookmarks, index);
davervw 0:1f3d069211cd 538 fclose(index);
davervw 0:1f3d069211cd 539
davervw 0:1f3d069211cd 540 return true;
davervw 0:1f3d069211cd 541 }
davervw 0:1f3d069211cd 542
davervw 0:1f3d069211cd 543 bool BibleIO::save_bookmarks()
davervw 0:1f3d069211cd 544 {
davervw 0:1f3d069211cd 545 char* fn = index_path("marks");
davervw 0:1f3d069211cd 546 remove(fn);
davervw 0:1f3d069211cd 547 FILE* index = fopen(fn, "w");
davervw 0:1f3d069211cd 548 delete [] fn;
davervw 0:1f3d069211cd 549 fn = 0;
davervw 0:1f3d069211cd 550
davervw 0:1f3d069211cd 551 if (index == 0)
davervw 0:1f3d069211cd 552 return false;
davervw 0:1f3d069211cd 553
davervw 0:1f3d069211cd 554 fwrite(bookmarks, sizeof(position), num_bookmarks, index);
davervw 0:1f3d069211cd 555 fclose(index);
davervw 0:1f3d069211cd 556
davervw 0:1f3d069211cd 557 return true;
davervw 0:1f3d069211cd 558 }
davervw 0:1f3d069211cd 559
davervw 0:1f3d069211cd 560 bool BibleIO::bookmark_add(short book, short chapter, short verse)
davervw 0:1f3d069211cd 561 {
davervw 0:1f3d069211cd 562 int i;
davervw 0:1f3d069211cd 563 for (i=0; i<num_bookmarks; ++i)
davervw 0:1f3d069211cd 564 {
davervw 0:1f3d069211cd 565 if (bookmarks[i].book == book && bookmarks[i].chapter == chapter && bookmarks[i].verse == verse)
davervw 0:1f3d069211cd 566 {
davervw 0:1f3d069211cd 567 return false; // already present
davervw 0:1f3d069211cd 568 }
davervw 0:1f3d069211cd 569 }
davervw 0:1f3d069211cd 570
davervw 0:1f3d069211cd 571 // resize list
davervw 0:1f3d069211cd 572 position* new_bookmarks = new position[num_bookmarks+1];
davervw 0:1f3d069211cd 573 for (i=0; i<num_bookmarks; ++i)
davervw 0:1f3d069211cd 574 new_bookmarks[i] = bookmarks[i];
davervw 0:1f3d069211cd 575 new_bookmarks[i].book = book;
davervw 0:1f3d069211cd 576 new_bookmarks[i].chapter = chapter;
davervw 0:1f3d069211cd 577 new_bookmarks[i].verse = verse;
davervw 0:1f3d069211cd 578 new_bookmarks[i].rsvd = 0;
davervw 0:1f3d069211cd 579 delete [] bookmarks;
davervw 0:1f3d069211cd 580 bookmarks = new_bookmarks;
davervw 0:1f3d069211cd 581 ++num_bookmarks;
davervw 0:1f3d069211cd 582
davervw 0:1f3d069211cd 583 return save_bookmarks();
davervw 0:1f3d069211cd 584 }
davervw 0:1f3d069211cd 585
davervw 0:1f3d069211cd 586 bool BibleIO::bookmark_del(short book, short chapter, short verse)
davervw 0:1f3d069211cd 587 {
davervw 0:1f3d069211cd 588 // search for bookmark
davervw 0:1f3d069211cd 589 int i;
davervw 0:1f3d069211cd 590 for (i=0; i<num_bookmarks; ++i)
davervw 0:1f3d069211cd 591 if (bookmarks[i].book == book && bookmarks[i].chapter == chapter && bookmarks[i].verse == verse)
davervw 0:1f3d069211cd 592 break;
davervw 0:1f3d069211cd 593 if (i>=num_bookmarks)
davervw 0:1f3d069211cd 594 return false; // not found
davervw 0:1f3d069211cd 595
davervw 0:1f3d069211cd 596 // move previous entries down
davervw 0:1f3d069211cd 597 for (int j=i+1; j<num_bookmarks; ++j)
davervw 0:1f3d069211cd 598 bookmarks[j-1] = bookmarks[j];
davervw 0:1f3d069211cd 599
davervw 0:1f3d069211cd 600 --num_bookmarks;
davervw 0:1f3d069211cd 601
davervw 0:1f3d069211cd 602 // rewrite to filesystem
davervw 0:1f3d069211cd 603 return save_bookmarks();
davervw 0:1f3d069211cd 604 }
davervw 0:1f3d069211cd 605
davervw 0:1f3d069211cd 606 bool BibleIO::bookmark_prev(short &book, short &chapter, short &verse)
davervw 0:1f3d069211cd 607 {
davervw 0:1f3d069211cd 608 // search for bookmark
davervw 0:1f3d069211cd 609 int i;
davervw 0:1f3d069211cd 610 for (i=0; i<num_bookmarks; ++i)
davervw 0:1f3d069211cd 611 if (bookmarks[i].book == book && bookmarks[i].chapter == chapter && bookmarks[i].verse == verse)
davervw 0:1f3d069211cd 612 break;
davervw 0:1f3d069211cd 613 if (i==0)
davervw 0:1f3d069211cd 614 i=num_bookmarks; // wrap around
davervw 0:1f3d069211cd 615
davervw 0:1f3d069211cd 616 // previous
davervw 0:1f3d069211cd 617 --i;
davervw 0:1f3d069211cd 618
davervw 0:1f3d069211cd 619 if (i < 0 || i >= num_bookmarks)
davervw 0:1f3d069211cd 620 return false;
davervw 0:1f3d069211cd 621
davervw 0:1f3d069211cd 622 book = bookmarks[i].book;
davervw 0:1f3d069211cd 623 chapter = bookmarks[i].chapter;
davervw 0:1f3d069211cd 624 verse = bookmarks[i].verse;
davervw 0:1f3d069211cd 625
davervw 0:1f3d069211cd 626 return true;
davervw 0:1f3d069211cd 627 }
davervw 0:1f3d069211cd 628
davervw 0:1f3d069211cd 629 bool BibleIO::bookmark_next(short &book, short &chapter, short &verse)
davervw 0:1f3d069211cd 630 {
davervw 0:1f3d069211cd 631 // search for bookmark
davervw 0:1f3d069211cd 632 int i;
davervw 0:1f3d069211cd 633 for (i=0; i<num_bookmarks; ++i)
davervw 0:1f3d069211cd 634 if (bookmarks[i].book == book && bookmarks[i].chapter == chapter && bookmarks[i].verse == verse)
davervw 0:1f3d069211cd 635 break;
davervw 0:1f3d069211cd 636 // next
davervw 0:1f3d069211cd 637 if (++i >= num_bookmarks)
davervw 0:1f3d069211cd 638 i = 0;
davervw 0:1f3d069211cd 639
davervw 0:1f3d069211cd 640 if (i < 0 || i >= num_bookmarks)
davervw 0:1f3d069211cd 641 return false;
davervw 0:1f3d069211cd 642
davervw 0:1f3d069211cd 643 book = bookmarks[i].book;
davervw 0:1f3d069211cd 644 chapter = bookmarks[i].chapter;
davervw 0:1f3d069211cd 645 verse = bookmarks[i].verse;
davervw 0:1f3d069211cd 646
davervw 0:1f3d069211cd 647 return true;
davervw 0:1f3d069211cd 648 }
davervw 0:1f3d069211cd 649
davervw 0:1f3d069211cd 650 char* BibleIO::index_path()
davervw 0:1f3d069211cd 651 {
davervw 0:1f3d069211cd 652 char* path = index_path("");
davervw 0:1f3d069211cd 653 path[strlen(path)-1] = 0; // remove trailing slash
davervw 0:1f3d069211cd 654 return path;
davervw 0:1f3d069211cd 655 }
davervw 0:1f3d069211cd 656
davervw 0:1f3d069211cd 657 char* BibleIO::index_path(char* name)
davervw 0:1f3d069211cd 658 {
davervw 0:1f3d069211cd 659 int base_len = strrchr(text_filename, '/') + 1 - text_filename;
davervw 0:1f3d069211cd 660 int index_len = base_len + strlen("index/") + strlen(name);
davervw 0:1f3d069211cd 661 char* index = new char[index_len+1];
davervw 0:1f3d069211cd 662 memcpy(index, text_filename, base_len);
davervw 0:1f3d069211cd 663 index[base_len] = 0;
davervw 0:1f3d069211cd 664 strcat(index, "index/");
davervw 0:1f3d069211cd 665 strcat(index, name);
davervw 0:1f3d069211cd 666 return index;
davervw 0:1f3d069211cd 667 }
davervw 0:1f3d069211cd 668
davervw 0:1f3d069211cd 669 char* BibleIO::index_path(short book)
davervw 0:1f3d069211cd 670 {
davervw 0:1f3d069211cd 671 char indexname[50];
davervw 0:1f3d069211cd 672 sprintf(indexname, "%hd", book);
davervw 0:1f3d069211cd 673 return index_path(indexname);
davervw 0:1f3d069211cd 674 }
davervw 0:1f3d069211cd 675
davervw 0:1f3d069211cd 676 char* BibleIO::index_path(short book, short chapter)
davervw 0:1f3d069211cd 677 {
davervw 0:1f3d069211cd 678 char indexname[50];
davervw 0:1f3d069211cd 679 sprintf(indexname, "%hd/%hd", book, chapter);
davervw 0:1f3d069211cd 680 return index_path(indexname);
davervw 0:1f3d069211cd 681 }