Mercurial > hg > xmms-sid
view src/xs_stil.c @ 99:2bc56809ec0b
STIL-support fixes, variable renaming
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 10 Jan 2004 23:51:04 +0000 |
parents | 086681f70910 |
children | 4614f58ab169 |
line wrap: on
line source
/* xmms-sid - SIDPlay input plugin for X MultiMedia System (XMMS) STIL-database parsing functions Mostly written by Matti "ccr" Hamalainen <ccr@tnsp.org>, some parts written by Willem Monsuwe <willem@stack.nl> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "xs_stil.h" #include "xs_support.h" #include "xs_config.h" #include <stdlib.h> #include <stdio.h> #include <ctype.h> #include <string.h> /* * Pointer to database in memory */ static t_xs_stil_node *xs_stildb = NULL; static t_xs_stil_node **xs_stildbi = NULL; static gint xs_stildbn = 0; /* * Hash-database handling functions */ t_xs_stil_node *xs_stildb_node_new(void) { t_xs_stil_node *pResult; /* Allocate memory for new node */ pResult = (t_xs_stil_node *) g_malloc0(sizeof(t_xs_stil_node)); if (!pResult) return NULL; return pResult; } void xs_stildb_node_free(t_xs_stil_node *pNode) { gint i; if (pNode) { for (i = 0; i < pNode->nsubTunes; i++) { g_free(pNode->subTune[i].pName); g_free(pNode->subTune[i].pTitle); g_free(pNode->subTune[i].pArtist); g_free(pNode->subTune[i].pComment); } g_free(pNode->pcFilename); g_free(pNode); } } /* * Insert given node to db linked list */ #define LPREV (pNode->pPrev) #define LTHIS (pNode) #define LNEXT (pNode->pNext) void xs_stildb_node_insert(t_xs_stil_node *pNode) { if (xs_stildb) { /* The first node's pPrev points to last node */ LPREV = xs_stildb->pPrev; /* New node's prev = Previous last node */ xs_stildb->pPrev->pNext = pNode; /* Previous last node's next = New node */ xs_stildb->pPrev = pNode; /* New last node = New node */ LNEXT = NULL; /* But next is NULL! */ } else { xs_stildb = pNode; /* First node ... */ LPREV = pNode; /* ... it's also last */ LNEXT = NULL; /* But next is NULL! */ } } /* * Get STIL information from database */ t_xs_stil_node * xs_stildb_get(gchar *pcFilename) { gint iStartNode, iEndNode, iQNode, r, i; gboolean iFound; t_xs_stil_node *pResult; /* Check the database pointers */ if (!xs_stildb || !xs_stildbi) return NULL; /* Look-up via index using binary search */ pResult = NULL; iStartNode = 0; iEndNode = (xs_stildbn - 1); iQNode = (iEndNode / 2); iFound = FALSE; while ((!iFound) && ((iEndNode - iStartNode) > 128)) { r = strcmp(pcFilename, xs_stildbi[iQNode]->pcFilename); if (r < 0) { /* Hash was in the <- LEFT side */ iEndNode = iQNode; iQNode = iStartNode + ((iEndNode - iStartNode) / 2); } else if (r > 0) { /* Hash was in the RIGHT -> side */ iStartNode = iQNode; iQNode = iStartNode + ((iEndNode - iStartNode) / 2); } else iFound = TRUE; } /* If not found already */ if (!iFound) { /* Search the are linearly */ iFound = FALSE; i = iStartNode; while ((i <= iEndNode) && (!iFound)) { if (strcmp(pcFilename, xs_stildbi[iQNode]->pcFilename) == 0) iFound = TRUE; else i++; } /* Check the result */ if (iFound) pResult = xs_stildbi[i]; } else { /* Found via binary search */ pResult = xs_stildbi[iQNode]; } return pResult; } /* * Read database to memory */ gint xs_stildb_read(gchar *dbFilename) { FILE *inFile; gchar inLine[XS_BUFSIZE]; guint lineNum, linePos; gboolean iOK; t_xs_stil_node *tmpNode; /* Try to open the file */ if ((inFile = fopen(dbFilename, "ra")) == NULL) { XSERR("Could not open STILDB '%s'\n", dbFilename); return -1; } /* Read and parse the data */ lineNum = 0; while (!feof(inFile)) { fgets(inLine, sizeof(inLine), inFile); lineNum++; } /* while */ /* Close the file */ fclose(inFile); return 0; } /* * Compare two nodes' hashes */ gint xs_stildb_cmp(const void *pNode1, const void *pNode2) { /* We assume here that we never ever get NULL-pointers or similar */ return strcmp((*(t_xs_stil_node **) pNode1)->pcFilename, (*(t_xs_stil_node **) pNode2)->pcFilename); } /* * Initialize the song-length system */ gint xs_stil_init(void) { t_xs_stil_node *pCurr; gint i; XSDEBUG("stil_init()\n"); /* Read the database */ if (!xs_cfg.stilDBPath) return -10; if (xs_stildb_read(xs_cfg.stilDBPath) < 0) return -9; XSDEBUG("indexing...\n"); /* Get size of db */ pCurr = xs_stildb; xs_stildbn = 0; while (pCurr) { xs_stildbn++; pCurr = pCurr->pNext; } /* Check number of nodes */ if (xs_stildbn > 0) { /* Allocate memory for index-table */ xs_stildbi = (t_xs_stil_node **) g_malloc(sizeof(t_xs_stil_node *) * xs_stildbn); if (!xs_stildbi) return -6; /* Get node-pointers to table */ i = 0; pCurr = xs_stildb; while (pCurr) { xs_stildbi[i++] = pCurr; pCurr = pCurr->pNext; } /* Sort the indexes */ qsort(xs_stildbi, xs_stildbn, sizeof(t_xs_stil_node *), xs_stildb_cmp); } /* OK */ XSDEBUG("init ok.\n"); return 0; } /* * Close song-length system */ void xs_stil_close(void) { t_xs_stil_node *pCurr, *pNext; /* Free the memory allocated for database */ XSDEBUG("stildb_close()\n"); pCurr = xs_stildb; while (pCurr) { pNext = pCurr->pNext; xs_stildb_node_free(pCurr); pCurr = pNext; } xs_stildb = NULL; /* Free memory allocated for indexes */ if (xs_stildbi) { g_free(xs_stildbi); xs_stildbi = NULL; } } /* * Get STIL information */ t_xs_stil_node * xs_stil_get(gchar *pcFilename) { t_xs_stil_node *pResult; return pResult; }