changeset 94:086681f70910

Start of re-write of STIL-support
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 10 Jan 2004 22:53:00 +0000
parents 63cf9b2ddadf
children 4e929bb71057
files src/xs_stil.c src/xs_stil.h
diffstat 2 files changed, 301 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/xs_stil.c	Sat Jan 10 12:44:00 2004 +0000
+++ b/src/xs_stil.c	Sat Jan 10 22:53:00 2004 +0000
@@ -21,6 +21,296 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
-#include "xmms-sid.h"
-#include <glib.h>
+#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_db_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_db_node_free(t_xs_stil_node *pNode)
+{
+ 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_db_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! */
+ 	}
+}
+
+
+/*
+ * Compare two given MD5-hashes.
+ * Return: 0 if equal
+ *         negative if testHash1 < testHash2
+ *         positive if testHash1 > testHash2
+ */
+gint xs_db_cmphash(t_xs_md5hash testHash1, t_xs_md5hash testHash2)
+{
+ register gint i, res = 0;
+  
+ /* Compute difference of hashes */
+ for (i = 0; (i < XS_MD5HASH_LENGTH) && (!res); i++)
+ 	res = (testHash1[i] - testHash2[i]);
+
+ return res;
+}
+
+
+/*
+ * Get song length from database
+ */
+t_xs_stil_node * xs_db_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 = xs_db_cmphash(pHash, xs_stildbi[iQNode]->md5Hash);
+ 	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 (xs_db_cmphash(pHash, xs_stildbi[i]->md5Hash) == 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_db_cmp(const void *pNode1, const void *pNode2)
+{
+ /* We assume here that we never ever get NULL-pointers or similar */
+ return xs_db_cmphash((*(t_xs_stil_node **) pNode1)->md5Hash,
+                      (*(t_xs_stil_node **) pNode2)->md5Hash);
+}
+
+
+/*
+ * Initialize the song-length system
+ */
+gint xs_songlen_init(void)
+{
+ t_xs_stil_node *pCurr;
+ gint i;
+
+XSDEBUG("stildb_init()\n");
+ 
+ /* Read the database */
+ if (!xs_cfg.songlenDBPath)
+ 	return -10;
+
+ if (xs_db_read(xs_cfg.songlenDBPath) < 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_db_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_db_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;
+}
--- a/src/xs_stil.h	Sat Jan 10 12:44:00 2004 +0000
+++ b/src/xs_stil.h	Sat Jan 10 22:53:00 2004 +0000
@@ -11,13 +11,17 @@
  * Defines and typedefs
  */
 typedef struct {
-	
+	gchar	*pName,
+		*pTitle,
+		*pArtist,
+		*pComment;
 } t_xs_stil_subnode;
 
 typedef struct _t_xs_stil_node {
-
-	t_xs_stil_subnode	subTuneInfo[XS_STIL_MAXENTRY];
-	struct _t_xs_stil_node *pPrev, *pNext;
+	gchar			*pcFilename;
+	gint			nsubTunes;
+	t_xs_stil_subnode	subTune[XS_STIL_MAXENTRY];
+	struct _t_xs_stil_node	*pPrev, *pNext;
 } t_xs_stil_node;
 
 
@@ -26,7 +30,7 @@
  */
 gint	xs_stil_init(void);		/* Initialize STIL subsystem */
 void	xs_stil_close(void);		/* Close/shutdown */
-gint32	xs_stil_get(gchar *);		/* Get STIL information */
+t_xs_stil_node*	xs_stil_get(gchar *);	/* Get STIL information */
 
 
 #ifdef __cplusplus