annotate open.cpp @ 507:e7fd50483311

Free bits of the datum constructed in audioDB::query. We're not quite safe: error calls between allocation of some of these bits and pieces and their use will cause failure... but not freeing things here is definitely wrong.
author mas01cr
date Tue, 13 Jan 2009 21:37:10 +0000
parents 342822c2d49a
children cc2b97d020b1
rev   line source
mas01cr@498 1 #include "audioDB.h"
mas01cr@498 2 extern "C" {
mas01cr@498 3 #include "audioDB_API.h"
mas01cr@498 4 #include "audioDB-internals.h"
mas01cr@498 5 }
mas01cr@498 6
mas01cr@498 7 static bool audiodb_check_header(adb_header_t *header) {
mas01cr@498 8 /* FIXME: use syslog() or write to stderr or something to give the
mas01cr@498 9 poor user some diagnostics. */
mas01cr@498 10 if(header->magic == O2_OLD_MAGIC) {
mas01cr@498 11 return false;
mas01cr@498 12 }
mas01cr@498 13 if(header->magic != O2_MAGIC) {
mas01cr@498 14 return false;
mas01cr@498 15 }
mas01cr@498 16 if(header->version != O2_FORMAT_VERSION) {
mas01cr@498 17 return false;
mas01cr@498 18 }
mas01cr@498 19 if(header->headerSize != O2_HEADERSIZE) {
mas01cr@498 20 return false;
mas01cr@498 21 }
mas01cr@498 22 return true;
mas01cr@498 23 }
mas01cr@498 24
mas01cr@498 25 static int audiodb_collect_keys(adb_t *adb) {
mas01cr@498 26 char *key_table = 0;
mas01cr@498 27 size_t key_table_length = 0;
mas01cr@498 28
mas01cr@498 29 if(adb->header->length > 0) {
mas01cr@498 30 unsigned nfiles = adb->header->numFiles;
mas01cr@498 31 key_table_length = ALIGN_PAGE_UP(nfiles * O2_FILETABLE_ENTRY_SIZE);
mas01cr@498 32 mmap_or_goto_error(char *, key_table, adb->header->fileTableOffset, key_table_length);
mas01cr@498 33 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@498 34 adb->keys->push_back(key_table + k*O2_FILETABLE_ENTRY_SIZE);
mas01cr@498 35 (*adb->keymap)[(key_table + k*O2_FILETABLE_ENTRY_SIZE)] = k;
mas01cr@498 36 }
mas01cr@498 37 munmap(key_table, key_table_length);
mas01cr@498 38 }
mas01cr@498 39
mas01cr@498 40 return 0;
mas01cr@498 41
mas01cr@498 42 error:
mas01cr@498 43 maybe_munmap(key_table, key_table_length);
mas01cr@498 44 return 1;
mas01cr@498 45 }
mas01cr@498 46
mas01cr@498 47 static int audiodb_collect_track_lengths(adb_t *adb) {
mas01cr@498 48 uint32_t *track_table = 0;
mas01cr@498 49 size_t track_table_length = 0;
mas01cr@498 50 if(adb->header->length > 0) {
mas01cr@498 51 unsigned nfiles = adb->header->numFiles;
mas01cr@498 52 track_table_length = ALIGN_PAGE_UP(nfiles * O2_TRACKTABLE_ENTRY_SIZE);
mas01cr@498 53 mmap_or_goto_error(uint32_t *, track_table, adb->header->trackTableOffset, track_table_length);
mas01cr@498 54 off_t offset = 0;
mas01cr@498 55 for (unsigned int k = 0; k < nfiles; k++) {
mas01cr@498 56 uint32_t track_length = track_table[k];
mas01cr@498 57 adb->track_lengths->push_back(track_length);
mas01cr@498 58 adb->track_offsets->push_back(offset);
mas01cr@498 59 offset += track_length * adb->header->dim * sizeof(double);
mas01cr@498 60 }
mas01cr@498 61 munmap(track_table, track_table_length);
mas01cr@498 62 }
mas01cr@498 63
mas01cr@498 64 return 0;
mas01cr@498 65
mas01cr@498 66 error:
mas01cr@498 67 maybe_munmap(track_table, track_table_length);
mas01cr@498 68 return 1;
mas01cr@498 69 }
mas01cr@498 70
mas01cr@498 71 adb_t *audiodb_open(const char *path, int flags) {
mas01cr@498 72 adb_t *adb = 0;
mas01cr@498 73 int fd = -1;
mas01cr@498 74
mas01cr@498 75 flags &= (O_RDONLY|O_RDWR);
mas01cr@498 76 fd = open(path, flags);
mas01cr@498 77 if(fd == -1) {
mas01cr@498 78 goto error;
mas01cr@498 79 }
mas01cr@498 80 if(acquire_lock(fd, flags == O_RDWR)) {
mas01cr@498 81 goto error;
mas01cr@498 82 }
mas01cr@498 83
mas01cr@498 84 adb = (adb_t *) calloc(1, sizeof(adb_t));
mas01cr@498 85 if(!adb) {
mas01cr@498 86 goto error;
mas01cr@498 87 }
mas01cr@498 88 adb->fd = fd;
mas01cr@498 89 adb->flags = flags;
mas01cr@498 90 adb->path = (char *) malloc(1+strlen(path));
mas01cr@498 91 if(!(adb->path)) {
mas01cr@498 92 goto error;
mas01cr@498 93 }
mas01cr@498 94 strcpy(adb->path, path);
mas01cr@498 95
mas01cr@498 96 adb->header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@498 97 if(!(adb->header)) {
mas01cr@498 98 goto error;
mas01cr@498 99 }
mas01cr@498 100 if(read(fd, (char *) adb->header, O2_HEADERSIZE) != O2_HEADERSIZE) {
mas01cr@498 101 goto error;
mas01cr@498 102 }
mas01cr@498 103 if(!audiodb_check_header(adb->header)) {
mas01cr@498 104 goto error;
mas01cr@498 105 }
mas01cr@498 106
mas01cr@498 107 adb->keys = new std::vector<std::string>;
mas01cr@498 108 if(!adb->keys) {
mas01cr@498 109 goto error;
mas01cr@498 110 }
mas01cr@498 111 adb->keymap = new std::map<std::string,uint32_t>;
mas01cr@498 112 if(!adb->keymap) {
mas01cr@498 113 goto error;
mas01cr@498 114 }
mas01cr@498 115 if(audiodb_collect_keys(adb)) {
mas01cr@498 116 goto error;
mas01cr@498 117 }
mas01cr@498 118 adb->track_lengths = new std::vector<uint32_t>;
mas01cr@498 119 if(!adb->track_lengths) {
mas01cr@498 120 goto error;
mas01cr@498 121 }
mas01cr@498 122 adb->track_lengths->reserve(adb->header->numFiles);
mas01cr@498 123 adb->track_offsets = new std::vector<off_t>;
mas01cr@498 124 if(!adb->track_offsets) {
mas01cr@498 125 goto error;
mas01cr@498 126 }
mas01cr@498 127 adb->track_offsets->reserve(adb->header->numFiles);
mas01cr@498 128 if(audiodb_collect_track_lengths(adb)) {
mas01cr@498 129 goto error;
mas01cr@498 130 }
mas01cr@498 131 adb->cached_lsh = 0;
mas01cr@498 132 return adb;
mas01cr@498 133
mas01cr@498 134 error:
mas01cr@498 135 if(adb) {
mas01cr@498 136 if(adb->header) {
mas01cr@498 137 free(adb->header);
mas01cr@498 138 }
mas01cr@498 139 if(adb->path) {
mas01cr@498 140 free(adb->path);
mas01cr@498 141 }
mas01cr@498 142 if(adb->keys) {
mas01cr@498 143 delete adb->keys;
mas01cr@498 144 }
mas01cr@498 145 if(adb->keymap) {
mas01cr@498 146 delete adb->keymap;
mas01cr@498 147 }
mas01cr@498 148 if(adb->track_lengths) {
mas01cr@498 149 delete adb->track_lengths;
mas01cr@498 150 }
mas01cr@498 151 free(adb);
mas01cr@498 152 }
mas01cr@498 153 if(fd != -1) {
mas01cr@498 154 close(fd);
mas01cr@498 155 }
mas01cr@498 156 return NULL;
mas01cr@498 157 }