annotate open.cpp @ 592:cfa74bcc1249

Remove uses of mmap() from open.cpp (These are relatively easy to deal with; just replace them with an lseek()/read() pair. Of course, now we're destructively modifying the fd position; I'd have liked to use pread() but, surprise, that's not available on mingw.)
author mas01cr
date Tue, 11 Aug 2009 21:42:29 +0000
parents cc2b97d020b1
children 6ad0a6e67d4c
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@592 31 key_table = (char *)malloc(key_table_length);
mas01cr@592 32 if(!key_table) {
mas01cr@592 33 goto error;
mas01cr@592 34 }
mas01cr@592 35 lseek_set_or_goto_error(adb->fd, adb->header->fileTableOffset);
mas01cr@592 36 read_or_goto_error(adb->fd, key_table, key_table_length);
mas01cr@498 37 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@509 38 adb->keys->push_back(key_table + k*ADB_FILETABLE_ENTRY_SIZE);
mas01cr@509 39 (*adb->keymap)[(key_table + k*ADB_FILETABLE_ENTRY_SIZE)] = k;
mas01cr@498 40 }
mas01cr@592 41 free(key_table);
mas01cr@498 42 }
mas01cr@498 43
mas01cr@498 44 return 0;
mas01cr@498 45
mas01cr@498 46 error:
mas01cr@592 47 if(key_table) {
mas01cr@592 48 free(key_table);
mas01cr@592 49 }
mas01cr@498 50 return 1;
mas01cr@498 51 }
mas01cr@498 52
mas01cr@498 53 static int audiodb_collect_track_lengths(adb_t *adb) {
mas01cr@498 54 uint32_t *track_table = 0;
mas01cr@498 55 size_t track_table_length = 0;
mas01cr@498 56 if(adb->header->length > 0) {
mas01cr@498 57 unsigned nfiles = adb->header->numFiles;
mas01cr@509 58 track_table_length = align_page_up(nfiles * ADB_TRACKTABLE_ENTRY_SIZE);
mas01cr@592 59 track_table = (uint32_t *) malloc(track_table_length);
mas01cr@592 60 if (!track_table) {
mas01cr@592 61 goto error;
mas01cr@592 62 }
mas01cr@592 63 lseek_set_or_goto_error(adb->fd, adb->header->trackTableOffset);
mas01cr@592 64 read_or_goto_error(adb->fd, track_table, track_table_length);
mas01cr@498 65 off_t offset = 0;
mas01cr@498 66 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@498 67 uint32_t track_length = track_table[k];
mas01cr@498 68 adb->track_lengths->push_back(track_length);
mas01cr@498 69 adb->track_offsets->push_back(offset);
mas01cr@498 70 offset += track_length * adb->header->dim * sizeof(double);
mas01cr@498 71 }
mas01cr@592 72 free(track_table);
mas01cr@498 73 }
mas01cr@498 74
mas01cr@498 75 return 0;
mas01cr@498 76
mas01cr@498 77 error:
mas01cr@592 78 if(track_table) {
mas01cr@592 79 free(track_table);
mas01cr@592 80 }
mas01cr@498 81 return 1;
mas01cr@498 82 }
mas01cr@498 83
mas01cr@498 84 adb_t *audiodb_open(const char *path, int flags) {
mas01cr@498 85 adb_t *adb = 0;
mas01cr@498 86 int fd = -1;
mas01cr@498 87
mas01cr@498 88 flags &= (O_RDONLY|O_RDWR);
mas01cr@498 89 fd = open(path, flags);
mas01cr@498 90 if(fd == -1) {
mas01cr@498 91 goto error;
mas01cr@498 92 }
mas01cr@498 93 if(acquire_lock(fd, flags == O_RDWR)) {
mas01cr@498 94 goto error;
mas01cr@498 95 }
mas01cr@498 96
mas01cr@498 97 adb = (adb_t *) calloc(1, sizeof(adb_t));
mas01cr@498 98 if(!adb) {
mas01cr@498 99 goto error;
mas01cr@498 100 }
mas01cr@498 101 adb->fd = fd;
mas01cr@498 102 adb->flags = flags;
mas01cr@498 103 adb->path = (char *) malloc(1+strlen(path));
mas01cr@498 104 if(!(adb->path)) {
mas01cr@498 105 goto error;
mas01cr@498 106 }
mas01cr@498 107 strcpy(adb->path, path);
mas01cr@498 108
mas01cr@498 109 adb->header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@498 110 if(!(adb->header)) {
mas01cr@498 111 goto error;
mas01cr@498 112 }
mas01cr@509 113 if(read(fd, (char *) adb->header, ADB_HEADER_SIZE) != ADB_HEADER_SIZE) {
mas01cr@498 114 goto error;
mas01cr@498 115 }
mas01cr@498 116 if(!audiodb_check_header(adb->header)) {
mas01cr@498 117 goto error;
mas01cr@498 118 }
mas01cr@498 119
mas01cr@498 120 adb->keys = new std::vector<std::string>;
mas01cr@498 121 if(!adb->keys) {
mas01cr@498 122 goto error;
mas01cr@498 123 }
mas01cr@498 124 adb->keymap = new std::map<std::string,uint32_t>;
mas01cr@498 125 if(!adb->keymap) {
mas01cr@498 126 goto error;
mas01cr@498 127 }
mas01cr@498 128 if(audiodb_collect_keys(adb)) {
mas01cr@498 129 goto error;
mas01cr@498 130 }
mas01cr@498 131 adb->track_lengths = new std::vector<uint32_t>;
mas01cr@498 132 if(!adb->track_lengths) {
mas01cr@498 133 goto error;
mas01cr@498 134 }
mas01cr@498 135 adb->track_lengths->reserve(adb->header->numFiles);
mas01cr@498 136 adb->track_offsets = new std::vector<off_t>;
mas01cr@498 137 if(!adb->track_offsets) {
mas01cr@498 138 goto error;
mas01cr@498 139 }
mas01cr@498 140 adb->track_offsets->reserve(adb->header->numFiles);
mas01cr@498 141 if(audiodb_collect_track_lengths(adb)) {
mas01cr@498 142 goto error;
mas01cr@498 143 }
mas01cr@498 144 adb->cached_lsh = 0;
mas01cr@498 145 return adb;
mas01cr@498 146
mas01cr@498 147 error:
mas01cr@498 148 if(adb) {
mas01cr@498 149 if(adb->header) {
mas01cr@498 150 free(adb->header);
mas01cr@498 151 }
mas01cr@498 152 if(adb->path) {
mas01cr@498 153 free(adb->path);
mas01cr@498 154 }
mas01cr@498 155 if(adb->keys) {
mas01cr@498 156 delete adb->keys;
mas01cr@498 157 }
mas01cr@498 158 if(adb->keymap) {
mas01cr@498 159 delete adb->keymap;
mas01cr@498 160 }
mas01cr@498 161 if(adb->track_lengths) {
mas01cr@498 162 delete adb->track_lengths;
mas01cr@498 163 }
mas01cr@498 164 free(adb);
mas01cr@498 165 }
mas01cr@498 166 if(fd != -1) {
mas01cr@498 167 close(fd);
mas01cr@498 168 }
mas01cr@498 169 return NULL;
mas01cr@498 170 }