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