summaryrefslogtreecommitdiff
path: root/sid/sidplay-libs-2.1.0/libsidutils/src/SidDatabase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sid/sidplay-libs-2.1.0/libsidutils/src/SidDatabase.cpp')
-rw-r--r--sid/sidplay-libs-2.1.0/libsidutils/src/SidDatabase.cpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/sid/sidplay-libs-2.1.0/libsidutils/src/SidDatabase.cpp b/sid/sidplay-libs-2.1.0/libsidutils/src/SidDatabase.cpp
new file mode 100644
index 00000000..20dd20b3
--- /dev/null
+++ b/sid/sidplay-libs-2.1.0/libsidutils/src/SidDatabase.cpp
@@ -0,0 +1,182 @@
+/***************************************************************************
+ dbget.cpp - Get time from database
+ -------------------
+ begin : Fri Jun 2 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "SidDatabase.h"
+#include "MD5/MD5.h"
+
+const char *SidDatabase::ERR_DATABASE_CORRUPT = "SID DATABASE ERROR: Database seems to be corrupt.";
+const char *SidDatabase::ERR_NO_DATABASE_LOADED = "SID DATABASE ERROR: Songlength database not loaded.";
+const char *SidDatabase::ERR_NO_SELECTED_SONG = "SID DATABASE ERROR: No song selected for retrieving song length.";
+const char *SidDatabase::ERR_MEM_ALLOC = "SID DATABASE ERROR: Memory Allocation Failure.";
+const char *SidDatabase::ERR_UNABLE_TO_LOAD_DATABASE = "SID DATABASE ERROR: Unable to load the songlegnth database.";
+
+
+SidDatabase::~SidDatabase ()
+{
+ close ();
+}
+
+
+int_least32_t SidDatabase::parseTimeStamp(const char* arg)
+{
+ /* Read in m:s format at most.
+ * Could use a system function if available.
+ */
+ int_least32_t seconds = 0;
+ int passes = 2; // minutes, seconds
+ bool gotDigits = false;
+ while ( passes-- )
+ {
+ if ( isdigit(*arg) )
+ {
+ int t = atoi(arg);
+ seconds += t;
+ gotDigits = true;
+ }
+ while ( *arg && isdigit(*arg) )
+ {
+ ++arg;
+ }
+ if ( *arg && *arg==':' )
+ {
+ seconds *= 60;
+ ++arg;
+ }
+ }
+
+ // Handle -:-- time stamps and old 0:00 entries which
+ // need to be rounded up by one second.
+ if ( !gotDigits )
+ seconds = 0;
+ else if ( seconds==0 )
+ ++seconds;
+
+ return seconds;
+}
+
+
+uint_least8_t SidDatabase::timesFound (char *str)
+{
+ /* Try and determine the number of times read back.
+ * Used to check validility of times in database.
+ */
+ uint_least8_t count = 0;
+ while (*str)
+ {
+ if (*str++ == ':')
+ count++;
+ }
+ return count;
+}
+
+
+int SidDatabase::open (const char *filename)
+{
+ close ();
+ // @FIXME@: Libini should be changed
+ database = ini_open ((char *) filename, "r", ";");
+ if (!database)
+ {
+ errorString = ERR_UNABLE_TO_LOAD_DATABASE;
+ return -1;
+ }
+
+ return 0;
+}
+
+void SidDatabase::close ()
+{
+ if (database)
+ ini_close (database);
+}
+
+int_least32_t SidDatabase::length (SidTuneMod &tune)
+{
+ SidTuneInfo tuneInfo;
+ int_least32_t time = 0;
+ char timeStamp[10];
+ MD5 myMD5;
+ char digest[33];
+ uint_least16_t selectedSong = 0;
+
+ if (!database)
+ {
+ errorString = ERR_NO_DATABASE_LOADED;
+ return -1;
+ }
+
+ tune.getInfo(tuneInfo);
+ selectedSong = tuneInfo.currentSong;
+ if (!selectedSong)
+ {
+ errorString = ERR_NO_SELECTED_SONG;
+ return -1;
+ }
+
+ // Restart fingerprint
+ myMD5.reset();
+ tune.createMD5(myMD5);
+ myMD5.finish();
+
+ // Construct fingerprint.
+ digest[0] = '\0';
+ for (int di = 0; di < 16; ++di)
+ sprintf (digest, "%s%02x", digest, (int) myMD5.getDigest()[di]);
+
+
+ // Now set up array access
+ if (ini_listDelims (database, " ") == -1)
+ {
+ errorString = ERR_MEM_ALLOC;
+ return -1;
+ }
+
+ // Read Time (and check times before hand)
+ (void) ini_locateHeading (database, "Database");
+ (void) ini_locateKey (database, digest);
+ // If length return is -1 then no entry found in database
+ if (ini_dataLength (database) != -1)
+ {
+ selectedSong = 0;
+ while (selectedSong < tuneInfo.currentSong)
+ {
+ selectedSong++;
+ if (ini_readString (database, timeStamp, sizeof (timeStamp)) == -1)
+ { // No time found
+ errorString = ERR_DATABASE_CORRUPT;
+ return -1;
+ }
+
+ // Validate Time
+ if (timesFound (timeStamp) != 1)
+ {
+ errorString = ERR_DATABASE_CORRUPT;
+ return -1;
+ }
+ }
+
+ // Parse timestamp
+ time = parseTimeStamp (timeStamp);
+ }
+
+ return time;
+}