annotate open.cpp @ 509:cc2b97d020b1

Code rearrangements to tease apart library code from C++ audioDB code. There should be precisely no functional changes in this commit. Instead, the only thing that has happened is that all the abstraction violation and other horribleness is concentrated in one place: the include of "audioDB-internals.h" in audioDB.h -- the separation will be complete once that include can be removed. This include is necessary because the command-line binary / SOAP server still does some things directly rather than through an API: not least of which the operations that have not yet been integrated into the API yet, but also some messing around with constants, flags and nominally internal functions. The intent is to remove as many of these as possible and think quite hard about the rest. In the meantime, the library is now much more self-contained: the only things it uses are in the audioDB_API.h and audioDB-internals.h headers; thus there are fewer nasty surprises lurking for readers of the code. The Makefile has been adjusted to take advantage of this rearrangement in the dependencies.
author mas01cr
date Thu, 15 Jan 2009 13:57:33 +0000
parents 342822c2d49a
children cfa74bcc1249
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@498 31 mmap_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@498 36 munmap(key_table, key_table_length);
mas01cr@498 37 }
mas01cr@498 38
mas01cr@498 39 return 0;
mas01cr@498 40
mas01cr@498 41 error:
mas01cr@498 42 maybe_munmap(key_table, key_table_length);
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@498 52 mmap_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@498 60 munmap(track_table, track_table_length);
mas01cr@498 61 }
mas01cr@498 62
mas01cr@498 63 return 0;
mas01cr@498 64
mas01cr@498 65 error:
mas01cr@498 66 maybe_munmap(track_table, track_table_length);
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@498 135 if(adb->header) {
mas01cr@498 136 free(adb->header);
mas01cr@498 137 }
mas01cr@498 138 if(adb->path) {
mas01cr@498 139 free(adb->path);
mas01cr@498 140 }
mas01cr@498 141 if(adb->keys) {
mas01cr@498 142 delete adb->keys;
mas01cr@498 143 }
mas01cr@498 144 if(adb->keymap) {
mas01cr@498 145 delete adb->keymap;
mas01cr@498 146 }
mas01cr@498 147 if(adb->track_lengths) {
mas01cr@498 148 delete adb->track_lengths;
mas01cr@498 149 }
mas01cr@498 150 free(adb);
mas01cr@498 151 }
mas01cr@498 152 if(fd != -1) {
mas01cr@498 153 close(fd);
mas01cr@498 154 }
mas01cr@498 155 return NULL;
mas01cr@498 156 }