annotate open.cpp @ 596:6ad0a6e67d4c

Take advantage of those new handy _or_goto_error macros Use them in various places where previously we either elided the error checking (various lseek() calls) or used a combination of calls (replaced by malloc_and_fill_or_goto_error()). In the process, fix what is probably a bug (or else introduce one, but I don't think so): audiodb_track_id_datum() computed the offset into the timesTable wrongly, forgetting to multiply by 2. (TODO: this should be easily testable using the API). Now all of LIBOBJS can be produced by my (Debian's) mingw32 cross-compiler, except for lshlib.o.
author mas01cr
date Tue, 11 Aug 2009 21:42:49 +0000
parents cfa74bcc1249
children b1723ae7675e
rev   line source
mas01cr@498 1 extern "C" {
mas01cr@498 2 #include "audioDB_API.h"
mas01cr@509 3 }
mas01cr@498 4 #include "audioDB-internals.h"
mas01cr@498 5
mas01cr@498 6 static bool audiodb_check_header(adb_header_t *header) {
mas01cr@498 7 /* FIXME: use syslog() or write to stderr or something to give the
mas01cr@498 8 poor user some diagnostics. */
mas01cr@509 9 if(header->magic == ADB_OLD_MAGIC) {
mas01cr@498 10 return false;
mas01cr@498 11 }
mas01cr@509 12 if(header->magic != ADB_MAGIC) {
mas01cr@498 13 return false;
mas01cr@498 14 }
mas01cr@509 15 if(header->version != ADB_FORMAT_VERSION) {
mas01cr@498 16 return false;
mas01cr@498 17 }
mas01cr@509 18 if(header->headerSize != ADB_HEADER_SIZE) {
mas01cr@498 19 return false;
mas01cr@498 20 }
mas01cr@498 21 return true;
mas01cr@498 22 }
mas01cr@498 23
mas01cr@498 24 static int audiodb_collect_keys(adb_t *adb) {
mas01cr@498 25 char *key_table = 0;
mas01cr@498 26 size_t key_table_length = 0;
mas01cr@498 27
mas01cr@498 28 if(adb->header->length > 0) {
mas01cr@498 29 unsigned nfiles = adb->header->numFiles;
mas01cr@509 30 key_table_length = align_page_up(nfiles * ADB_FILETABLE_ENTRY_SIZE);
mas01cr@596 31 malloc_and_fill_or_goto_error(char *, key_table, adb->header->fileTableOffset, key_table_length);
mas01cr@498 32 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@509 33 adb->keys->push_back(key_table + k*ADB_FILETABLE_ENTRY_SIZE);
mas01cr@509 34 (*adb->keymap)[(key_table + k*ADB_FILETABLE_ENTRY_SIZE)] = k;
mas01cr@498 35 }
mas01cr@592 36 free(key_table);
mas01cr@498 37 }
mas01cr@498 38
mas01cr@498 39 return 0;
mas01cr@498 40
mas01cr@498 41 error:
mas01cr@596 42 maybe_free(key_table);
mas01cr@498 43 return 1;
mas01cr@498 44 }
mas01cr@498 45
mas01cr@498 46 static int audiodb_collect_track_lengths(adb_t *adb) {
mas01cr@498 47 uint32_t *track_table = 0;
mas01cr@498 48 size_t track_table_length = 0;
mas01cr@498 49 if(adb->header->length > 0) {
mas01cr@498 50 unsigned nfiles = adb->header->numFiles;
mas01cr@509 51 track_table_length = align_page_up(nfiles * ADB_TRACKTABLE_ENTRY_SIZE);
mas01cr@596 52 malloc_and_fill_or_goto_error(uint32_t *, track_table, adb->header->trackTableOffset, track_table_length);
mas01cr@498 53 off_t offset = 0;
mas01cr@498 54 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@498 55 uint32_t track_length = track_table[k];
mas01cr@498 56 adb->track_lengths->push_back(track_length);
mas01cr@498 57 adb->track_offsets->push_back(offset);
mas01cr@498 58 offset += track_length * adb->header->dim * sizeof(double);
mas01cr@498 59 }
mas01cr@592 60 free(track_table);
mas01cr@498 61 }
mas01cr@498 62
mas01cr@498 63 return 0;
mas01cr@498 64
mas01cr@498 65 error:
mas01cr@596 66 maybe_free(track_table);
mas01cr@498 67 return 1;
mas01cr@498 68 }
mas01cr@498 69
mas01cr@498 70 adb_t *audiodb_open(const char *path, int flags) {
mas01cr@498 71 adb_t *adb = 0;
mas01cr@498 72 int fd = -1;
mas01cr@498 73
mas01cr@498 74 flags &= (O_RDONLY|O_RDWR);
mas01cr@498 75 fd = open(path, flags);
mas01cr@498 76 if(fd == -1) {
mas01cr@498 77 goto error;
mas01cr@498 78 }
mas01cr@498 79 if(acquire_lock(fd, flags == O_RDWR)) {
mas01cr@498 80 goto error;
mas01cr@498 81 }
mas01cr@498 82
mas01cr@498 83 adb = (adb_t *) calloc(1, sizeof(adb_t));
mas01cr@498 84 if(!adb) {
mas01cr@498 85 goto error;
mas01cr@498 86 }
mas01cr@498 87 adb->fd = fd;
mas01cr@498 88 adb->flags = flags;
mas01cr@498 89 adb->path = (char *) malloc(1+strlen(path));
mas01cr@498 90 if(!(adb->path)) {
mas01cr@498 91 goto error;
mas01cr@498 92 }
mas01cr@498 93 strcpy(adb->path, path);
mas01cr@498 94
mas01cr@498 95 adb->header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@498 96 if(!(adb->header)) {
mas01cr@498 97 goto error;
mas01cr@498 98 }
mas01cr@509 99 if(read(fd, (char *) adb->header, ADB_HEADER_SIZE) != ADB_HEADER_SIZE) {
mas01cr@498 100 goto error;
mas01cr@498 101 }
mas01cr@498 102 if(!audiodb_check_header(adb->header)) {
mas01cr@498 103 goto error;
mas01cr@498 104 }
mas01cr@498 105
mas01cr@498 106 adb->keys = new std::vector<std::string>;
mas01cr@498 107 if(!adb->keys) {
mas01cr@498 108 goto error;
mas01cr@498 109 }
mas01cr@498 110 adb->keymap = new std::map<std::string,uint32_t>;
mas01cr@498 111 if(!adb->keymap) {
mas01cr@498 112 goto error;
mas01cr@498 113 }
mas01cr@498 114 if(audiodb_collect_keys(adb)) {
mas01cr@498 115 goto error;
mas01cr@498 116 }
mas01cr@498 117 adb->track_lengths = new std::vector<uint32_t>;
mas01cr@498 118 if(!adb->track_lengths) {
mas01cr@498 119 goto error;
mas01cr@498 120 }
mas01cr@498 121 adb->track_lengths->reserve(adb->header->numFiles);
mas01cr@498 122 adb->track_offsets = new std::vector<off_t>;
mas01cr@498 123 if(!adb->track_offsets) {
mas01cr@498 124 goto error;
mas01cr@498 125 }
mas01cr@498 126 adb->track_offsets->reserve(adb->header->numFiles);
mas01cr@498 127 if(audiodb_collect_track_lengths(adb)) {
mas01cr@498 128 goto error;
mas01cr@498 129 }
mas01cr@498 130 adb->cached_lsh = 0;
mas01cr@498 131 return adb;
mas01cr@498 132
mas01cr@498 133 error:
mas01cr@498 134 if(adb) {
mas01cr@596 135 maybe_free(adb->header);
mas01cr@596 136 maybe_free(adb->path);
mas01cr@498 137 if(adb->keys) {
mas01cr@498 138 delete adb->keys;
mas01cr@498 139 }
mas01cr@498 140 if(adb->keymap) {
mas01cr@498 141 delete adb->keymap;
mas01cr@498 142 }
mas01cr@498 143 if(adb->track_lengths) {
mas01cr@498 144 delete adb->track_lengths;
mas01cr@498 145 }
mas01cr@498 146 free(adb);
mas01cr@498 147 }
mas01cr@498 148 if(fd != -1) {
mas01cr@498 149 close(fd);
mas01cr@498 150 }
mas01cr@498 151 return NULL;
mas01cr@498 152 }