diff options
| author | Jonathan Gordon <rockbox@jdgordon.info> | 2006-10-25 14:30:45 +0000 |
|---|---|---|
| committer | Jonathan Gordon <rockbox@jdgordon.info> | 2006-10-25 14:30:45 +0000 |
| commit | e48a0354093a5c7f26d67f5584dfb2f38f680870 (patch) | |
| tree | aab8d06f6fa3aa8b8bafe3f8e1a33ad6e0db72cb | |
| parent | 18755b97c014365387f42ea2acd8e9982982fb00 (diff) | |
| download | rockbox-e48a0354093a5c7f26d67f5584dfb2f38f680870.zip rockbox-e48a0354093a5c7f26d67f5584dfb2f38f680870.tar.gz rockbox-e48a0354093a5c7f26d67f5584dfb2f38f680870.tar.bz2 rockbox-e48a0354093a5c7f26d67f5584dfb2f38f680870.tar.xz | |
remove the old tagdb source, tagcache replaced this a while ago
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11340 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | apps/tagdb/album.c | 456 | ||||
| -rw-r--r-- | apps/tagdb/album.h | 105 | ||||
| -rw-r--r-- | apps/tagdb/array_buffer.c | 668 | ||||
| -rw-r--r-- | apps/tagdb/array_buffer.h | 161 | ||||
| -rw-r--r-- | apps/tagdb/artist.c | 372 | ||||
| -rw-r--r-- | apps/tagdb/artist.h | 102 | ||||
| -rw-r--r-- | apps/tagdb/config.h | 41 | ||||
| -rw-r--r-- | apps/tagdb/db.c | 605 | ||||
| -rw-r--r-- | apps/tagdb/db.h | 39 | ||||
| -rw-r--r-- | apps/tagdb/file.c | 270 | ||||
| -rw-r--r-- | apps/tagdb/file.h | 86 | ||||
| -rw-r--r-- | apps/tagdb/header.c | 122 | ||||
| -rw-r--r-- | apps/tagdb/header.h | 41 | ||||
| -rw-r--r-- | apps/tagdb/main.c | 117 | ||||
| -rw-r--r-- | apps/tagdb/malloc.c | 133 | ||||
| -rw-r--r-- | apps/tagdb/malloc.h | 18 | ||||
| -rw-r--r-- | apps/tagdb/parser.c | 219 | ||||
| -rw-r--r-- | apps/tagdb/song.c | 452 | ||||
| -rw-r--r-- | apps/tagdb/song.h | 95 | ||||
| -rw-r--r-- | apps/tagdb/tag_dummy.c | 13 | ||||
| -rw-r--r-- | apps/tagdb/tag_dummy.h | 5 | ||||
| -rw-r--r-- | apps/tagdb/unique.c | 18 | ||||
| -rw-r--r-- | apps/tagdb/unique.h | 8 |
23 files changed, 0 insertions, 4146 deletions
diff --git a/apps/tagdb/album.c b/apps/tagdb/album.c deleted file mode 100644 index 0c06329..0000000 --- a/apps/tagdb/album.c +++ /dev/null @@ -1,456 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "malloc.h" // realloc() and free() -#include <strings.h> // strncasecmp() -#include <string.h> // strlen() - -#include "album.h" - -// how is our flag organized? -#define FLAG(deleted, spare) ( 0xE0 | (deleted?0x10:0x00) | (spare & 0x0F) ) -#define FLAG_VALID(flag) ((flag & 0xE0) == 0xE0) -#define FLAG_DELETED(flag) (flag & 0x10) -#define FLAG_SPARE(flag) (flag & 0x0F) - -static int do_resize(struct album_entry *e, const uint32_t name_len, const uint32_t song_count, const int zero_fill); - -struct album_entry* new_album_entry(const uint32_t name_len, const uint32_t song_count) { - // Start my allocating memory - struct album_entry *e = (struct album_entry*)malloc(sizeof(struct album_entry)); - if( e == NULL ) { - DEBUGF("new_album_entry: could not allocate memory\n"); - return NULL; - } - - // We begin empty - e->name = NULL; - e->size.name_len = 0; - e->key = NULL; - e->artist = 0; - e->song = NULL; - e->size.song_count = 0; - - e->flag = FLAG(0, 0); - - // and resize to the requested size - if( do_resize(e, name_len, song_count, 1) ) { - free(e); - return NULL; - } - return e; -} - -int album_entry_destruct(struct album_entry *e) { - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - free(e->name); - free(e->key); - free(e->song); - - free(e); - - return ERR_NONE; -} - -static int do_resize(struct album_entry *e, const uint32_t name_len, const uint32_t song_count, const int zero_fill) { - void* temp; - - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - // begin with name - if( name_len != e->size.name_len ) { - temp = realloc(e->name, name_len); - if(temp == NULL && name_len > 0) { // if realloc(,0) don't complain about NULL-pointer - DEBUGF("do_resize: out of memory to resize name\n"); - return ERR_MALLOC; - } - e->name = (char*)temp; - - // if asked, fill it with zero's - if( zero_fill ) { - uint32_t i; - for(i=e->size.name_len; i<name_len; i++) - e->name[i] = (char)0x00; - } - - e->size.name_len = name_len; - } - - // now the song[] - if( song_count != e->size.song_count ) { - temp = realloc(e->song, song_count * sizeof(*e->song)); - if(temp == NULL && song_count > 0) { // if realloc(,0) don't complain about NULL-pointer - DEBUGF("album_entry_resize: out of memory to resize song[]\n"); - return ERR_MALLOC; - } - e->song = (uint32_t*)temp; - - // if asked, fill it with zero's - if( zero_fill ) { - uint32_t i; - for(i=e->size.song_count; i<song_count; i++) - e->song[i] = (uint32_t)0x00000000; - } - - e->size.song_count = song_count; - } - - return ERR_NONE; -} - -inline int album_entry_resize(struct album_entry *e, const uint32_t name_len, const uint32_t song_count) { - return do_resize(e, name_len, song_count, 1); -} - -int album_entry_serialize(FILE *fd, const struct album_entry *e) { - uint32_t length; - - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - assert(fd != NULL); - - if( FLAG_DELETED(e->flag) ) { // we are deleted, do nothing - return ERR_NONE; - } - - // First byte we write is a flag-byte - if( fwrite(&e->flag, 1, 1, fd) != 1 ) { - DEBUGF("album_entry_serialize: failed to write flag-byte\n"); - return ERR_FILE; - } - - // First we write the length of the name field - if( fwrite(&e->size.name_len, sizeof(e->size.name_len), 1, fd) != 1 ) { - DEBUGF("album_entry_serialize: failed to write name_len\n"); - return ERR_FILE; - } - - // now the name field itself - if( fwrite(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("album_entry_serialize: failed to write name\n"); - return ERR_FILE; - } - - // the key-field (if present) - if( e->key != NULL ) { - length = strlen(e->key); - } else { - length = 0; - } - // length (always, 0 if not present) - if( fwrite(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("album_entry_serialize: failed to write length of key\n"); - return ERR_FILE; - } - if( e->key != NULL ) { - // key itself - if( fwrite(e->key, 1, length, fd) != length ) { - DEBUGF("album_entry_serialize: failed to write key\n"); - return ERR_FILE; - } - } - - // Artist field - if( fwrite(&e->artist, sizeof(e->artist), 1, fd) != 1 ) { - DEBUGF("album_entry_serialize: failed to write artist\n"); - return ERR_FILE; - } - - // count of songs - if( fwrite(&e->size.song_count, sizeof(e->size.song_count), 1, fd) != 1 ) { - DEBUGF("album_entry_serialize: failed to write song_count\n"); - return ERR_FILE; - } - - // song[] itself - if( fwrite(e->song, sizeof(*e->song), e->size.song_count, fd) != e->size.song_count ) { - DEBUGF("album_entry_serialize: failed to write songs\n"); - return ERR_FILE; - } - - return ERR_NONE; -} - -int album_entry_unserialize(struct album_entry **e, FILE *fd) { - uint32_t length; - unsigned char flag; - - assert(e != NULL); - assert(fd != NULL); - - // First byte we read are the flags - if( fread(&flag, 1, 1, fd) != 1 ) { - DEBUGF("album_entry_unserialize: failed to read flag-byte\n"); - return ERR_FILE; - } - - // See what we have: - if( ! FLAG_VALID(flag) ) { - DEBUGF("album_entry_unserialize: flag-byte is invalid\n"); - return ERR_INVALID; - } - - // Allocate memory - *e = new_album_entry(0, 0); - if( *e == NULL ) { - DEBUGF("album_entry_unserialize: could not create new album_entry\n"); - return ERR_MALLOC; - } - - (*e)->flag = flag; // we had a valid entry, copy it over - - // First we read the length of the name field - if( fread(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("album_entry_unserialize: failed to read name_len\n"); - album_entry_destruct(*e); - return ERR_FILE; - } - - // allocate memory for the upcomming name-field - if( do_resize(*e, length, 0, 0) ) { - DEBUGF("album_entry_unserialize: failed to allocate memory for name\n"); - album_entry_destruct(*e); - return ERR_MALLOC; - } - - // read it in - if( fread((*e)->name, 1, (*e)->size.name_len, fd) != (*e)->size.name_len ) { - DEBUGF("album_entry_unserialize: failed to read name\n"); - album_entry_destruct(*e); - return ERR_FILE; - } - - if( FLAG_DELETED(flag) ) { - // all there is... free some memory - if( do_resize(*e, 0, 0, 0) ) { - DEBUGF("album_entry_unserialize: couldn't free() name\n"); - return ERR_MALLOC; - } - return ERR_NONE; - } - - // maybe a key-field - if( fread(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("album_entry_unserialize: failed to read length of key\n"); - album_entry_destruct(*e); - return ERR_FILE; - } - - if( length > 0 ) { - // allocate memory - if( ((*e)->key = malloc(length)) == NULL ) { - DEBUGF("album_entry_unserialize: failed to allocate memory for key\n"); - album_entry_destruct(*e); - return ERR_MALLOC; - } - - // read it - if( fread((*e)->key, 1, length, fd) != length ) { - DEBUGF("album_entry_unserialize: failed to read key\n"); - album_entry_destruct(*e); - return ERR_FILE; - } - } - - // next the artist field - if( fread(&(*e)->artist, sizeof((*e)->artist), 1, fd) != 1 ) { - DEBUGF("album_entry_unserialize: failed to read artist\n"); - album_entry_destruct(*e); - return ERR_FILE; - } - - // Next the count of songs - if( fread(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("album_entry_unserialize: failed to read song_count\n"); - album_entry_destruct(*e); - return ERR_FILE; - } - - // allocate memory for the upcomming name-field - if( do_resize(*e, (*e)->size.name_len, length, 0) ) { - DEBUGF("album_entry_unserialize: failed to allocate memory for song[]\n"); - album_entry_destruct(*e); - return ERR_MALLOC; - } - - // read it in - if( fread((*e)->song, sizeof(*(*e)->song), (*e)->size.song_count, fd) != (*e)->size.song_count ) { - DEBUGF("album_entry_unserialize: failed to read songs\n"); - album_entry_destruct(*e); - return ERR_FILE; - } - - return ERR_NONE; -} - -int album_entry_write(FILE *fd, struct album_entry *e, struct album_size *s) { - uint32_t i, be; - char pad = 0x00; - - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - assert(fd != NULL); - - if( FLAG_DELETED(e->flag) ) { // we are deleted, do nothing - return ERR_NONE; - } - - // resize-write to size *s - // First check if we are not reducing the size... - if( s != NULL && ( s->name_len < e->size.name_len || s->song_count < e->size.song_count ) ) { - // just do it in 2 steps - if( do_resize(e, s->name_len, s->song_count, 0) ) { - DEBUGF("album_entry_write: failed to reduce size of entry, failing...\n"); - return ERR_MALLOC; - } - } - - // album name - if( fwrite(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("album_entry_write: failed to write name\n"); - return ERR_FILE; - } - // pad the rest - i = e->size.name_len; - while( s != NULL && s->name_len > i) { - if( fwrite(&pad, 1, 1, fd) == 1 ) { - i++; - continue; - } else { - DEBUGF("album_entry_write: failed to pad name\n"); - return ERR_FILE; - } - } - - // artist - be = BE32(e->artist); - if( fwrite(&be, sizeof(be), 1, fd) != 1 ) { - DEBUGF("album_entry_write: failed to write artist\n"); - return ERR_FILE; - } - - // song offsets, but in BIG ENDIAN! - // so we need to iterate over each item to convert it - for(i=0; i<e->size.song_count; i++) { - be = BE32(e->song[i]); - if( fwrite(&be, sizeof(be), 1, fd) != 1 ) { - DEBUGF("album_entry_write: failed to write song[%d]\n", i); - return ERR_FILE; - } - } - // pad the rest - be = BE32(0x00000000); - for(; s != NULL && i<s->song_count; i++) { - if( fwrite(&be, sizeof(be), 1, fd) != 1 ) { - DEBUGF("album_entry_write: failed to pad song[]\n"); - return ERR_FILE; - } - } - - return 0; -} - -inline int album_entry_compare(const struct album_entry *a, const struct album_entry *b) { - assert(a != NULL); - assert(b != NULL); - assert(a->key != NULL); - assert(b->key != NULL); - return strcasecmp(a->key, b->key); -} - -struct album_size* new_album_size() { - struct album_size *s; - s = (struct album_size*)malloc(sizeof(struct album_size)); - if( s == NULL ) { - DEBUGF("new_album_size: failed to allocate memory\n"); - return NULL; - } - s->name_len = 0; - s->song_count = 0; - - return s; -} - -inline uint32_t album_size_get_length(const struct album_size *size) { - assert(size != NULL); - return size->name_len + 4 + 4*size->song_count; -} - -inline int album_size_max(struct album_size *s, const struct album_entry *e) { - assert(s != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - s->name_len = ( s->name_len >= e->size.name_len ? s->name_len : e->size.name_len ); - s->song_count = ( s->song_count >= e->size.song_count ? s->song_count : e->size.song_count ); - return ERR_NONE; -} - -int album_size_destruct(struct album_size *s) { - assert(s != NULL); - // nothing to do... - free(s); - return ERR_NONE; -} - -int album_entry_add_song_mem(struct album_entry *e, struct album_size *s, const uint32_t song) { - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - if( do_resize(e, e->size.name_len, e->size.song_count+1, 0) ) { - DEBUGF("album_entry_add_song_mem: failed to resize song[]\n"); - return ERR_MALLOC; - } - - e->song[e->size.song_count-1] = song; - - if( s != NULL) album_size_max(s, e); // can't fail - - return ERR_NONE; -} - -static int delete_serialized(FILE *fd, struct album_entry *e) { -// the entry should be both, in memory and in file at the current location -// this function will mark the file-entry as deleted - uint32_t size; - unsigned char flag; - - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - // overwrite the beginning of the serialized data: - flag = FLAG(1, 0); // set the delete flag, clear the spare flags - - // First byte we write is the flag-byte to indicate this is a deleted - if( fwrite(&flag, 1, 1, fd) != 1 ) { - DEBUGF("album_entry_delete_serialized: failed to write flag-byte\n"); - return ERR_FILE; - } - - // Then we write the length of the COMPLETE entry - size = album_size_get_length(&e->size) + 4; // 4 = overhead for the song[] - if( fwrite(&size, sizeof(size), 1, fd) != 1 ) { - DEBUGF("album_entry_delete_serialized: failed to write len\n"); - return ERR_FILE; - } - - return ERR_NONE; -} - -int album_entry_add_song_file(FILE *fd, struct album_entry *e, struct album_size *s, const uint32_t song) { - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - DEBUGF("album_entry_add_song_file() called\n"); - - if( delete_serialized(fd, e) ) { - DEBUGF("album_entry_add_song_file: could not mark as deleted\n"); - return ERR_FILE; - } - - return ERR_NO_INPLACE_UPDATE; -} -#endif diff --git a/apps/tagdb/album.h b/apps/tagdb/album.h deleted file mode 100644 index 3f4eacd..0000000 --- a/apps/tagdb/album.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __ALBUM_H__ -#define __ALBUM_H__ - -#include "config.h" -#include <stdio.h> - -struct album_entry { - char* name; // album name - char* key; // key for sorting/searching: album___artist___directory - uint32_t artist; // pointer to artist - uint32_t *song; // song-pointers - struct album_size { - uint32_t name_len; // length of this field (must be mulitple of 4) - uint32_t song_count; // number of song pointers - } size; // keeps the size of this thing - unsigned char flag; // flags -}; - -struct album_entry* new_album_entry(const uint32_t name_len, const uint32_t song_count); -/* Creates a new album_entry with the specified sizes - * Returns a pointer to the structure on success, - * NULL when malloc() fails - */ - -int album_entry_destruct(struct album_entry *e); -/* Destructs the given album_entry and free()'s it's memory - * returns ERR_NONE on success (can never fail) - */ - -inline int album_entry_resize(struct album_entry *e, const uint32_t name_len, const uint32_t song_count); -/* Change the size of the entry - * returns ERR_NONE on succes - * ERR_MALLOC when malloc() fails - */ - -int album_entry_serialize(FILE *fd, const struct album_entry *e); -/* Serializes the entry in the file at the current position - * returns ERR_NONE on success - * ERR_FILE on fwrite() failure - */ - -int album_entry_unserialize(struct album_entry* *e, FILE *fd); -/* Unserializes an entry from file into a new structure - * The address of the structure is saved into *e - * returns ERR_NONE on success - * ERR_MALLOC on malloc() failure - * ERR_FILE on fread() failure - */ - -int album_entry_write(FILE *fd, struct album_entry *e, struct album_size *s); -/* Writes the entry to file in the final form - * returns ERR_NONE on success - * ERR_FILE on fwrite() failure - * ERR_MALLOC when e could not be resized due to malloc() problems - * If s is smaller than e, s is used!!! - */ - -inline int album_entry_compare(const struct album_entry *a, const struct album_entry *b); -/* Compares 2 entries - * When a < b it returns <0 - * a = b 0 - * a > b >0 - */ - -struct album_size* new_album_size(); -/* Creates a new size structure - * returns a pointer to the structure on success, - * NULL on malloc() failure - */ - -inline uint32_t album_size_get_length(const struct album_size *size); -/* Calculates the length of the entry when written by album_entry_write() - * returns the length on success (can never fail) - */ - -inline int album_size_max(struct album_size *s, const struct album_entry *e); -/* Updates the album_size structure to contain the maximal lengths of either - * the original entry in s, or the entry e - * returns ERR_NONE on success (can never fail) - */ - -int album_size_destruct(struct album_size *s); -/* destructs the album_size structure - * returns ERR_NONE on success (can never fail) - */ - - -int album_entry_add_song_mem(struct album_entry *e, struct album_size *s, const uint32_t song); -/* Adds the song to the array - * returns ERR_NONE on success - * ERR_MALLOC on malloc() failure - */ - -int album_entry_add_song_file(FILE *fd, struct album_entry *e, struct album_size *s, const uint32_t song); -/* Adds the song to the serialized entry in the file - * When this fails, the entry is invalidated and the function returns - * ERR_NO_INPLACE_UPDATE - * returns ERR_NONE on success - * ERR_NO_INPLACE_UPDATE (see above) - * ERR_FILE on fwrite() failure - */ - -#endif -#endif diff --git a/apps/tagdb/array_buffer.c b/apps/tagdb/array_buffer.c deleted file mode 100644 index 2b8b017..0000000 --- a/apps/tagdb/array_buffer.c +++ /dev/null @@ -1,668 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "malloc.h" // malloc() and free() - -#include "array_buffer.h" -#include "unique.h" - -static int add_mem(struct array_buffer *b, void *e); -static int add_file(struct array_buffer *b, void *e); - -static int update_entry_mem(struct array_buffer *b, const uint32_t index, uint32_t item); -static int update_entry_file(struct array_buffer *b, const uint32_t index, uint32_t item); - -static int find_entry_mem(struct array_buffer *b, const void *needle, uint32_t *index); -static int find_entry_file(struct array_buffer *b, const void *needle, uint32_t *index); - -static int sort_mem(struct array_buffer *b); -static int sort_mem_merge_blocks(uint32_t *dest, uint32_t *s1, uint32_t s1_l, uint32_t *s2, uint32_t s2_l, struct array_buffer *b); -static int sort_mem_merge(uint32_t *dest, uint32_t *src, struct array_buffer *b, uint32_t blocksize); -static int sort_file(struct array_buffer *b); - -struct array_buffer* new_array_buffer( int (*cmp)(const void *a, const void *b), - int (*serialize)(FILE *fd, const void *e), - int (*unserialize)(void **e, FILE *fd), - uint32_t (*get_length)(const void *size), - int (*write)(FILE *fd, void *e, const void *size), - int (*destruct)(void *e), - char* file_name, - void* max_size, - int (*max_size_update)(void *max_size, const void *e), - int (*max_size_destruct)(void *max_size), - int (*add_item_mem)(void *e, void *s, uint32_t item), - int (*add_item_file)(FILE *fd, void *e, void *s, uint32_t item), - int (*pre_write)(void *e, void *s) - ) { - struct array_buffer *b; - b = (struct array_buffer*)malloc(sizeof(struct array_buffer)); - if( b == NULL ) { - DEBUGF("new_array_buffer: failed to allocate memory\n"); - return NULL; - } - - b->count = 0; - b->array = NULL; - b->sort = NULL; - - b->file_name = file_name; - - b->fd = NULL; - - b->cmp = cmp; - b->serialize = serialize; - b->unserialize = unserialize; - b->get_length = get_length; - b->write = write; - b->destruct = destruct; - - b->max_size = max_size; - b->max_size_update = max_size_update; - b->max_size_destruct = max_size_destruct; - - b->add_item_mem = add_item_mem; - b->add_item_file = add_item_file; - - b->pre_write = pre_write; - - return b; -} - -int array_buffer_destruct(struct array_buffer *b, const int free_file_name) { - assert(b != NULL); - - if( b->fd == NULL ) { - if( b->destruct == NULL ) { - DEBUGF("array_buffer_destruct: no destruct() function registered\n"); - return ERR_MALLOC; - } - //we have memory to clean up - // iterate over all stored objects: - for(; b->count > 0; b->count--) { - if( b->destruct(b->array[b->count-1].mem) ) { - DEBUGF("array_buffer_destruct: failed to destruct item[%u]\n", b->count-1); - return ERR_MALLOC; - } - } - } - free(b->array); - - if( b->fd != NULL ) { - // we have a file to clean up - if( fclose(b->fd) != 0 ) { - DEBUGF("array_buffer_destruct: fclose() failed\n"); - return ERR_FILE; - } - b->fd = NULL; - - // remove that file - if( remove(b->file_name) != 0 ) { - DEBUGF("array_buffer_destruct: remove() failed\n"); - return ERR_FILE; - } - } - if( free_file_name ) { - free(b->file_name); - b->file_name = NULL; - } - - free(b->sort); - b->sort = NULL; - - // free the max_size - if( b->max_size != NULL ) { - if( b->max_size_destruct == NULL ) { - DEBUGF("array_buffer_destruct: no max_size_destruct() function registered\n"); - return 1; - } - - if( b->max_size_destruct(b->max_size) ) { - DEBUGF("array_buffer_destruct: failed to destruct max_size\n"); - return ERR_MALLOC; - } - b->max_size = NULL; - } - - free(b); - - return ERR_NONE; -} - -int array_buffer_switch_to_file(struct array_buffer *b) { - uint32_t i; - long offset; - - assert(b != NULL); - - if(b->file_name == NULL) { - DEBUGF("array_buffer_switch_to_file: no file_name, failing...\n"); - return ERR_MALLOC; - } - - if( b->fd != NULL ) { - DEBUGF("array_buffer_switch_to_file: already in file, failing...\n"); - return ERR_MALLOC; - } - - // function calls exist? - if( b->serialize == NULL || b->unserialize == NULL ) { - DEBUGF("array_buffer_switch_to_file: serialize() and/or unserialize() function(s) not registered\n"); - return ERR_INVALID; - } - - // since we got here, we are VERY short on memory - // We cannot do any memory allocation before free()ing some - // The filename is already allocated in the constructor - - // open the file - b->fd = fopen(b->file_name, "w+"); - if( b->fd == NULL ) { - DEBUGF("array_buffer_switch_to_file: failed to fopen() file\n"); - return ERR_FILE; - } - - for(i=0; i<b->count; i++) { - offset = ftell(b->fd); - if( offset == -1 ) { - DEBUGF("array_buffer_switch_to_file: ftell() failed\n"); - return ERR_FILE; - } - - if( b->serialize(b->fd, b->array[i].mem) ) { - DEBUGF("array_buffer_switch_to_file: serialize() failed on item[%u], ignoring...\n", i); - } - b->destruct(b->array[i].mem); - - b->array[i].file_offset = offset; - } - - return ERR_NONE; -} - -static int add_mem(struct array_buffer *b, void *e) { - assert(b != NULL); - assert(e != NULL); - - // just copy over the pointer - b->array[b->count].mem = e; - - return ERR_NONE; -} - -static int add_file(struct array_buffer *b, void *e) { - int rc; - - assert(b != NULL); - assert(e != NULL); - - if( fseek(b->fd, 0, SEEK_END) != 0 ) { - DEBUGF("add_file: could not seek to end of file\n"); - return ERR_FILE; - } - if(( b->array[b->count].file_offset = ftell(b->fd) ) == -1) { - DEBUGF("add_file: ftell() failed to get file_offset\n"); - return ERR_FILE; - } - - if(( rc = b->serialize(b->fd, e) )) { - DEBUGF("add_file: could not serialize entry\n"); - return rc; - } - if( b->destruct(e) ) { - DEBUGF("add_file: could not destruct entry, ignoring... (memory leak)\n"); - } - return ERR_NONE; -} - -int array_buffer_add(struct array_buffer *b, void *e, uint32_t *index) { - void* temp; - int rc; - - assert(b != NULL); - assert(e != NULL); - - // allow the object to update the max_size - // Do this first, so if it fails we can just return without cleanup to do - if( b->max_size_update != NULL ) { - if(( rc = b->max_size_update(b->max_size, e) )) { - DEBUGF("array_buffer_add: could not update max_size, failing...\n"); - return rc; - } - } - - // we need to enlarge the array[] - temp = (void*)realloc(b->array, sizeof(*b->array)*(b->count+1)); - while( temp == NULL ) { - DEBUGF("array_buffer_add: failed to enlarge index_map[]. Switching to file\n"); - if(( rc = array_buffer_switch_to_file(b) )) { - DEBUGF("array_buffer_add: failed to switch to file, failing...\n"); - return rc; - } - // now retry - temp = (void*)realloc(b->array, sizeof(*b->array)*(b->count+1)); - } - b->array = (union entry*)temp; - - if( b->fd == NULL ) { // we are in memory - rc = add_mem(b, e); - if( rc == ERR_MALLOC ) { - DEBUGF("array_buffer_add: failed to add in memory due to malloc() trouble, switching to file\n"); - if(( rc = array_buffer_switch_to_file(b) )) { - DEBUGF("array_buffer_add: failed to switch to file, failing...\n"); - return rc; - } - // fall out and catch next if - } - } // NOT else, so we can catch the fall-through - if( b->fd != NULL) { - if(( rc = add_file(b, e) )) { - DEBUGF("array_buffer_add: failed to add in file, failing...\n"); - return rc; - } - } - - // count and index-stuff - if(index != NULL) *index = b->count; - b->count++; - - return ERR_NONE; -} - -inline uint32_t array_buffer_get_next_index(struct array_buffer *b) { - assert( b != NULL ); - return b->count; -} - -static int update_entry_mem(struct array_buffer *b, const uint32_t index, const uint32_t item) { - int rc; - - assert(b != NULL); - assert(index < b->count); - - if( (rc = b->add_item_mem(b->array[index].mem, b->max_size, item)) ) { - DEBUGF("update_entry_mem: failed to update entry\n"); - return rc; - } - - return ERR_NONE; -} - -static int update_entry_file(struct array_buffer *b, const uint32_t index, uint32_t item) { -/* uint32_t i, index; - void *e; - int rc; - long prev_file_offset;*/ - - assert(b != NULL); - assert(index < b->count); - - printf("TODO: update entry in file\n"); - - return 10; // TODO -/* - rewind(b->fd); - - rc = ERR_NOTFOUND; - for(i=0; i<b->count; i++) { - prev_file_offset = ftell(b->fd); // keep this file-position - if( prev_file_offset == -1 ) { - DEBUGF("file_entry_add_file: ftell() failed\n"); - return ERR_FILE; - } - - if( (rc = b->unserialize(&e, b->fd)) ) { - DEBUGF("find_entry_add_file: unserialize failed\n"); - return rc; - } - - if( b->cmp(e, needle) == 0 ) { // found - if( fseek(b->fd, prev_file_offset, SEEK_SET) ) { - DEBUGF("file_entry_add_file: fseek() to entry[%u] failed\n", i); - return ERR_FILE; - } - - rc = b->add_item_file(b->fd, e, b->max_size, item); - if( !( rc == ERR_NONE || rc == ERR_NO_INPLACE_UPDATE )) { - DEBUGF("find_entry_add_mem: failed to add item\n"); - return rc; - } - - break; // stop looping - } - - b->destruct(e); - } - - // seek to the end - if( fseek(b->fd, 0, SEEK_END) != 0) { - DEBUGF("find_entry_add_file: fseek(SEEK_END) failed\n"); - return ERR_FILE; - } - - // We either succeded, deleted the entry or didn't find it: - if( rc == ERR_NOTFOUND ) { - return rc; // quit - } else if( rc == ERR_NONE ) { - b->destruct(e); // delete the entry and quit - return rc; - } - - // we could not update inplace - // the entry is deleted, update it and add it again - if( (rc = b->add_item_mem(e, b->max_size, item)) ) { - DEBUGF("find_entry_add_file: failed to add item in mem\n"); - return rc; - } - - if( (rc = array_buffer_add(b, e, &index) ) ) { - DEBUGF("find_entry_add_file: failed to re-add item to array"); - return rc; - } - - // the entry is now re-added, but with another index number... - // change the index_map to reflect this: - b->index_map[i] = index; - - return ERR_NONE;*/ -} - -int array_buffer_entry_update(struct array_buffer *b, const uint32_t index, uint32_t item) { - assert(b != NULL); - - if(index >= b->count) { - DEBUGF("array_buffer_entry_update: index out of bounds\n"); - return ERR_INVALID; - } - - if( b->fd == NULL ) { - return update_entry_mem(b, index, item); - } else { - return update_entry_file(b, index, item); - } -} - -static int find_entry_mem(struct array_buffer *b, const void *needle, uint32_t *index) { - uint32_t i; - - assert(b != NULL); - assert(needle != NULL); - assert(index != NULL); - - for(i=0; i<b->count; i++) { - if( b->cmp(b->array[i].mem, needle) == 0 ) { // found - *index = i; - return ERR_NONE; - } - } - return ERR_NOTFOUND; -} - -static int find_entry_file(struct array_buffer *b, const void *needle, uint32_t *index) { - uint32_t i; - void *e; - int rc; - long prev_file_offset; - - assert(b != NULL); - assert(needle != NULL); - assert(index != NULL); - - // We do this search in the order of the entries in file. - // After we found one, we look for the index of that offset - // (in memory). - // This will (PROBABELY: TODO) be faster than random-access the file - rewind(b->fd); - - for(i=0; i<b->count; i++) { - prev_file_offset = ftell(b->fd); // keep this file-position - if( prev_file_offset == -1 ) { - DEBUGF("file_entry_add_file: ftell() failed\n"); - return ERR_FILE; - } - - if( (rc = b->unserialize(&e, b->fd)) ) { - DEBUGF("find_entry_add_file: unserialize failed\n"); - return rc; - } - - if( b->cmp(e, needle) == 0 ) { // found - if( fseek(b->fd, prev_file_offset, SEEK_SET) ) { - DEBUGF("file_entry_add_file: fseek() to entry[%u] failed\n", i); - return ERR_FILE; - } - - b->destruct(e); - break; // out of the for() loop - } - - b->destruct(e); - } - - if( i == b->count ) { - // we didn't find anything - return ERR_NOTFOUND; - } - - // we found an entry, look for the index number of that offset: - for(i=0; i<b->count; i++) { - if(prev_file_offset == b->array[i].file_offset) { - // found - *index = i; - return ERR_NONE; - } - } - - // we should never get here - DEBUGF("find_entry_file: found entry in file, but doens't match an index\n"); - return ERR_INVALID; -} - -int array_buffer_find_entry(struct array_buffer *b, const void *needle, uint32_t *index) { - assert(b != NULL); - assert(needle != NULL); - assert(index != NULL); // TODO: if it is null, do the search but trash the index - - if( b->fd == NULL ) { - return find_entry_mem(b, needle, index); - } else { - return find_entry_file(b, needle, index); - } -} - -/* -static int sort_mem_merge_blocks(uint32_t *dest, const uint32_t *s1, const uint32_t s1_l, const uint32_t *s2, const uint32_t s2_l, struct array_buffer *b) { -// merges the 2 blocks at s1 (with s1_l items) and s2 (with s2_l items) -// together in dest - uint32_t *s1_max, s2_max; - -#define CMP(a, b) b->cmp( b->entry[a].mem, b->entry[b].mem ) - - s1_max = s1 + s1_l; - s2_max = s2 + s2_l; - while( s1 < s1_max || s2 < s2_max ) { - while( s1 < s1_max && ( s2 == s2_max || CMP(s1, s2) <= 0 ) ) // s1 is smaller than s2 (or s2 is used up) - *(dest++) = s1++; // copy and move to next - while( s2 < s2_max && ( s1 == s1_max || CMP(s1, s2) > 0 ) ) // s2 smaller - *(dest++) = s2++; - } - - return ERR_NONE; -} - -#define MIN(a, b) ( (a) <= (b) ? (a) : (b) ) -static int sort_mem_merge(uint32_t *dest, uint32_t *src, struct array_buffer *b, uint32_t blocksize) { -// does 1 merge from src[] into dest[] -// asumes there are sorted blocks in src[] of size blocksize - assert( dest != NULL); - assert( src != NULL ); - - assert( b->count > blocksize ); - - // TODO -} -*/ - -static int sort_mem(struct array_buffer *b) { - uint32_t *tmp, blocksize; - - assert(b != NULL); - - tmp = (uint32_t*)malloc(sizeof(uint32_t)*b->count); - if( tmp == NULL ) { - DEBUGF("sort_mem: could not malloc() for second sort[] array\n"); - return ERR_MALLOC; - } - - for( blocksize = 1; blocksize < b->count; blocksize++) { - b->sort[blocksize] = blocksize; // 1-1 map TODO - } - - free(tmp); - - return ERR_NONE; -} - -static int sort_file(struct array_buffer *b) { - printf("TODO: file-sorting\n"); // TODO - return ERR_INVALID; -} - -int array_buffer_sort(struct array_buffer *b) { - int rc; - - assert(b != NULL); - - b->sort = (uint32_t*)malloc(sizeof(uint32_t)*b->count); - if( b->sort == NULL ) { - DEBUGF("array_buffer_sort: could not malloc() sort[] array\n"); - return ERR_MALLOC; - } - - if( b->fd == NULL ) { // in memory - rc = sort_mem(b); - if( rc == ERR_MALLOC ) { - if(( rc = array_buffer_switch_to_file(b) )) { - DEBUGF("array_buffer_sort: could not switch to file mode\n"); - return rc; - } - return sort_file(b); - } else if( rc ) { - DEBUGF("array_buffer_sort: could not sort array\n"); - return rc; - } - return ERR_NONE; - } else { - return sort_file(b); - } -} - -uint32_t array_buffer_get_offset(struct array_buffer *b, const uint32_t index) { - uint32_t offset; - - assert(b != NULL); - - if( index >= b->count ) { - DEBUGF("array_buffer_get_offset: index out of bounds\n"); - return (uint32_t)0xffffffff; - } - - // what is the (max) length of 1 item - if( b->get_length == NULL ) { - DEBUGF("array_buffer_get_offset: get_length() function not registered\n"); - return (uint32_t)0xffffffff; - } - offset = b->get_length(b->max_size); - - // multiply that by the number of items before me - if( b->sort == NULL ) { // easy, we are unsorted - offset *= index; - } else { - uint32_t i; - for(i=0; i<b->count; i++) { - if( b->sort[i] == index ) - break; - } - if( i == b->count ) { - DEBUGF("array_buffer_get_offset: index does not appeat in sorted list\n"); - return ERR_INVALID; - } - offset *= i; // that many items are before me - } - return offset; -} - -uint32_t array_buffer_get_length(struct array_buffer *b) { - uint32_t length; - - assert(b != NULL); - - // what is the (max) length of 1 item - if( b->get_length == NULL ) { - DEBUGF("array_buffer_get_offset: get_length() function not registered\n"); - return (uint32_t)0xffffffff; - } - length = b->get_length(b->max_size); - - // multiply that by the number of items - length *= b->count; - return length; -} - -int array_buffer_write(FILE *fd, struct array_buffer *b) { - uint32_t i; - int rc; - - assert(b != NULL); - assert(fd != NULL); - - // check if the functions exist - if( b->write == NULL ) { - DEBUGF("array_buffer_write: write() function not registered\n"); - return ERR_INVALID; - } - // if the array is in file - // serialize and unserialize will exist, since they're checked - // in the array_buffer_switch_to_file() - - if( b->fd != NULL ) { - rewind(b->fd); // seek to the beginning - } - - for(i=0; i<b->count; i++) { // for each element - void* item; - uint32_t j; - - // go through the sort-array and see which item should go next - if(b->sort != NULL) { - j = b->sort[i]; - } else j = i; - - // get the item in memory - if( b->fd == NULL ) { // it already is im memory, fetch the pointer - item = b->array[j].mem; - } else { - // since it's sorted, we shouldn't have to seek - if( (rc = b->unserialize(&item, b->fd)) ) { - DEBUGF("array_buffer_write: could not unserialize item[%u], failing...\n", i); - return rc; - } - } - - if(b->pre_write != NULL && ( rc = b->pre_write(item, b->max_size) )) { - DEBUGF("array_buffer_write: pre_write function failed, failing...\n"); - return rc; - } - - // write item to file - if(( rc = b->write(fd, item, b->max_size) )) { - DEBUGF("array_buffer_write: could not write item[%u], failing...\n", i); - return rc; - } - - // put it back where it came from - if( b->fd != NULL ) { - b->destruct(item); - } - } - - return ERR_NONE; -} -#endif diff --git a/apps/tagdb/array_buffer.h b/apps/tagdb/array_buffer.h deleted file mode 100644 index d098c7a..0000000 --- a/apps/tagdb/array_buffer.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __ARRAY_BUFFER_H__ -#define __ARRAY_BUFFER_H__ - -#include "config.h" -#include <stdio.h> -#include <stdint.h> - -struct array_buffer { - uint32_t count; // how much items doe we have? - - union entry { - void* mem; - long file_offset; - } *array; // where is the data? - // This array will always point to the same data - // after sorting the position of the data may be canged - // but this array will also be canged accordingly - - uint32_t *sort; // In what order should we put the entries on disk? - - char* file_name; // filename - FILE *fd; // file where entries are being kept. (NULL if in mem) - - int (*cmp)(const void *a, const void *b); // compare a to b, should return: - // a < b ==> <0 - // a = b ==> 0 - // a > b ==> >0 - - int (*serialize)(FILE *fd, const void *e); // serialize e into fd - int (*unserialize)(void **e, FILE *fd); // unserialize the entry in fd - - uint32_t (*get_length)(const void *size); // get's the length - int (*write)(FILE *fd, void *e, const void *size); // write e to file - - int (*destruct)(void *e); // destruct object - - void *max_size; // keep the current maximal size - int (*max_size_update)(void *max_size, const void *e); // update the max_size - int (*max_size_destruct)(void *max_size); // destruct the size-object - - int (*add_item_mem)(void *e, void *s, uint32_t item); - int (*add_item_file)(FILE *fd, void *e, void *s, uint32_t item); - - int (*pre_write)(void *e, void *s); // do whatever you want, just before the entry is wrtiiten -}; - -struct array_buffer* new_array_buffer( int (*cmp)(const void *a, const void *b), - int (*serialize)(FILE *fd, const void *e), - int (*unserialize)(void **e, FILE *fd), - uint32_t (*get_length)(const void *size), - int (*write)(FILE *fd, void *e, const void *size), - int (*destruct)(void *e), - char* file_name, - void* max_size, - int (*max_size_update)(void *max_size, const void *e), - int (*max_size_destruct)(void *max_size), - int (*add_item_mem)(void *e, void *s, uint32_t item), - int (*add_item_file)(FILE *fd, void *e, void *s, uint32_t item), - int (*pre_write)(void *e, void *s) - ); -/* This makes a new array_buffer - * - cmp() is the compare function used to sort: after sort cmp(item[i], item[i+1])<=0 - * - serialize() should put the entry into the file at the current location, return 0 on success - * - unserialize() should read an entry from file and return the entry in memory. - * return 0 on success, 1 on malloc() failures, 2 on fread() errors, - * anything else on other errors - * - get_length() calculates the length of the entry as it will be written by write() - * - write() should write the entry to file in it's final format - * - destruct() should free all memory assigned to e (including e itself) - * - * - file_name should contain a filename that can be used as extra storage if needed - * if malloc()'s fail, the array is automaticaly converted to file-mode - * and array_buffer retries the operation. - * by not setting file_name=NULL malloc() failures will result in call - * failures - * - * - max_size may be an object to record the maximal size \ - * - max_size_update() will be called on each add() to update the max_size-structure | may be NULL - * - max_size_destroy() should destroy the given max_size object / - * - * - add_item_mem() add item to the entry when it is in memory (may be NULL) - * - add_item_file() add item to the serialized entry at the current file position. - * the entry itself is also given in e for convenience. - * If the add cannot be done in-place the function should - * - invalidate the serialized entry - * - return ERR_NO_INPLACE_UPDATE - * The add will be done in memory and re-added to the end of the - * array (mey be NULL) - * both functions must update the s-structure to reflect the maximal entry - * - * - pre_write() is called right before the entry is written to disk in the write() call (may be NULL) - * - * It returns that buffer on succes, NULL otherwise - * NULL indicates a memory-allocation failure - */ - -int array_buffer_destruct(struct array_buffer *b, const int free_file_name); -/* Destructs the buffer: - * - destructs all containing elements using the supplied destruct() function - * - free()'s all allocations - * - optionaly free()'s the file_name - * - free()'s b itself - */ - -int array_buffer_switch_to_file(struct array_buffer *b); -/* Asks the buffer to switch to file mode - * returns 0 on success, 1 on failure - */ - -inline uint32_t array_buffer_get_next_index(struct array_buffer *b); -/* Returns the index that will be given to the next added entry - */ - -int array_buffer_add(struct array_buffer *b, void *e, uint32_t *index); -/* Adds entry e to the buffer. - * If index!=NULL *index will contain a unique number for the entry - * - * Returns 0 on succes, 1 otherwise - * Once an entry is added, the caller should not use the pointer (e) anymore, - * since array_buffer may swap the entry out to file - */ - -int array_buffer_entry_update(struct array_buffer *b, const uint32_t index, uint32_t item); -/* Updates entry index with item, either in memory or in file, depending on the current - * state of the array - * Returns ERR_NONE on success - * ERR_MALLOC on malloc() failure - * ERR_FILE on fread(), fwrite(), fseek() problems - */ - -int array_buffer_find_entry(struct array_buffer *b, const void *needle, uint32_t *index); -/* This looks for an entry that is equal to needle (i.e. that cmp(e, needle) returns 0) - * Returns ERR_NONE on success (the entry is found) - * ERR_NOTFOUNF when needle was not found, - * ERR_MALLOC on malloc() failure - * ERR_FILE on fread(), fwrite() of other file() failures - */ - -int array_buffer_sort(struct array_buffer *b); -/* - */ - -uint32_t array_buffer_get_offset(struct array_buffer *b, const uint32_t index); -/* Returns the offset of item[index] when it would be written by the - * array_buffer_write() call. - * Useful to get offsets after sorting! - */ - -uint32_t array_buffer_get_length(struct array_buffer *b); -/* Returns the total number of bytes array_buffer_write() - * would write to the file - */ - -int array_buffer_write(FILE *fd, struct array_buffer *b); -/* Iterate over each element and write it to file - * returns 0 on success, 1 on failure - */ - -#endif -#endif diff --git a/apps/tagdb/artist.c b/apps/tagdb/artist.c deleted file mode 100644 index 36ce560..0000000 --- a/apps/tagdb/artist.c +++ /dev/null @@ -1,372 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "malloc.h" // realloc() and free() -#include <string.h> // strncasecmp() - -#include "artist.h" - -// how is our flag organized? -#define FLAG(deleted, spare) ( 0xC0 | (deleted?0x10:0x00) | (spare & 0x0F) ) -#define FLAG_VALID(flag) ((flag & 0xE0) == 0xC0) -#define FLAG_DELETED(flag) (flag & 0x10) -#define FLAG_SPARE(flag) (flag & 0x0F) - -static int do_resize(struct artist_entry *e, const uint32_t name_len, const uint32_t album_count, const int zero_fill); - -struct artist_entry* new_artist_entry(const uint32_t name_len, const uint32_t album_count) { - // start by allocating memory - struct artist_entry *e = (struct artist_entry*)malloc(sizeof(struct artist_entry)); - if( e == NULL ) { - DEBUGF("new_artist_entry: could not allocate memory\n"); - return NULL; - } - - // We begin empty - e->name = NULL; - e->size.name_len = 0; - e->album = NULL; - e->size.album_count = 0; - e->flag = FLAG(0, 0); - - // and resize to the requested size - if( do_resize(e, name_len, album_count, 1) ) { - free(e); - return NULL; - } - return e; -} - -int artist_entry_destruct(struct artist_entry *e) { - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - free(e->name); - free(e->album); - - free(e); - - return ERR_NONE; -} - -static int do_resize(struct artist_entry *e, const uint32_t name_len, const uint32_t album_count, const int zero_fill) { - void* temp; - - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - // begin with name - if( name_len != e->size.name_len ) { - temp = realloc(e->name, name_len); - if(temp == NULL && name_len > 0) { // if realloc(,0) don't complain about NULL-pointer - DEBUGF("artist_entry_resize: out of memory to resize name\n"); - return ERR_MALLOC; - } - e->name = (char*)temp; - - // if asked, fill it with zero's - if( zero_fill ) { - uint32_t i; - for(i=e->size.name_len; i<name_len; i++) - e->name[i] = (char)0x00; - } - - e->size.name_len = name_len; - } - - // now the album - if( album_count != e->size.album_count ) { - temp = realloc(e->album, album_count * sizeof(*e->album)); - if(temp == NULL && album_count > 0) { // if realloc(,0) don't complain about NULL-pointer - DEBUGF("artist_entry_resize: out of memory to resize album[]\n"); - return ERR_MALLOC; - } - e->album = (uint32_t*)temp; - - // if asked, fill it with zero's - if( zero_fill ) { - uint32_t i; - for(i=e->size.album_count; i<album_count; i++) - e->album[i] = (uint32_t)0x00000000; - } - - e->size.album_count = album_count; - } - - return ERR_NONE; -} - -int artist_entry_resize(struct artist_entry *e, const uint32_t name_len, const uint32_t album_count) { - return do_resize(e, name_len, album_count, 1); -} - -int artist_entry_serialize(FILE *fd, const struct artist_entry *e) { - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - if( FLAG_DELETED(e->flag) ) { // we are deleted, do nothing - return ERR_NONE; - } - - // First byte we write is a flag-byte to indicate this is a valid record - if( fwrite(&e->flag, 1, 1, fd) != 1 ) { - DEBUGF("artist_entry_serialize: failed to write flag-byte\n"); - return ERR_FILE; - } - - // First we write the length of the name field - if( fwrite(&e->size.name_len, sizeof(e->size.name_len), 1, fd) != 1 ) { - DEBUGF("artist_entry_serialize: failed to write name_len\n"); - return ERR_FILE; - } - - // now the name field itself - if( fwrite(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("artist_entry_serialize: failed to write name\n"); - return ERR_FILE; - } - - // count of albums - if( fwrite(&e->size.album_count, sizeof(e->size.album_count), 1, fd) != 1 ) { - DEBUGF("artist_entry_serialize: failed to write album_count\n"); - return ERR_FILE; - } - - // album[] itself - if( fwrite(e->album, sizeof(*e->album), e->size.album_count, fd) != e->size.album_count ) { - DEBUGF("artist_entry_serialize: failed to write albums\n"); - return ERR_FILE; - } - - return ERR_NONE; -} - -int artist_entry_unserialize(struct artist_entry **e, FILE *fd) { - uint32_t length; - unsigned char flag; - - assert(e != NULL); - assert(fd != NULL); - - // First byte we read is flag-byte - if( fread(&flag, 1, 1, fd) != 1 ) { - DEBUGF("artist_entry_unserialize: failed to read flag-byte\n"); - return ERR_FILE; - } - - // See what we have: - if( ! FLAG_VALID(flag) ) { - DEBUGF("artist_entry_unserialize: flag-byte not found\n"); - return ERR_INVALID; - } - - // Allocate memory - *e = new_artist_entry(0, 0); - if( *e == NULL ) { - DEBUGF("artist_entry_unserialize: could not create new artist_entry\n"); - return ERR_MALLOC; - } - - (*e)->flag = flag; - - // First we read the length of the name field - if( fread(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("artist_entry_unserialize: failed to read name_len\n"); - artist_entry_destruct(*e); - return ERR_FILE; - } - - // allocate memory for the upcomming name-field - if( do_resize((*e), length, 0, 0) ) { - DEBUGF("artist_entry_unserialize: failed to allocate memory for name\n"); - artist_entry_destruct(*e); - return ERR_MALLOC; - } - - // read it in - if( fread((*e)->name, 1, (*e)->size.name_len, fd) != (*e)->size.name_len ) { - DEBUGF("artist_entry_unserialize: failed to read name\n"); - artist_entry_destruct(*e); - return ERR_FILE; - } - - if( FLAG_DELETED(flag) ) { - // all there is... free some memory - if( do_resize(*e, 0, 0, 0) ) { - DEBUGF("artist_entry_unserialize: couldn't free() name\n"); - return ERR_MALLOC; - } - return ERR_NONE; - } - - // Next the count of albums - if( fread(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("artist_entry_unserialize: failed to read album_count\n"); - artist_entry_destruct(*e); - return ERR_FILE; - } - - // allocate memory for the upcomming name-field - if( do_resize(*e, (*e)->size.name_len, length, 0) ) { - DEBUGF("artist_entry_unserialize: failed to allocate memory for album[]\n"); - artist_entry_destruct(*e); - return ERR_MALLOC; - } - - // read it in - if( fread((*e)->album, sizeof(*(*e)->album), (*e)->size.album_count, fd) != (*e)->size.album_count ) { - DEBUGF("artist_entry_unserialize: failed to read albums\n"); - artist_entry_destruct(*e); - return ERR_FILE; - } - - return ERR_NONE; -} - -int artist_entry_write(FILE *fd, const struct artist_entry *e, const struct artist_size *s) { - uint32_t i, be; - char pad = 0x00; - - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - if( FLAG_DELETED(e->flag) ) { // we are deleted, do nothing - return ERR_NONE; - } - - // artist name - if( fwrite(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("artist_entry_write: failed to write name\n"); - return ERR_FILE; - } - // padd the rest - i = e->size.name_len; - while( s != NULL && s->name_len > i) { - if( fwrite(&pad, 1, 1, fd) == 1 ) { - i++; - continue; - } else { - DEBUGF("artist_entry_write: failed to padd name\n"); - return ERR_FILE; - } - } - - // album offsets, but in BIG ENDIAN! - // so we need to iterate over each item to convert it - for(i=0; i<e->size.album_count; i++) { - be = BE32(e->album[i]); - if( fwrite(&be, sizeof(be), 1, fd) != 1 ) { - DEBUGF("artist_entry_write: failed to write album[%d]\n", i); - return ERR_FILE; - } - } - // padd the rest - be = BE32(0x00000000); - for(; s != NULL && i<s->album_count; i++) { - if( fwrite(&be, sizeof(be), 1, fd) != 1 ) { - DEBUGF("artist_entry_write: failed to padd album[]\n"); - return ERR_FILE; - } - } - - return ERR_NONE; -} - -inline int artist_entry_compare(const struct artist_entry *a, const struct artist_entry *b) { - assert(a != NULL); - assert(b != NULL); - if( a->name == NULL || b->name == NULL ) - return 1; // never match on no-names - return strcasecmp(a->name, b->name); -} - -struct artist_size* new_artist_size() { - struct artist_size *s; - s = (struct artist_size*)malloc(sizeof(struct artist_size)); - if( s == NULL ) { - DEBUGF("new_artist_size: failed to allocate memory\n"); - return NULL; - } - s->name_len = 0; - s->album_count = 0; - - return s; -} - -inline uint32_t artist_size_get_length(const struct artist_size *size) { - assert(size != NULL); - return size->name_len + 4*size->album_count; -} - -inline int artist_size_max(struct artist_size *s, const struct artist_entry *e) { - s->name_len = ( s->name_len >= e->size.name_len ? s->name_len : e->size.name_len ); - s->album_count = ( s->album_count >= e->size.album_count ? s->album_count : e->size.album_count ); - return ERR_NONE; -} - -int artist_size_destruct(struct artist_size *s) { - assert(s != NULL); - // nothing to do... - free(s); - return ERR_NONE; -} - -int artist_entry_add_album_mem(struct artist_entry *e, struct artist_size *s, const uint32_t album) { - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - if( do_resize(e, e->size.name_len, e->size.album_count+1, 0) ) { - DEBUGF("artist_entry_add_song_mem: failed to resize album[]\n"); - return ERR_MALLOC; - } - - e->album[e->size.album_count-1] = album; - - if(s != NULL) artist_size_max(s, e); // can't fail - - return ERR_NONE; -} - -static int delete_serialized(FILE *fd, struct artist_entry *e) { -// the entry should be both, in memory and in file at the current location -// this function will mark the file-entry as deleted - uint32_t size; - unsigned char flag; - // overwrite the beginning of the serialized data: - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - flag = FLAG(1, 0); // mark as deleted - - // First byte we write is the flag-byte to indicate this is a deleted - if( fwrite(&flag, 1, 1, fd) != 1 ) { - DEBUGF("artist_entry_delete_serialized: failed to write flag-byte\n"); - return ERR_FILE; - } - - // Then we write the length of the COMPLETE entry - size = artist_size_get_length(&e->size) + 4; // 4 = overhead for the album[] - if( fwrite(&size, sizeof(size), 1, fd) != 1 ) { - DEBUGF("artist_entry_delete_serialized: failed to write len\n"); - return ERR_FILE; - } - - return ERR_NONE; -} - -int artist_entry_add_album_file(FILE *fd, struct artist_entry *e, struct artist_size *s, const uint32_t album) { - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - DEBUGF("artist_entry_add_song_file() called\n"); - - if( delete_serialized(fd, e) ) { - DEBUGF("artist_entry_add_album_file: could not mark as deleted\n"); - return ERR_FILE; - } - - return ERR_NO_INPLACE_UPDATE; -} -#endif diff --git a/apps/tagdb/artist.h b/apps/tagdb/artist.h deleted file mode 100644 index 102e287..0000000 --- a/apps/tagdb/artist.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __ARTIST_H__ -#define __ARTIST_H__ - -#include "config.h" -#include <stdio.h> -#include <stdint.h> - -struct artist_entry { - char* name; // artist name - uint32_t *album; // album-pointers - struct artist_size { - uint32_t name_len; // length of this field (must be mulitple of 4) - uint32_t album_count; // number of album pointers - } size; - unsigned char flag; // flags -}; - -struct artist_entry* new_artist_entry(const uint32_t name_len, const uint32_t album_count); -/* Creates a new artist_entry with the specified sizes - * Returns a pointer to the structure on success, - * NULL on failure -*/ - -int artist_entry_destruct(struct artist_entry *e); -/* Destructs the given artist_entry and free()'s it's memory - * returns ERR_NONE on success (can't fail) - */ - -int artist_entry_resize(struct artist_entry *e, const uint32_t name_len, const uint32_t album_count); -/* Change the size of the entry - * returns ERR_NONE on succes - * ERR_MALLOC on malloc() failure - */ - -int artist_entry_serialize(FILE *fd, const struct artist_entry *e); -/* Serializes the entry in the file at the current position - * returns ERR_NONE on success - * ERR_FILE on fwrite() failure - */ - -int artist_entry_unserialize(struct artist_entry* *e, FILE *fd); -/* Unserializes an entry from file into a new structure - * The address of the structure is saved into *e - * returns ERR_NONE on success - * ERR_MALLOC on malloc() failure - * ERR_FILE on fread() failure - */ - -int artist_entry_write(FILE *fd, const struct artist_entry *e, const struct artist_size *s); -/* Writes the entry to file in the final form - * returns ERR_NONE on success - * ERR_FILE on fwrite() failure - */ - -inline int artist_entry_compare(const struct artist_entry *a, const struct artist_entry *b); -/* Compares 2 entries - * When a < b it returns <0 - * a = b 0 - * a > b >0 - */ - -struct artist_size* new_artist_size(); -/* Creates a new size structure - * returns a pointer to the structure on success, - * NULL on failure - */ - -inline uint32_t artist_size_get_length(const struct artist_size *size); -/* Calculates the length of the entry when written by artist_entry_write() - * returns the length on success (can't fail) - */ - -inline int artist_size_max(struct artist_size *s, const struct artist_entry *e); -/* Updates the artist_size structure to contain the maximal lengths of either - * the original entry in s, or the entry e - * returns ERR_NONE on success (can't fail) - */ - -int artist_size_destruct(struct artist_size *s); -/* destructs the artist_size structure - * returns ERR_NONE on success (can't fail) - */ - - -int artist_entry_add_album_mem(struct artist_entry *e, struct artist_size *s, const uint32_t album); -/* Adds the album to the array - * returns ERR_NONE on success - * ERR_MALLOC on malloc() failure - */ - -int artist_entry_add_album_file(FILE *fd, struct artist_entry *e, struct artist_size *s, const uint32_t album); -/* Adds the album to the serialized entry in the file - * When this fails, the entry is invalidated and the function returns - * ERR_NO_INPLACE_UPDATE - * returns ERR_NONE on success - * ERR_NO_INPLACE_UPDATE (see above) - * ERR_FILE on fread()/fwrite() error - */ - -#endif -#endif diff --git a/apps/tagdb/config.h b/apps/tagdb/config.h deleted file mode 100644 index 5e5e870..0000000 --- a/apps/tagdb/config.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __CONFIG_H // Include me only once -#define __CONFIG_H - -// DEBUGF will print in debug mode: -#ifdef DEBUG -#define DEBUGF(...) fprintf (stderr, __VA_ARGS__) -#define DEBUGT(...) fprintf (stdout, __VA_ARGS__) -#else //DEBUG -#define DEBUGF(...) -#endif //DEBUG - - -#define OS_LINUX // architecture: LINUX, ROCKBOX, WINDOWS -#define ROCKBOX_LITTLE_ENDIAN // we are intel... little-endian - - -#ifdef ROCKBOX_LITTLE_ENDIAN -#define BE32(_x_) ((( (_x_) & 0xff000000) >> 24) | \ - (( (_x_) & 0x00ff0000) >> 8) | \ - (( (_x_) & 0x0000ff00) << 8) | \ - (( (_x_) & 0x000000ff) << 24)) -#define BE16(_x_) ( (( (_x_) & 0xff00) >> 8) | (( (_x_) & 0x00ff) << 8)) -#else -#define BE32(_x_) _x_ -#define BE16(_x_) _x_ -#endif - -#include <stdint.h> - -#define ERR_NONE 0 // no error -#define ERR_NOTFOUND -1 // entry not found -#define ERR_MALLOC 1 // memory allocation failed -#define ERR_FILE 2 // file operation failed -#define ERR_INVALID 3 // something is invalid -#define ERR_NO_INPLACE_UPDATE 4 // can't update in this place - -#include <assert.h> - -#endif -#endif diff --git a/apps/tagdb/db.c b/apps/tagdb/db.c deleted file mode 100644 index 4dfeb47..0000000 --- a/apps/tagdb/db.c +++ /dev/null @@ -1,605 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include <string.h> // strlen() strcpy() strcat() - -#include "malloc.h" -#include "db.h" -#include "header.h" - -#include "artist.h" -#include "album.h" -#include "song.h" -#include "file.h" - -#include "tag_dummy.h" - -#define CEIL32BIT(x) ( ((x) + 3) & 0xfffffffc ) -#define CEIL32BIT_LEN(x) CEIL32BIT(strlen(x) + 1) // +1 because we want to store the \0 at least once - -#define CATCH_MALLOC(condition) \ - while( condition ) { \ - int rc_catch_malloc = free_ram(); \ - if (rc_catch_malloc != ERR_NONE) { \ - DEBUGF("catch_malloc: " #condition ": could not free memory, failing...\n"); \ - return rc_catch_malloc; \ - } \ - } - -#define CATCH_MALLOC_ERR(expr) CATCH_MALLOC( (expr) == ERR_MALLOC ) -#define CATCH_MALLOC_NULL(expr) CATCH_MALLOC( (expr) == NULL ) -// Loop the expression as long as it returns ERR_MALLOC (for CATCH_MALLOC_ERR) -// or NULL (for CATCH_MALLOC_NULL) -// on each failure, call free_ram() to free some ram. if free_ram() fails, return -// the fail-code -#define CATCH_ERR(expr) \ - CATCH_MALLOC_ERR(rc = expr); \ - if( rc != ERR_NONE ) { \ - DEBUGF("catch_err: " #expr ": failed\n"); \ - return rc; \ - } -// Catches all errors: if it's a MALLOC one, try to free memory, -// if it's another one, return the code - -static int fill_artist_offsets(struct artist_entry *e, struct artist_size *max_s); -static int fill_album_offsets(struct album_entry *e, struct album_size *max_s); -static int fill_song_offsets(struct song_entry *e, struct song_size *max_s); -static int fill_file_offsets(struct file_entry *e, struct file_size *max_s); - -static int do_add(const struct tag_info *t); - -static int tag_empty_get(struct tag_info *t); -/* Adds "<no artist tag>" and "<no album tag>" if they're empty - */ - -static int free_ram(); -static char in_file = 0; - -static int do_write(FILE *fd); - -static struct array_buffer *artists; -static struct array_buffer *albums; -static struct array_buffer *songs; -static struct array_buffer *files; -static uint32_t artist_start=0, album_start=0, song_start=0, file_start=0; -static uint32_t artist_entry_len, album_entry_len, song_entry_len, file_entry_len; -static char *artists_file, *albums_file, *songs_file, *files_file; - -int db_construct() { - void *max_size; - - // struct array_buffer* new_array_buffer( int (*cmp)(const void *a, const void *b), - // int (*serialize)(FILE *fd, const void *e), - // int (*unserialize)(void **e, FILE *fd), - // uint32_t (*get_length)(const void *size), - // int (*write)(FILE *fd, void *e, const void *size), - // int (*destruct)(void *e), - // char* file_name, - // void* max_size, - // int (*max_size_update)(void *max_size, const void *e), - // int (*max_size_destruct)(void *max_size), - // int (*add_item_mem)(void *e, void *s, uint32_t item), - // int (*add_item_file)(FILE *fd, void *e, void *s, uint32_t item) - // ); - - if(!( max_size = (void*)new_artist_size() )) { - DEBUGF("new_db: new_artist_size() failed\n"); - return ERR_MALLOC; - } - if(!( artists = new_array_buffer( (int (*)(const void *a, const void *b)) artist_entry_compare, - (int (*)(FILE *fd, const void *e)) artist_entry_serialize, - (int (*)(void **e, FILE *fd)) artist_entry_unserialize, - (uint32_t (*)(const void *size)) artist_size_get_length, - (int (*)(FILE *fd, void *e, const void *size)) artist_entry_write, - (int (*)(void *e)) artist_entry_destruct, - NULL, // don't allow to switch to file - max_size, - (int (*)(void *max_size, const void *e)) artist_size_max, - (int (*)(void *max_size)) artist_size_destruct, - (int (*)(void *e, void *s, uint32_t item)) artist_entry_add_album_mem, - (int (*)(FILE *fd, void *e, void *s, uint32_t item)) artist_entry_add_album_file, - (int (*)(void *e, void *s)) fill_artist_offsets - ) )) { - DEBUGF("new_db: new_array_buffer() failed on artists[]\n"); - return ERR_MALLOC; - } - if(!( artists_file = malloc(12) )) { // artists.tmp - DEBUGF("new_db: could not malloc() for artists[] file_name\n"); - return ERR_MALLOC; - } - strcpy(artists_file, "artists.tmp"); - - if(!( max_size = (void*)new_album_size() )) { - DEBUGF("new_db: new_album_size() failed\n"); - return ERR_MALLOC; - } - if(!( albums = new_array_buffer( (int (*)(const void *a, const void *b)) album_entry_compare, - (int (*)(FILE *fd, const void *e)) album_entry_serialize, - (int (*)(void **e, FILE *fd)) album_entry_unserialize, - (uint32_t (*)(const void *size)) album_size_get_length, - (int (*)(FILE *fd, void *e, const void *size)) album_entry_write, - (int (*)(void *e)) album_entry_destruct, - NULL, // don't allow to switch to file - max_size, - (int (*)(void *max_size, const void *e)) album_size_max, - (int (*)(void *max_size)) album_size_destruct, - (int (*)(void *e, void *s, uint32_t item)) album_entry_add_song_mem, - (int (*)(FILE *fd, void *e, void *s, uint32_t item)) album_entry_add_song_file, - (int (*)(void *e, void *s)) fill_album_offsets - ) )) { - DEBUGF("new_db: new_array_buffer() failed on albums[]\n"); - return ERR_MALLOC; - } - if(!( albums_file = malloc(11) )) { // albums.tmp - DEBUGF("new_db: could not malloc() for albums[] file_name\n"); - return ERR_MALLOC; - } - strcpy(albums_file, "albums.tmp"); - - if(!( max_size = (void*)new_song_size() )) { - DEBUGF("new_db: new_song_size() failed\n"); - return ERR_MALLOC; - } - if(!( songs = new_array_buffer( (int (*)(const void *a, const void *b)) song_entry_compare, - (int (*)(FILE *fd, const void *e)) song_entry_serialize, - (int (*)(void **e, FILE *fd)) song_entry_unserialize, - (uint32_t (*)(const void *size)) song_size_get_length, - (int (*)(FILE *fd, void *e, const void *size)) song_entry_write, - (int (*)(void *e)) song_entry_destruct, - NULL, // may switch to file, but we'd like to know about it - max_size, - (int (*)(void *max_size, const void *e)) song_size_max, - (int (*)(void *max_size)) song_size_destruct, - NULL, - NULL, - (int (*)(void *e, void *s)) fill_song_offsets - ) )) { - DEBUGF("new_db: new_array_buffer() failed on songs[]\n"); - return ERR_MALLOC; - } - if(!( songs_file = malloc(10) )) { // songs.tmp - DEBUGF("new_db: could not malloc() for songs[] file_name\n"); - return ERR_MALLOC; - } - strcpy(songs_file, "songs.tmp"); - - if(!( max_size = (void*)new_file_size() )) { - DEBUGF("new_db: new_file_size() failed\n"); - return ERR_MALLOC; - } - if(!( files = new_array_buffer( (int (*)(const void *a, const void *b)) file_entry_compare, - (int (*)(FILE *fd, const void *e)) file_entry_serialize, - (int (*)(void **e, FILE *fd)) file_entry_unserialize, - (uint32_t (*)(const void *size)) file_size_get_length, - (int (*)(FILE *fd, void *e, const void *size)) file_entry_write, - (int (*)(void *e)) file_entry_destruct, - NULL, - max_size, - (int (*)(void *max_size, const void *e)) file_size_max, - (int (*)(void *max_size)) file_size_destruct, - NULL, - NULL, - (int (*)(void *e, void *s)) fill_file_offsets - ) )) { - DEBUGF("new_db: new_array_buffer() failed on files[]\n"); - return ERR_MALLOC; - } - if(!( files_file = malloc(10) )) { // files.tmp - DEBUGF("new_db: could not malloc() for files[] file_name\n"); - return ERR_MALLOC; - } - strcpy(files_file, "files.tmp"); - - return ERR_NONE; -} - -int db_destruct() { - int rc; - - CATCH_ERR( array_buffer_destruct(artists, 1) ); - artists = NULL; - free(artists_file); - artists_file = NULL; - - CATCH_ERR( array_buffer_destruct(albums, 1) ); - albums = NULL; - free(albums_file); - albums_file = NULL; - - CATCH_ERR( array_buffer_destruct(songs, 1) ); - songs = NULL; - free(songs_file); - songs_file = NULL; - - CATCH_ERR( array_buffer_destruct(files, 1) ); - files = NULL; - free(files_file); - files_file = NULL; - - return ERR_NONE; -} - -static int do_add(const struct tag_info *t) { - struct artist_entry *artist; uint32_t artistn; - struct album_entry *album; uint32_t albumn; - struct song_entry *song; uint32_t songn; - struct file_entry *file; uint32_t filen; - int rc; - - // create file - CATCH_MALLOC_NULL( file = new_file_entry( CEIL32BIT( strlen(t->directory) + 1 + strlen(t->filename) + 1 ) ) ); // "dir"."/"."file"."\0" - - // fill in file - strcpy(file->name, t->directory); - strcat(file->name, "/"); - strcat(file->name, t->filename); - file->hash = 0xffffffff; // TODO - file->song = songn = array_buffer_get_next_index(songs); - file->rundb = 0xffffffff; // TODO - - // add - CATCH_ERR( array_buffer_add(files, file, &filen) ); - - // create artist - CATCH_MALLOC_NULL( artist = new_artist_entry( CEIL32BIT_LEN(t->artist), 0) ); - // fill in - strcpy(artist->name, t->artist); - // see if it is already in - CATCH_MALLOC_ERR( rc = array_buffer_find_entry(artists, artist, &artistn) ); - if( rc == ERR_NONE ) { // found it - // remove our self-made one - artist_entry_destruct(artist); - artist = NULL; - } else if( rc == ERR_NOTFOUND ) { // didn't find it - // fill in the rest and add - CATCH_ERR( artist_entry_resize(artist, artist->size.name_len, 1) ); - artist->album[0] = albumn = array_buffer_get_next_index(albums); // if artist isn't in, album will not be in either - CATCH_ERR( array_buffer_add(artists, artist, &artistn) ); - // leave artist != NULL, to indicate that we made a new one - } else { //error - DEBUGF("do_add: could not search for artist in artists[]\n"); - return rc; - } - - - // create album - CATCH_MALLOC_NULL( album = new_album_entry(0,0) ); - // malloc for key - CATCH_MALLOC_NULL( album->key = malloc( strlen(t->album) + 3 + strlen(t->artist) + 3 + strlen(t->directory) + 1 ) ); - // fill in - strcpy(album->key, t->album); - strcat(album->key, "___"); - strcat(album->key, t->artist); - strcat(album->key, "___"); - strcat(album->key, t->directory); - // see if it is already in - CATCH_MALLOC_ERR( rc = array_buffer_find_entry(albums, album, &albumn) ); - if( rc == ERR_NONE ) { // found it - assert(artist == NULL); // make sure artist was found; else we have trouble! - // Remove our search-album and add the song to the already existing one - album_entry_destruct(album); - album = NULL; - CATCH_ERR( array_buffer_entry_update(albums, albumn, songn) ); - } else if( rc == ERR_NOTFOUND ) { // didn't find it - // fill in the rest of the info in this album and add it - CATCH_ERR( album_entry_resize(album, CEIL32BIT_LEN(t->album), 1 ) ); - strcpy(album->name, t->album); - album->artist = artistn; - album->song[0] = songn; - CATCH_ERR( array_buffer_add(albums, album, &albumn) ); - } else { // error - DEBUGF("do_add: could not search for album in albums[]\n"); - return rc; - } - - - if( album != NULL && artist == NULL ) { - // we have a new album from an already existing artist - // add it! - CATCH_ERR( array_buffer_entry_update(artists, artistn, albumn) ); - } - - - // song - CATCH_MALLOC_NULL( song = new_song_entry( CEIL32BIT_LEN(t->song), CEIL32BIT_LEN(t->genre)) ); - // fill in - strcpy(song->name, t->song); - song->artist = artistn; - song->album = albumn; - song->file = filen; - strcpy(song->genre, t->genre); - song->bitrate = t->bitrate; - song->year = t->year; - song->playtime = t->playtime; - song->track = t->track; - song->samplerate = t->samplerate; - // add - CATCH_ERR( array_buffer_add(songs, song, NULL) ); - - return ERR_NONE; -} - -static int tag_empty_get(struct tag_info *t) { - assert( t != NULL ); - - if( t->song == NULL ) { - CATCH_MALLOC_NULL( t->song = (char*)malloc(14) ); - strcpy(t->song, "<no song tag>"); - } - if( t->genre == NULL ) { - CATCH_MALLOC_NULL( t->genre = (char*)malloc(15) ); - strcpy(t->genre, "<no genre tag>"); - } - if( t->artist == NULL ) { - CATCH_MALLOC_NULL( t->artist = (char*)malloc(16) ); - strcpy(t->artist, "<no artist tag>"); - } - if( t->album == NULL ) { - CATCH_MALLOC_NULL( t->album = (char*)malloc(15) ); - strcpy(t->album, "<no album tag>"); - } - - return ERR_NONE; -} - -int db_add(char* file_path, const char* strip_path, const char* add_path) { - char *basename, *dir; - struct tag_info *t; - int rc; - - assert(file_path != NULL); - - // Create a new tag_info structure - CATCH_MALLOC_NULL( t = new_tag_info() ); - - // fill in the file_name - basename = strrchr(file_path, '/'); // TODO: add \ for windows - if( basename == NULL ) { - basename = file_path; // no / in the path, so it's only a filename - dir = NULL; - } else { - dir = file_path; - basename[0] = '\0'; // set the / to \0 to split the string - basename++; // skip past the / - } - CATCH_MALLOC_NULL( t->filename = malloc(strlen(basename)+1) ); // +1 for the '\0' termination - strcpy(t->filename, basename); - - // convert the path - if( strip_path != NULL && strlen(strip_path) > 0) { - if( dir == NULL || strncmp(file_path, strip_path, strlen(strip_path)) ) { - printf("db_add: could not strip path from \"%s\"\n", file_path); - } else { - dir += strlen(strip_path); // skip the path to strip - } - } - if( add_path != NULL ) { - CATCH_MALLOC_NULL( t->directory = malloc( strlen(add_path) + strlen(dir) + 1 ) ); // +1 for '\0' termination - strcpy(t->directory, add_path); - strcat(t->directory, dir); - } else { - CATCH_MALLOC_NULL( t->directory = malloc( strlen(dir) + 1 ) ); - strcpy(t->directory, dir); - } - - // restore the file_path to it's original state - if( dir != NULL) *(basename-1) = '/'; - - // So far we have: - // filename - // directory - // try to get the rest from tag-information: - //tag_id3v2_get(file_path, t); - //tag_id3v1_get(file_path, t); - tag_dummy(file_path, t); - - // If it is still empty here, skip this file - if( t->artist==NULL && t->song==NULL && t->album==NULL && t->genre==NULL) { - tag_info_destruct(t); // we won't need it anymore - return ERR_NONE; - } - - // fill in empty tags with "<no ... tag>" - CATCH_ERR( tag_empty_get(t) ); - - // all filled in, now add it - CATCH_ERR( do_add(t) ); - - tag_info_destruct(t); // we won't need it anymore - - return ERR_NONE; -} - -static int free_ram() { - // put things in file that we won't need to search a lot: - // files[] and songs[] are write only - // artists[] and albums[] should stay in memory as long as possible - // albums[] is updated for every song; - // artists[] for every album: artists[] will be the first to loose ram... - if(!( in_file & 0x01 )) { // files[] is still in ram - in_file |= 0x01; - // switch files[] to file-mode - files->file_name = files_file; - files_file = NULL; // since array_buffer will clean this up - return array_buffer_switch_to_file(files); - } else if(!( in_file & 0x02 )) { // song[] is still in ram - in_file |= 0x02; - // switch songs[] to file-mode - songs->file_name = songs_file; - songs_file = NULL; // since array_buffer will clean this up - return array_buffer_switch_to_file(songs); - } else if(!( in_file & 0x04 )) { // artists[] is still in ram - in_file |= 0x04; - // switch artists[] to file-mode - artists->file_name = artists_file; - artists_file = NULL; // since array_buffer will clean this up - return array_buffer_switch_to_file(artists); - } else if(!( in_file & 0x08 )) { // albums[] is still in ram - in_file |= 0x08; - // switch albums[] to file-mode - albums->file_name = albums_file; - albums_file = NULL; // since array_buffer will clean this up - return array_buffer_switch_to_file(albums); - } else { - // all is already in file mode, sorry... - DEBUGF("free_ram: everything is already in file-mode, cannot free more ram, sorry...\n"); - return ERR_MALLOC; - } -} - -static int fill_artist_offsets(struct artist_entry *e, struct artist_size *max_s) { - uint32_t i; - - assert(e != NULL); - assert(album_start != 0); - - for(i=0; i<e->size.album_count; i++) { - e->album[i] = album_start + e->album[i] * album_entry_len; - } - return ERR_NONE; -} - -static int fill_album_offsets(struct album_entry *e, struct album_size *max_s) { - uint32_t i; - - assert(e != NULL); - assert(song_start != 0); - - e->artist = artist_start + e->artist * artist_entry_len; - for(i=0; i<e->size.song_count; i++) { - e->song[i] = song_start + e->song[i] * song_entry_len; - } - return ERR_NONE; -} - -static int fill_song_offsets(struct song_entry *e, struct song_size *max_s) { - - assert(e != NULL); - assert(artist_start != 0); - assert(album_start != 0); - assert(file_start != 0); - - e->artist = artist_start + e->artist * artist_entry_len; - e->album = album_start + e->album * album_entry_len; - e->file = file_start + e->file * file_entry_len; - return ERR_NONE; -} - -static int fill_file_offsets(struct file_entry *e, struct file_size *max_s) { - - assert(e != NULL); - assert(song_start != 0); - - e->song = song_start + e->song * song_entry_len; - return ERR_NONE; -} - -static int do_write(FILE *fd) { - int rc; - struct header h; - - assert(fd != NULL); - - // make a header - h.magic[0] = 'R'; h.magic[1] = 'D'; h.magic[2] = 'B'; - h.version = 0x03; - - h.artist_start = artist_start = HEADER_SIZE; - h.album_start = album_start = h.artist_start + array_buffer_get_length(artists); // TODO error check - h.song_start = song_start = h.album_start + array_buffer_get_length(albums); - h.file_start = file_start = h.song_start + array_buffer_get_length(songs); - - h.artist_count = artists->count; - h.album_count = albums->count; - h.song_count = songs->count; - h.file_count = files->count; - - h.artist_len = ((struct artist_size*)artists->max_size)->name_len; - h.album_len = ((struct album_size*)albums->max_size)->name_len; - h.song_len = ((struct song_size*)songs->max_size)->name_len; - h.genre_len = ((struct song_size*)songs->max_size)->genre_len; - h.file_len = ((struct file_size*)files->max_size)->name_len; - - artist_entry_len = artist_size_get_length(artists->max_size); // TODO error check - album_entry_len = album_size_get_length(albums->max_size); - song_entry_len = song_size_get_length(songs->max_size); - file_entry_len = file_size_get_length(files->max_size); - - h.song_array_count = ((struct album_size*)albums->max_size)->song_count; - h.album_array_count = ((struct artist_size*)artists->max_size)->album_count; - - h.flags.reserved = 0; - h.flags.rundb_dirty = 1; - - // write the header - CATCH_ERR( header_write(fd, &h) ); - - // write the arrays - CATCH_ERR( array_buffer_write(fd, artists) ); - CATCH_ERR( array_buffer_write(fd, albums) ); - CATCH_ERR( array_buffer_write(fd, songs) ); - CATCH_ERR( array_buffer_write(fd, files) ); - - return ERR_NONE; -} - -int db_write(FILE *fd) { - int rc; - // sort everything - CATCH_ERR( array_buffer_sort(artists) ); - CATCH_ERR( array_buffer_sort(albums) ); - CATCH_ERR( array_buffer_sort(songs) ); - CATCH_ERR( array_buffer_sort(files) ); - - CATCH_ERR( do_write(fd) ); - - return ERR_NONE; -} - -struct tag_info* new_tag_info() { - struct tag_info *t; - t = malloc(sizeof(struct tag_info)); - if( t == NULL ) { - DEBUGF("new_tag_info: could not malloc() for tag_info\n"); - return NULL; - } - - t->directory = NULL; - t->filename = NULL; - t->song = NULL; - t->artist = NULL; - t->album = NULL; - t->genre = NULL; - t->bitrate = 0; - t->year = 0; - t->playtime = 0; - t->track = 0; - t->samplerate = 0; - - return t; -} - -int tag_info_destruct(struct tag_info *t) { - assert(t != NULL); - - free(t->directory); - t->directory = NULL; - free(t->filename); - t->filename = NULL; - free(t->song); - t->song = NULL; - free(t->artist); - t->artist = NULL; - free(t->album); - t->album = NULL; - free(t->genre); - t->genre = NULL; - t->bitrate = 0; - t->year = 0; - t->playtime = 0; - t->track = 0; - t->samplerate = 0; - - free(t); - - return ERR_NONE; -} -#endif diff --git a/apps/tagdb/db.h b/apps/tagdb/db.h deleted file mode 100644 index 709bf1f..0000000 --- a/apps/tagdb/db.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __DB_H__ -#define __DB_H__ - -#include "config.h" -#include <stdio.h> - -#include "array_buffer.h" - -struct tag_info { - char* directory; - char* filename; // \0 terminated string's - char* song; - char* artist; - char* album; - char* genre; - uint16_t bitrate; - uint16_t year; - uint32_t playtime; - uint16_t track; - uint16_t samplerate; -}; - -int db_construct(); - -int db_destruct(); - -int db_add(char* file_path, const char* strip_path, const char* add_path); - -int db_sort(); - -int db_write(FILE *fd); - -struct tag_info* new_tag_info(); - -int tag_info_destruct(struct tag_info *t); - -#endif -#endif diff --git a/apps/tagdb/file.c b/apps/tagdb/file.c deleted file mode 100644 index 762f008..0000000 --- a/apps/tagdb/file.c +++ /dev/null @@ -1,270 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "malloc.h" // realloc() and free() -#include <string.h> // strncasecmp() - -#include "file.h" - -// how is our flag organized? -#define FLAG ( 0xBF ) -#define FLAG_VALID(flag) (flag == 0xBF) - -static int do_resize(struct file_entry *e, const uint32_t name_len, const int zero_fill); - -struct file_entry* new_file_entry(const uint32_t name_len) { - // Start my allocating memory - struct file_entry *e = (struct file_entry*)malloc(sizeof(struct file_entry)); - if( e == NULL ) { - DEBUGF("new_file_entry: could not allocate memory\n"); - return NULL; - } - - // We begin empty - e->name = NULL; - e->size.name_len = 0; - - e->hash = 0; - e->song = 0; - e->rundb = 0; - - e->flag = FLAG; - - // and resize to the requested size - if( do_resize(e, name_len, 1) ) { - free(e); - return NULL; - } - - return e; -} - -int file_entry_destruct(struct file_entry *e) { - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - free(e->name); - - free(e); - - return ERR_NONE; -} - -static int do_resize(struct file_entry *e, const uint32_t name_len, const int zero_fill) { - void* temp; - - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - if( name_len != e->size.name_len ) { - temp = realloc(e->name, name_len); - if(temp == NULL) { - DEBUGF("file_entry_resize: out of memory to resize name\n"); - return ERR_MALLOC; - } - e->name = (char*)temp; - - // if asked, fill it with zero's - if( zero_fill ) { - uint32_t i; - for(i=e->size.name_len; i<name_len; i++) - e->name[i] = (char)0x00; - } - - e->size.name_len = name_len; - } - - return ERR_NONE; -} - -inline int file_entry_resize(struct file_entry *e, const uint32_t name_len) { - return do_resize(e, name_len, 1); -} - -int file_entry_serialize(FILE *fd, const struct file_entry *e) { - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - // First byte we write is a flag-byte to indicate this is a valid record - if( fwrite(&e->flag, 1, 1, fd) != 1 ) { - DEBUGF("file_entry_serialize: failed to write flag-byte\n"); - return ERR_FILE; - } - - // First we write the length of the name field - if( fwrite(&e->size.name_len, sizeof(e->size.name_len), 1, fd) != 1 ) { - DEBUGF("file_entry_serialize: failed to write name_len\n"); - return ERR_FILE; - } - // now the name field itself - if( fwrite(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("file_entry_serialize: failed to write name\n"); - return ERR_FILE; - } - - // hash field - if( fwrite(&e->hash, sizeof(e->hash), 1, fd) != 1 ) { - DEBUGF("file_entry_serialize: failed to write hash\n"); - return ERR_FILE; - } - - // song field - if( fwrite(&e->song, sizeof(e->song), 1, fd) != 1 ) { - DEBUGF("file_entry_serialize: failed to write song\n"); - return ERR_FILE; - } - - // rundb field - if( fwrite(&e->rundb, sizeof(e->rundb), 1, fd) != 1 ) { - DEBUGF("file_entry_serialize: failed to write rundb\n"); - return ERR_FILE; - } - - return ERR_NONE; -} - -int file_entry_unserialize(struct file_entry **dest, FILE *fd) { - uint32_t length; - struct file_entry *e; - - assert(dest != NULL); - assert(fd != NULL); - - // Allocate memory - e = new_file_entry(0); - if( e == NULL ) { - DEBUGF("file_entry_unserialize: could not create new file_entry\n"); - return ERR_MALLOC; - } - - // First we read the length of the name field - if( fread(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("file_entry_unserialize: failed to read name_len\n"); - file_entry_destruct(e); - return ERR_FILE; - } - - // allocate memory for the upcomming name-field - if( do_resize(e, length, 0) ) { - DEBUGF("file_entry_unserialize: failed to allocate memory for name\n"); - file_entry_destruct(e); - return ERR_MALLOC; - } - - // read it in - if( fread(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("file_entry_unserialize: failed to read name\n"); - file_entry_destruct(e); - return ERR_FILE; - } - - // hash field - if( fread(&e->hash, sizeof(e->hash), 1, fd) != 1 ) { - DEBUGF("file_entry_unserialize: failed to read hash\n"); - file_entry_destruct(e); - return ERR_FILE; - } - - // song field - if( fread(&e->song, sizeof(e->song), 1, fd) != 1 ) { - DEBUGF("file_entry_unserialize: failed to read song\n"); - file_entry_destruct(e); - return ERR_FILE; - } - - // rundb field - if( fread(&e->rundb, sizeof(e->rundb), 1, fd) != 1 ) { - DEBUGF("file_entry_unserialize: failed to read rundb\n"); - file_entry_destruct(e); - return ERR_FILE; - } - - *dest = e; - return ERR_NONE; -} - -int file_entry_write(FILE *fd, struct file_entry *e, struct file_size *s) { - uint32_t be32; - char pad = 0x00; - - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - // file name - if( fwrite(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("file_entry_write: failed to write name\n"); - return ERR_FILE; - } - // pad the rest - be32 = e->size.name_len; // abuse be32 as counter - while( s != NULL && s->name_len > be32) { - if( fwrite(&pad, 1, 1, fd) == 1 ) { - be32++; - } else { - DEBUGF("file_entry_write: failed to pad name\n"); - return ERR_FILE; - } - } - - // hash - be32 = BE32(e->hash); - if( fwrite(&be32, sizeof(be32), 1, fd) != 1 ) { - DEBUGF("file_entry_write: failed to write hash\n"); - return ERR_FILE; - } - - // song - be32 = BE32(e->song); - if( fwrite(&be32, sizeof(be32), 1, fd) != 1 ) { - DEBUGF("file_entry_write: failed to write song\n"); - return ERR_FILE; - } - - // rundb - be32 = BE32(e->rundb); - if( fwrite(&be32, sizeof(be32), 1, fd) != 1 ) { - DEBUGF("file_entry_write: failed to write rundb\n"); - return ERR_FILE; - } - - return ERR_NONE; -} - -inline int file_entry_compare(const struct file_entry *a, const struct file_entry *b) { - assert(a != NULL); - assert(b != NULL); - return strncasecmp(a->name, b->name, (a->size.name_len <= b->size.name_len ? a->size.name_len : b->size.name_len) ); -} - -struct file_size* new_file_size() { - struct file_size *s; - s = (struct file_size*)malloc(sizeof(struct file_size)); - if( s == NULL ) { - DEBUGF("new_file_size: failed to allocate memory\n"); - return NULL; - } - s->name_len = 0; - - return s; -} - -inline uint32_t file_size_get_length(const struct file_size *size) { - assert(size != NULL); - return size->name_len + 12; -} - -inline int file_size_max(struct file_size *s, const struct file_entry *e) { - assert(s != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - s->name_len = ( s->name_len >= e->size.name_len ? s->name_len : e->size.name_len ); - return ERR_NONE; -} - -int file_size_destruct(struct file_size *s) { - assert(s != NULL); - // nothing to do... - free(s); - return ERR_NONE; -} -#endif diff --git a/apps/tagdb/file.h b/apps/tagdb/file.h deleted file mode 100644 index 103a601..0000000 --- a/apps/tagdb/file.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __FILE_H__ -#define __FILE_H__ - -#include "config.h" -#include <stdio.h> -#include <stdint.h> - -struct file_entry { - char* name; // song name - - uint32_t hash; - uint32_t song; // pointer to song - uint32_t rundb; // pointer to rundb - - struct file_size { - uint32_t name_len; // must be mulitple of 4 - } size; - unsigned char flag; // flags -}; - -struct file_entry* new_file_entry(const uint32_t name_len); -/* Creates a new file_entry with the specified sizes - * Returns a pointer to the structure on success, - * NULL on failure - */ - -int file_entry_destruct(struct file_entry *e); -/* Destructs the given file_entry and free()'s it's memory - * returns 0 on success, 1 on failure - */ - -inline int file_entry_resize(struct file_entry *e, const uint32_t name_len); -/* Change the size of the entry - * returns 0 on succes, 1 on failure - */ - -int file_entry_serialize(FILE *fd, const struct file_entry *e); -/* Serializes the entry in the file at the current position - * returns 0 on success, 1 on failure - */ - -int file_entry_unserialize(struct file_entry* *e, FILE *fd); -/* Unserializes an entry from file into a new structure - * The address of the structure is saved into *e - * returns 0 on success - * 1 on malloc() failure - * 2 on fread() failure - */ - -int file_entry_write(FILE *fd, struct file_entry *e, struct file_size *s); -/* Writes the entry to file in the final form - * returns 0 (0) on success, 1 (1) on failure - */ - -inline int file_entry_compare(const struct file_entry *a, const struct file_entry *b); -/* Compares 2 entries - * When a < b it returns <0 - * a = b 0 - * a > b >0 - */ - -struct file_size* new_file_size(); -/* Creates a new size structure - * returns a pointer to the structure on success, - * NULL on failure - */ - -inline uint32_t file_size_get_length(const struct file_size *size); -/* Calculates the length of the entry when written by file_entry_write() - * returns the length on success, 0xffffffff on failure - */ - -inline int file_size_max(struct file_size *s, const struct file_entry *e); -/* Updates the file_size structure to contain the maximal lengths of either - * the original entry in s, or the entry e - * returns 0 on success, 1 on failure - */ - -int file_size_destruct(struct file_size *s); -/* destructs the file_size structure - * returns 0 on success, 1 on failure - */ - -#endif -#ifdef HAVE_TAGCACHE diff --git a/apps/tagdb/header.c b/apps/tagdb/header.c deleted file mode 100644 index 524c5b7..0000000 --- a/apps/tagdb/header.c +++ /dev/null @@ -1,122 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include <stdio.h> - -#include "header.h" - -int header_write(FILE *fd, const struct header *h) { -// Write the header to file - uint32_t be; - - if( fwrite(h->magic, 3, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write magic[3]\n"); - return ERR_FILE; - } - if( fwrite(&h->version, 1, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write version\n"); - return ERR_FILE; - } - - be = BE32(h->artist_start); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write artist_start\n"); - return ERR_FILE; - } - - be = BE32(h->album_start); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write album_start\n"); - return ERR_FILE; - } - - be = BE32(h->song_start); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write song_start\n"); - return ERR_FILE; - } - - be = BE32(h->file_start); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write file_start\n"); - return ERR_FILE; - } - - - be = BE32(h->artist_count); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write artist_count\n"); - return ERR_FILE; - } - - be = BE32(h->album_count); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write album_count\n"); - return ERR_FILE; - } - - be = BE32(h->song_count); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write song_count\n"); - return ERR_FILE; - } - - be = BE32(h->file_count); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write file_count\n"); - return ERR_FILE; - } - - - be = BE32(h->artist_len); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write artist_len\n"); - return ERR_FILE; - } - - be = BE32(h->album_len); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write album_len\n"); - return ERR_FILE; - } - - be = BE32(h->song_len); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write song_len\n"); - return ERR_FILE; - } - - be = BE32(h->genre_len); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write genre_len\n"); - return ERR_FILE; - } - - be = BE32(h->file_len); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write file_len\n"); - return ERR_FILE; - } - - - be = BE32(h->song_array_count); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write song_array_count\n"); - return ERR_FILE; - } - - be = BE32(h->album_array_count); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write album_array_count\n"); - return ERR_FILE; - } - - - be = BE32( (h->flags.reserved << 1) | (h->flags.rundb_dirty) ); - if( fwrite(&be, 4, 1, fd) != 1 ) { - DEBUGF("header_write: failed to write flags\n"); - return ERR_FILE; - } - - - return ERR_NONE; -} -#endif diff --git a/apps/tagdb/header.h b/apps/tagdb/header.h deleted file mode 100644 index 28a28d3..0000000 --- a/apps/tagdb/header.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __HEADER_H__ -#define __HEADER_H__ - -#include "config.h" - -#define HEADER_SIZE 68 - -struct header { - char magic[3]; // (four bytes: 'R' 'D' 'B' and a byte for version. This is version 2. (0x02) - unsigned char version; - - uint32_t artist_start; // File Offset to the artist table(starting from 0) - uint32_t album_start; // File Offset to the album table(starting from 0) - uint32_t song_start; // File Offset of the song table(starting from 0) - uint32_t file_start; // File Offset to the filename table(starting from 0) - - uint32_t artist_count; // Number of artists - uint32_t album_count; // Number of albums - uint32_t song_count; // Number of songs - uint32_t file_count; // Number of File Entries, this is needed for the binary search. - - uint32_t artist_len; // Max Length of the artist name field - uint32_t album_len; // Max Length of the album name field - uint32_t song_len; // Max Length of the song name field - uint32_t genre_len; // Max Length of the genre field - uint32_t file_len; // Max Length of the filename field. - - uint32_t song_array_count; // Number of entries in songs-per-album array - uint32_t album_array_count; // Number of entries in albums-per-artist array - - struct { - unsigned reserved : 31; // must be 0 - unsigned rundb_dirty : 1; // if the TagDatabase in unsynchronized with the RuntimeDatabase, 0 if synchronized. - } flags; -}; - -int header_write(FILE *fd, const struct header *header); - -#endif -#endif diff --git a/apps/tagdb/main.c b/apps/tagdb/main.c deleted file mode 100644 index ce695e6..0000000 --- a/apps/tagdb/main.c +++ /dev/null @@ -1,117 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "config.h" - -#include <stdio.h> -#include <string.h> // strcmp() -#include <dirent.h> // opendir() readdir() closedir() -#include <sys/stat.h> // IS_DIR - -#include "malloc.h" -#include "db.h" - -extern int out_of_memory; - -// dir-is-album: all files in the dir ARE the same album, use the first name found. -// dir-is-album-name: if no tag found, use the dir's instead of "<no album tag>" -// -// files in different dirs are ALWAYS different albums - -static char* strip_path = NULL; -static char* add_path = NULL; - -static int iterate_dir(char* dir); -/* Iterates over each item in the given directory - * calls add_file() on each file - * calls iterate_directory() on each directory (recursively) - */ - -static int iterate_dir(char* dir) { - DIR *d; - struct dirent *e; - struct stat s; - int rc; - - assert(dir != NULL); - - if(!( d = opendir(dir) )) { - DEBUGF("iterate_dir: could not open directory \"%s\"\n", dir); - return ERR_FILE; - } - - while(( e = readdir(d) )) { - char *path; - - if( strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0 ) - continue; // we don't want to descend or loop around... - - path = malloc(strlen(dir) + 1 + strlen(e->d_name) + 1); // "dir/d_name\0" - if( path == NULL ) { - DEBUGF("iterate_dir: could not malloc() directory-entry-name\n"); - return ERR_MALLOC; - } - strcpy(path, dir); - strcat(path, "/"); - strcat(path, e->d_name); -#if defined OS_LINUX - if( stat(path, &s) ) { - DEBUGF("iterate_dir: could not stat(\"%s\")\n", path); - return ERR_FILE; - } - - if( S_ISDIR(s.st_mode) ) { -#elif defined OS_ROCKBOX -#error "Rockbox: not yet implemented: don't know how to list directory" - if( false ) { -#elif defined OS_WINDOWS - if( false ) { -#error "Windows: not yet implemented: don't know how to list directory" -#else - if( false ) { -#error "No OS specified: don't know how to list directory" -#endif - if(( rc = iterate_dir(path) )) { - closedir(d); - return rc; - } - } else { - if(( rc = db_add(path, strip_path, add_path) )) { - closedir(d); - return rc; - } - } - free(path); - } - - if( closedir(d) ) { - DEBUGF("iterate_dir: could not close directory \"%s\", ignoring...\n", dir); - } - - return ERR_NONE; -} - -int main(int argc, char* argv[]) { - FILE *fd; - - if( argc != 2 ) { - printf("usage: ./songdb dir\n"); - return 1; - } - - strip_path = "/home/niels/"; - add_path = "TEST/"; - - db_construct(); - - iterate_dir(argv[1]); - - fd = fopen("xxx.db", "w"); - db_write(fd); - fclose(fd); - - db_destruct(); - - malloc_stats(); - - return 0; -} -#endif diff --git a/apps/tagdb/malloc.c b/apps/tagdb/malloc.c deleted file mode 100644 index dbc2c5b..0000000 --- a/apps/tagdb/malloc.c +++ /dev/null @@ -1,133 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "config.h" -#include "malloc.h" - -#undef malloc -#undef free -#undef realloc - -#undef DEBUGF -#define DEBUGF(...) - -#include <stdio.h> -#include <stdlib.h> - -static size_t total=0; -static size_t max_total=0; - -struct size_array { - void *ptr; - size_t size; -} sizes[1000]; -#define NOT_FOUND 1001 -static unsigned long count=0; - -int out_of_memory = 1000000; - -void *do_malloc(size_t size) { - void *ret; - if(total + size > out_of_memory) { - DEBUGF("malloc(%d), total=%d: FAILED: simulating out-of-memory\n", size, total+size); - return NULL; - } - - ret = malloc(size); - if( ret == NULL ) { - DEBUGF("malloc(%d), total=%d FAILED\n", size, total+size); - return NULL; - } else { - total += size; - max_total = ( total > max_total ? total : max_total ); - sizes[count].ptr = ret; - sizes[count].size = size; - DEBUGF("malloc(%d), total=%d OK => 0x%08lx (%lu)\n", size, total, (unsigned long)ret, count); - count++; - if(count == NOT_FOUND) { - fprintf(stderr, "MALLOC MEMORY FULL!!!!!!! FAILING\n"); - free(ret); - count--; - return NULL; - } - return ret; - } -} - -static unsigned long find(void* ptr) { - unsigned long i; - for(i=0; i<count; i++) { - if( ptr == sizes[i].ptr ) { - return i; - } - } - return NOT_FOUND; -} - -void do_free(void *ptr) { - unsigned long i; - - i = find(ptr); - if( i == NOT_FOUND ) { - DEBUGF("free(%08lx) (?) ptr unknown\n", (unsigned long)ptr); - free(ptr); - } else { - total -= sizes[i].size; - DEBUGF("free(%08lx) (%lu, %dbytes) => total=%u\n", (unsigned long)ptr, i, sizes[i].size, total); - free(ptr); - sizes[i].ptr = NULL; // delete - sizes[i].size = 0; - } -} - -void *do_realloc(void *ptr, size_t size) { - void *ret; - unsigned long i; - - if( ptr == NULL ) { - DEBUGF("realloc()=>"); - return do_malloc(size); - } - - i = find(ptr); - - if( i == NOT_FOUND ) { - DEBUGF("realloc(%08lx, %d) (?) ptr unknown ", (unsigned long)ptr, size); - } else { - DEBUGF("realloc(%08lx, %d) (%lu, %dbytes) => total=%d ", (unsigned long)ptr, size, i, sizes[i].size, total+size-sizes[i].size); - } - - if(total + size - sizes[i].size > out_of_memory) { - DEBUGF("FAILED: simulating out-of-memory\n"); - return NULL; - } - - ret = realloc(ptr, size); - if( ret == NULL && size != 0) { // realloc(x, 0) returns NULL, but is valid! - DEBUGF("FAILED\n"); - } else { - total += size - sizes[i].size; - max_total = ( total > max_total ? total : max_total ); - sizes[i].ptr = ret; // update the ptr if realloc changed it - sizes[i].size = size; - DEBUGF("=> %08lx\n", (unsigned long)ret); - } - return ret; -} - -void malloc_stats() { - unsigned long i, j; - - printf("malloc stats:\n"); - printf(" Total number of allocated items: %lu\n", count); - printf(" Current number of allocated items: "); - j=0; - for(i=0; i<count; i++) { - if( sizes[i].ptr != NULL) { - printf("%lu ", i); - j++; - } - } - printf("=> %lu items\n", j); - printf(" Maximum amount of allocated memory: %dbytes\n", max_total); - printf(" Current amount of allocated memory: %dbytes\n", total); -} -#endif diff --git a/apps/tagdb/malloc.h b/apps/tagdb/malloc.h deleted file mode 100644 index c09649b..0000000 --- a/apps/tagdb/malloc.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __MALLOC_H__ -#define __MALLOC_H__ - -#include <stdlib.h> - -#define malloc do_malloc -#define free do_free -#define realloc do_realloc - -void *do_malloc(size_t size); -void do_free(void *ptr); -void *do_realloc(void *ptr, size_t size); - -void malloc_stats(); - -#endif -#endif diff --git a/apps/tagdb/parser.c b/apps/tagdb/parser.c deleted file mode 100644 index 6e2eeff..0000000 --- a/apps/tagdb/parser.c +++ /dev/null @@ -1,219 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <errno.h> - -#include "config.h" - -int read_failure(FILE *fd) { - fprintf(stderr, "Could not read from file: errno: %u ", errno); - if( feof(fd) ) fprintf(stderr, "EOF"); - fprintf(stderr, "\n"); - return 1; -} - -int mem_failure() { - fprintf(stderr, "Could not (re)allocate memory\n"); - return 1; -} - -int main(int argc, char *argv[]) { - FILE *fd; - uint32_t artist_start, album_start, song_start, file_start; - uint32_t artist_count, album_count, song_count, file_count; - uint32_t artist_len, album_array_count; - uint32_t album_len, song_array_count; - uint32_t song_len, genre_len; - uint32_t file_len; -#define header_start 0 -#define header_len 68 - - uint32_t i, j; - char *ct1 = NULL, *ct2 = NULL; // char temp 1 and 2 - uint32_t it = 0; // integer temp - - // input validation - if( argc != 2 ) { - fprintf(stderr, "usage: parser dbfile\n"); - return 1; - } - - // open file - fd = fopen(argv[1], "r"); - if( fd == NULL ) { - fprintf(stderr, "Could not open file \"%s\"\n", argv[1]); - return 1; - } - - // read the header - ct1 = realloc(ct1, 4); if( ct1 == NULL ) return mem_failure(); - if( fread(ct1, 4, 1, fd) != 1 ) return read_failure(fd); - if( ct1[0] != 'R' || ct1[1] != 'D' || ct1[2] != 'B' ) { - printf("No header found\n"); - return 1; - } - if( ct1[3] != 0x03 ) { - printf("Not version 3\n"); - return 1; - } - - if( fread(&artist_start, 4, 1, fd) != 1 ) return read_failure(fd); artist_start = BE32(artist_start); - if( fread(&album_start, 4, 1, fd) != 1 ) return read_failure(fd); album_start = BE32(album_start); - if( fread(&song_start, 4, 1, fd) != 1 ) return read_failure(fd); song_start = BE32(song_start); - if( fread(&file_start, 4, 1, fd) != 1 ) return read_failure(fd); file_start = BE32(file_start); - - if( fread(&artist_count, 4, 1, fd) != 1 ) return read_failure(fd); artist_count = BE32(artist_count); - if( fread(&album_count, 4, 1, fd) != 1 ) return read_failure(fd); album_count = BE32(album_count); - if( fread(&song_count, 4, 1, fd) != 1 ) return read_failure(fd); song_count = BE32(song_count); - if( fread(&file_count, 4, 1, fd) != 1 ) return read_failure(fd); file_count = BE32(file_count); - - if( fread(&artist_len, 4, 1, fd) != 1 ) return read_failure(fd); artist_len = BE32(artist_len); - if( fread(&album_len, 4, 1, fd) != 1 ) return read_failure(fd); album_len = BE32(album_len); - if( fread(&song_len, 4, 1, fd) != 1 ) return read_failure(fd); song_len = BE32(song_len); - if( fread(&genre_len, 4, 1, fd) != 1 ) return read_failure(fd); genre_len = BE32(genre_len); - if( fread(&file_len, 4, 1, fd) != 1 ) return read_failure(fd); file_len = BE32(file_len); - - if( fread(&song_array_count, 4, 1, fd) != 1 ) return read_failure(fd); song_array_count = BE32(song_array_count); - if( fread(&album_array_count, 4, 1, fd) != 1 ) return read_failure(fd); album_array_count = BE32(album_array_count); - - if( fread(ct1, 4, 1, fd) != 1 ) return read_failure(fd); - - // print header info - printf("HEADER"); - printf("\n Artist start: 0x%08x = %u", artist_start, artist_start); - if( artist_start != header_start + header_len ) - printf(" should be 0x%08x = %u", header_start + header_len, header_start + header_len); - printf("\n Album start: 0x%08x = %u", album_start, album_start); - if( album_start != artist_start + artist_count*(artist_len + 4*album_array_count) ) - printf(" should be 0x%08x = %u", artist_start + artist_count*(artist_len + 4*album_array_count), - artist_start + artist_count*(artist_len + 4*album_array_count)); - printf("\n Song start: 0x%08x = %u", song_start, song_start); - if( song_start != album_start + album_count*(album_len + 4 + 4*song_array_count) ) - printf(" should be 0x%08x = %u", album_start + album_count*(album_len + 4 + 4*song_array_count), - album_start + album_count*(album_len + 4 + 4*song_array_count)); - printf("\n File start: 0x%08x = %u", file_start, file_start); - if( file_start != song_start + song_count*(song_len + genre_len + 24) ) - printf(" should be 0x%08x = %u", song_start + song_count*(song_len + genre_len + 24), - song_start + song_count*(song_len + genre_len + 24)); - - printf("\n Artist count: 0x%08x = %u\n", artist_count, artist_count); - printf(" Album count: 0x%08x = %u\n", album_count, album_count); - printf(" Song count: 0x%08x = %u\n", song_count, song_count); - printf(" File count: 0x%08x = %u\n", file_count, file_count); - - printf(" Artist len: 0x%08x = %u\n", artist_len, artist_len); - printf(" Album len: 0x%08x = %u\n", album_len, album_len); - printf(" Song len: 0x%08x = %u\n", song_len, song_len); - printf(" Genre len: 0x%08x = %u\n", genre_len, genre_len); - printf(" File len: 0x%08x = %u\n", file_len, file_len); - - printf(" Song[] count: 0x%08x = %u\n", song_array_count, song_array_count); - printf(" Album[] count: 0x%08x = %u\n", album_array_count, album_array_count); - - printf(" Reserved: 0x%08x\n", ct1[0] & 0xFFFFFFFE); - printf(" Rundb dirty: 0x%01x\n", ct1[3] & 0x01); - - // iterate over artists: - ct1 = realloc(ct1, artist_len); if( ct1 == NULL && artist_count!=0 ) return mem_failure(); - for(i=0; i < artist_count; i++) { - printf("ARTIST %u/%u (offset 0x%08lx)\n", i, artist_count, (unsigned long)ftell(fd)); - - if( fread(ct1, artist_len, 1, fd) != 1 ) return read_failure(fd); - printf(" Name: \"%s\"\n", ct1); - - printf(" Albums:\n"); - for(j=0; j < album_array_count; j++) { - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Offset 0x%08x = ", it); - if(it != 0) { - printf("item %u\n", (it - album_start) / (album_len + 4 + 4*song_array_count)); - } else { - printf("padding\n"); - } - } - } - - // iterate over albums: - ct1 = realloc(ct1, album_len); if( ct1 == NULL && album_count!=0) return mem_failure(); - for(i=0; i < album_count; i++) { - printf("ALBUM %u/%u (offset 0x%08lx)\n", i, album_count, (unsigned long)ftell(fd)); - - if( fread(ct1, album_len, 1, fd) != 1 ) return read_failure(fd); - printf(" Name: \"%s\"\n", ct1); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Artist offset: 0x%08x = item %u\n", it, (it - artist_start) / (artist_len + 4*album_array_count)); - - printf(" Songs:\n"); - for(j=0; j < song_array_count; j++) { - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Offset 0x%08x = ", it); - if(it != 0) { - printf("item %u\n", (it - song_start) / (song_len + genre_len + 24)); - } else { - printf("padding\n"); - } - } - } - - // iterate over songs: - ct1 = realloc(ct1, song_len); if( ct1 == NULL && song_count!=0) return mem_failure(); - ct2 = realloc(ct2, genre_len); if( ct2 == NULL && song_count!=0) return mem_failure(); - for(i=0; i < song_count; i++) { - printf("SONG %u/%u (offset 0x%08lx)\n", i, song_count, (unsigned long)ftell(fd)); - - if( fread(ct1, song_len, 1, fd) != 1 ) return read_failure(fd); - printf(" Name: \"%s\"\n", ct1); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Artist offset: 0x%08x = item %u\n", it, (it - artist_start) / (artist_len + 4*album_array_count)); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Album offset: 0x%08x = item %u\n", it, (it - album_start) / (album_len + 4 + 4*song_array_count)); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" File offset: 0x%08x = item %u\n", it, (it - file_start) / (file_len + 12)); - - if( fread(ct2, genre_len, 1, fd) != 1 ) return read_failure(fd); - printf(" Genre: \"%s\"\n", ct2); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Bitrate: 0x%04x = %u\n", (it & 0xFFFF0000) >> 16, (it & 0xFFFF0000) >> 16); - printf(" Year: 0x%04x = %u\n", it & 0x0000FFFF, it & 0x0000FFFF); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Playtime: 0x%08x = %u\n", it, it); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Track: 0x%04x = %u\n", (it & 0xFFFF0000) >> 16, (it & 0xFFFF0000) >> 16); - printf(" Samplerate: 0x%04x = %u\n", it & 0x0000FFFF, it & 0x0000FFFF); - } - - // iterate over file: - ct1 = realloc(ct1, file_len); if( ct1 == NULL && file_count!=0) return mem_failure(); - for(i=0; i < file_count; i++) { - printf("FILE %u/%u (offset 0x%08lx)\n", i, file_count, (unsigned long)ftell(fd)); - - if( fread(ct1, file_len, 1, fd) != 1 ) return read_failure(fd); - printf(" Name: \"%s\"\n", ct1); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Hash: 0x%08x = %u\n", it, it); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Song offset: 0x%08x = item %u\n", it, (it - song_start) / (song_len + genre_len + 24)); - - if( fread(&it, 4, 1, fd) != 1 ) return read_failure(fd); it = BE32(it); - printf(" Rundb offset: 0x%08x = %u\n", it, it); - } - - // close the file - if( fclose(fd) != 0 ) { - fprintf(stderr, "Could not close file\n"); - return 1; - } - - return 0; -} -#endif diff --git a/apps/tagdb/song.c b/apps/tagdb/song.c deleted file mode 100644 index f62ecad..0000000 --- a/apps/tagdb/song.c +++ /dev/null @@ -1,452 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "malloc.h" // realloc() and free() -#include <string.h> // strncasecmp() - -#include "song.h" - -// how is our flag organized? -#define FLAG ( 0xCF ) -#define FLAG_VALID(flag) (flag == 0xCF) - -static int do_resize(struct song_entry *e, const uint32_t name_len, const uint32_t genre_len, const int zero_fill); - -struct song_entry* new_song_entry(const uint32_t name_len, const uint32_t genre_len) { - // Start my allocating memory - struct song_entry *e = (struct song_entry*)malloc(sizeof(struct song_entry)); - if( e == NULL ) { - DEBUGF("new_song_entry: could not allocate memory\n"); - return NULL; - } - - // We begin empty - e->name = NULL; - e->size.name_len = 0; - - e->artist = 0; - e->album = 0; - e->file = 0; - - e->genre = NULL; - e->size.genre_len = 0; - - e->bitrate = 0; - e->year = 0; - e->playtime = 0; - e->track = 0; - e->samplerate = 0; - - e->flag = FLAG; - - // and resize to the requested size - if( do_resize(e, name_len, genre_len, 1) ) { - free(e); - return NULL; - } - return e; -} - -int song_entry_destruct(struct song_entry *e) { - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - free(e->name); - free(e->genre); - - free(e); - - return ERR_NONE; -} - -static int do_resize(struct song_entry *e, const uint32_t name_len, const uint32_t genre_len, const int zero_fill) { - void* temp; - - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - // begin with name - if( name_len != e->size.name_len ) { - temp = realloc(e->name, name_len); - if(temp == NULL && name_len > 0) { // if realloc(,0) don't complain about NULL-pointer - DEBUGF("song_entry_resize: out of memory to resize name\n"); - return ERR_MALLOC; - } - e->name = (char*)temp; - - // if asked, fill it with zero's - if( zero_fill ) { - uint32_t i; - for(i=e->size.name_len; i<name_len; i++) - e->name[i] = (char)0x00; - } - - e->size.name_len = name_len; - } - - // now the genre - if( genre_len != e->size.genre_len ) { - temp = realloc(e->genre, genre_len); - if(temp == NULL && genre_len > 0) { // if realloc(,0) don't complain about NULL-pointer - DEBUGF("song_entry_resize: out of memory to resize genre\n"); - return ERR_MALLOC; - } - e->genre = (char*)temp; - - // if asked, fill it with zero's - if( zero_fill ) { - uint32_t i; - for(i=e->size.genre_len; i<genre_len; i++) - e->genre[i] = (char)0x00; - } - - e->size.genre_len = genre_len; - } - - return ERR_NONE; -} - -inline int song_entry_resize(struct song_entry *e, const uint32_t name_len, const uint32_t genre_len) { - return do_resize(e, name_len, genre_len, 1); -} - -int song_entry_serialize(FILE *fd, const struct song_entry *e) { - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - // First byte we write is a flag-byte to indicate this is a valid record - if( fwrite(&e->flag, 1, 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write flag-byte\n"); - return ERR_FILE; - } - - // Write the length of the name field - if( fwrite(&e->size.name_len, sizeof(e->size.name_len), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write name_len\n"); - return ERR_FILE; - } - - // now the name field itself - if( fwrite(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("song_entry_serialize: failed to write name\n"); - return ERR_FILE; - } - - // Artist field - if( fwrite(&e->artist, sizeof(e->artist), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write artist\n"); - return ERR_FILE; - } - - // Album field - if( fwrite(&e->album, sizeof(e->album), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write album\n"); - return ERR_FILE; - } - - // File field - if( fwrite(&e->file, sizeof(e->file), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write file\n"); - return ERR_FILE; - } - - // length of genre field - if( fwrite(&e->size.genre_len, sizeof(e->size.genre_len), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write genre_len\n"); - return ERR_FILE; - } - - // genre itself - if( fwrite(e->genre, 1, e->size.genre_len, fd) != e->size.genre_len ) { - DEBUGF("song_entry_serialize: failed to write genre\n"); - return ERR_FILE; - } - - // Bitrate field - if( fwrite(&e->bitrate, sizeof(e->bitrate), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write bitrate\n"); - return ERR_FILE; - } - - // Year field - if( fwrite(&e->year, sizeof(e->year), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write year\n"); - return ERR_FILE; - } - - // Playtime field - if( fwrite(&e->playtime, sizeof(e->playtime), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write playtime\n"); - return ERR_FILE; - } - - // Track field - if( fwrite(&e->track, sizeof(e->track), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write track\n"); - return ERR_FILE; - } - - // Samplerate field - if( fwrite(&e->samplerate, sizeof(e->samplerate), 1, fd) != 1 ) { - DEBUGF("song_entry_serialize: failed to write samplerate\n"); - return ERR_FILE; - } - - return ERR_NONE; -} - -int song_entry_unserialize(struct song_entry **dest, FILE *fd) { - uint32_t length; - struct song_entry* e; - - assert(dest != NULL); - assert(fd != NULL); - - // Allocate memory - e = new_song_entry(0, 0); - if( e == NULL ) { - DEBUGF("song_entry_unserialize: could not create new song_entry\n"); - return ERR_MALLOC; - } - - // First we read the length of the name field - if( fread(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read name_len\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // allocate memory for the upcomming name-field - if( do_resize(e, length, 0, 0) ) { - DEBUGF("song_entry_unserialize: failed to allocate memory for name\n"); - song_entry_destruct(e); - return ERR_MALLOC; - } - - // read it in - if( fread(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("song_entry_unserialize: failed to read name\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // Artist field - if( fread(&e->artist, sizeof(e->artist), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read artist\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // Album field - if( fread(&e->album, sizeof(e->album), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read album\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // File field - if( fread(&e->file, sizeof(e->file), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read file\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // Next the length of genre - if( fread(&length, sizeof(length), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read genre_len\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // allocate memory for the upcomming name-field - if( do_resize(e, e->size.name_len, length, 0) ) { - DEBUGF("song_entry_unserialize: failed to allocate memory for song\n"); - song_entry_destruct(e); - return ERR_MALLOC; - } - - // read it in - if( fread(e->genre, 1, e->size.genre_len, fd) != e->size.genre_len ) { - DEBUGF("song_entry_unserialize: failed to read genre\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // Bitrate field - if( fread(&e->bitrate, sizeof(e->bitrate), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read bitrate\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // Year field - if( fread(&e->year, sizeof(e->year), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read year\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // Playtime field - if( fread(&e->playtime, sizeof(e->playtime), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read playtime\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // Track field - if( fread(&e->track, sizeof(e->track), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read track\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - // Samplerate field - if( fread(&e->samplerate, sizeof(e->samplerate), 1, fd) != 1 ) { - DEBUGF("song_entry_unserialize: failed to read samplerate\n"); - song_entry_destruct(e); - return ERR_FILE; - } - - *dest = e; - return ERR_NONE; -} - -int song_entry_write(FILE *fd, struct song_entry *e, struct song_size *s) { - uint32_t be32; - uint16_t be16; - char pad = 0x00; - - assert(fd != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - - // song name - if( fwrite(e->name, 1, e->size.name_len, fd) != e->size.name_len ) { - DEBUGF("song_entry_write: failed to write name\n"); - return ERR_FILE; - } - // pad the rest (abuse be32 for counter) - be32 = e->size.name_len; - while( s != NULL && s->name_len > be32) { - if( fwrite(&pad, 1, 1, fd) == 1 ) { - be32++; - } else { - DEBUGF("genre_entry_write: failed to pad name\n"); - return ERR_FILE; - } - } - - // artist - be32 = BE32(e->artist); - if( fwrite(&be32, sizeof(be32), 1, fd) != 1 ) { - DEBUGF("song_entry_write: failed to write artist\n"); - return ERR_FILE; - } - - // album - be32 = BE32(e->album); - if( fwrite(&be32, sizeof(be32), 1, fd) != 1 ) { - DEBUGF("song_entry_write: failed to write album\n"); - return ERR_FILE; - } - - // file - be32 = BE32(e->file); - if( fwrite(&be32, sizeof(be32), 1, fd) != 1 ) { - DEBUGF("song_entry_write: failed to write file\n"); - return ERR_FILE; - } - - // genre - if( fwrite(e->genre, 1, e->size.genre_len, fd) != e->size.genre_len ) { - DEBUGF("song_entry_write: failed to write genre\n"); - return ERR_FILE; - } - // pad the rest (abuse be32 for counter) - be32 = e->size.genre_len; - while( s != NULL && s->genre_len > be32) { - if( fwrite(&pad, 1, 1, fd) == 1 ) { - be32++; - } else { - DEBUGF("genre_entry_write: failed to pad genre\n"); - return ERR_FILE; - } - } - - // bitrate - be16 = BE16(e->bitrate); - if( fwrite(&be16, sizeof(be16), 1, fd) != 1 ) { - DEBUGF("song_entry_write: failed to write bitrate\n"); - return ERR_FILE; - } - - // year - be16 = BE16(e->year); - if( fwrite(&be16, sizeof(be16), 1, fd) != 1 ) { - DEBUGF("song_entry_write: failed to write year\n"); - return ERR_FILE; - } - - // playtime - be32 = BE32(e->playtime); - if( fwrite(&be32, sizeof(be32), 1, fd) != 1 ) { - DEBUGF("song_entry_write: failed to write playtime\n"); - return ERR_FILE; - } - - // track - be16 = BE16(e->track); - if( fwrite(&be16, sizeof(be16), 1, fd) != 1 ) { - DEBUGF("song_entry_write: failed to write track\n"); - return ERR_FILE; - } - - // samplerate - be16 = BE16(e->samplerate); - if( fwrite(&be16, sizeof(be16), 1, fd) != 1 ) { - DEBUGF("song_entry_write: failed to write samplerate\n"); - return ERR_FILE; - } - - return ERR_NONE; -} - -inline int song_entry_compare(const struct song_entry *a, const struct song_entry *b) { - assert(a != NULL); - assert(b != NULL); - return strncasecmp(a->name, b->name, (a->size.name_len <= b->size.name_len ? a->size.name_len : b->size.name_len) ); -} - -struct song_size* new_song_size() { - struct song_size *s; - s = (struct song_size*)malloc(sizeof(struct song_size)); - if( s == NULL ) { - DEBUGF("new_song_size: failed to allocate memory\n"); - return NULL; - } - s->name_len = 0; - s->genre_len = 0; - - return s; -} - -inline uint32_t song_size_get_length(const struct song_size *size) { - assert(size != NULL); - return size->name_len + size->genre_len + 6*4; -} - -inline int song_size_max(struct song_size *s, const struct song_entry *e) { - assert(s != NULL); - assert(e != NULL); - assert(FLAG_VALID(e->flag)); - s->name_len = ( s->name_len >= e->size.name_len ? s->name_len : e->size.name_len ); - s->genre_len = ( s->genre_len >= e->size.genre_len ? s->genre_len : e->size.genre_len ); - return ERR_NONE; -} - -int song_size_destruct(struct song_size *s) { - assert(s != NULL); - // nothing to do... - free(s); - return ERR_NONE; -} -#endif diff --git a/apps/tagdb/song.h b/apps/tagdb/song.h deleted file mode 100644 index ac155b4..0000000 --- a/apps/tagdb/song.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifdef HAVE_TAGCACHE -#ifndef __SONG_H__ -#define __SONG_H__ - -#include "config.h" -#include <stdio.h> -#include <stdint.h> - -struct song_entry { - char* name; // song name - - uint32_t artist; // pointer to artist - uint32_t album; // pointer to album - uint32_t file; // pointer to file - - char* genre; // genre - - uint16_t bitrate; // bitrate (-1 = VBR or unknown) - uint16_t year; - uint32_t playtime; // in seconds - uint16_t track; - uint16_t samplerate; // in Hz - - struct song_size { - uint32_t name_len; // must be mulitple of 4 - uint32_t genre_len; // must be multiple of 4 - } size; - unsigned char flag; // flags -}; - -struct song_entry* new_song_entry(const uint32_t name_len, const uint32_t genre_len); -/* Creates a new song_entry with the specified sizes - * Returns a pointer to the structure on success, - * NULL on failure - */ - -int song_entry_destruct(struct song_entry *e); -/* Destructs the given song_entry and free()'s it's memory - * returns 0 on success, 1 on failure - */ - -inline int song_entry_resize(struct song_entry *e, const uint32_t name_len, const uint32_t genre_len); -/* Change the size of the entry - * returns 0 on succes, 1 on failure - */ - -int song_entry_serialize(FILE *fd, const struct song_entry *e); -/* Serializes the entry in the file at the current position - * returns 0 on success, 1 on failure - */ - -int song_entry_unserialize(struct song_entry* *e, FILE *fd); -/* Unserializes an entry from file into a new structure - * The address of the structure is saved into *e - * returns 0 on success - * 1 on malloc() failure - * 2 on fread() failure - */ - -int song_entry_write(FILE *fd, struct song_entry *e, struct song_size *s); -/* Writes the entry to file in the final form - * returns 0 (0) on success, 1 (1) on failure - */ - -inline int song_entry_compare(const struct song_entry *a, const struct song_entry *b); -/* Compares 2 entries - * When a < b it returns <0 - * a = b 0 - * a > b >0 - */ - -struct song_size* new_song_size(); -/* Creates a new size structure - * returns a pointer to the structure on success, - * NULL on failure - */ - -inline uint32_t song_size_get_length(const struct song_size *size); -/* Calculates the length of the entry when written by song_entry_write() - * returns the length on success, 0xffffffff on failure - */ - -inline int song_size_max(struct song_size *s, const struct song_entry *e); -/* Updates the song_size structure to contain the maximal lengths of either - * the original entry in s, or the entry e - * returns 0 on success, 1 on failure - */ - -int song_size_destruct(struct song_size *s); -/* destructs the song_size structure - * returns 0 on success, 1 on failure - */ - -#endif -#endif diff --git a/apps/tagdb/tag_dummy.c b/apps/tagdb/tag_dummy.c deleted file mode 100644 index 4318724..0000000 --- a/apps/tagdb/tag_dummy.c +++ /dev/null @@ -1,13 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "config.h" -#include "malloc.h" - -#include "tag_dummy.h" -#include <string.h> - -int tag_dummy(char *file, struct tag_info *t) { - t->song = malloc(strlen(file)+1); - strcpy(t->song, file); - return ERR_NONE; -} -#endif diff --git a/apps/tagdb/tag_dummy.h b/apps/tagdb/tag_dummy.h deleted file mode 100644 index e05595a..0000000 --- a/apps/tagdb/tag_dummy.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "db.h" - -int tag_dummy(char *file, struct tag_info *t); -#endif diff --git a/apps/tagdb/unique.c b/apps/tagdb/unique.c deleted file mode 100644 index 3fd4359..0000000 --- a/apps/tagdb/unique.c +++ /dev/null @@ -1,18 +0,0 @@ -#ifdef HAVE_TAGCACHE -#include "unique.h" - -#include <string.h> -#include <stdio.h> - -char *create_unique_name(char *buffer, const char *prefix, const char *suffix, int digits) { - static unsigned long i=0; - - strcpy(buffer, prefix); - sprintf(buffer+strlen(prefix), "%05lu", i); - strcat(buffer, suffix); - - i++; - - return buffer; -} -#endif diff --git a/apps/tagdb/unique.h b/apps/tagdb/unique.h deleted file mode 100644 index bd5ebd8..0000000 --- a/apps/tagdb/unique.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef -#ifndef __UNIQUE_H__ -#define __UNIQUE_H__ - -char *create_unique_name(char *buffer, const char *prefix, const char *suffix, int digits); - -#endif -#endif |