comparison src/xs_length.c @ 392:b09d74eb71e6

Working on getting STIL and SLDB using completely dynamically allocated structures. Indentation cleanups, etc.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 31 May 2006 10:02:00 +0000
parents 3c239e4160d5
children f997b79a7251
comparison
equal deleted inserted replaced
391:3cc7455360ad 392:b09d74eb71e6
27 #include <stdlib.h> 27 #include <stdlib.h>
28 #include <ctype.h> 28 #include <ctype.h>
29 #include <string.h> 29 #include <string.h>
30 30
31 31
32 /* Database handling functions 32 /* Free memory allocated for given SLDB node
33 */ 33 */
34 static t_xs_sldb_node *xs_sldb_node_new(void) 34 static void xs_sldb_node_free(t_xs_sldb_node *pNode)
35 {
36 t_xs_sldb_node *pResult;
37
38 /* Allocate memory for new node */
39 pResult = (t_xs_sldb_node *) g_malloc0(sizeof(t_xs_sldb_node));
40 if (!pResult)
41 return NULL;
42
43 return pResult;
44 }
45
46
47 static void xs_sldb_node_free(t_xs_sldb_node * pNode)
48 { 35 {
49 if (pNode) { 36 if (pNode) {
50 /* Nothing much to do here ... */ 37 /* Nothing much to do here ... */
38 g_free(pNode->sLengths);
51 g_free(pNode); 39 g_free(pNode);
52 } 40 }
53 } 41 }
54 42
55 43
56 /* Insert given node to db linked list 44 /* Insert given node to db linked list
57 */ 45 */
58 static void xs_sldb_node_insert(t_xs_sldb * db, t_xs_sldb_node * pNode) 46 static void xs_sldb_node_insert(t_xs_sldb *db, t_xs_sldb_node *pNode)
59 { 47 {
60 assert(db); 48 assert(db);
61 49
62 if (db->pNodes) { 50 if (db->pNodes) {
63 /* The first node's pPrev points to last node */ 51 /* The first node's pPrev points to last node */
71 LNEXT = NULL; /* But next is NULL! */ 59 LNEXT = NULL; /* But next is NULL! */
72 } 60 }
73 } 61 }
74 62
75 63
76 /* Parses a time-entry in SLDB format 64 /* Parse a time-entry in SLDB format
77 */ 65 */
78 static gint xs_sldb_gettime(gchar * pcStr, size_t * piPos) 66 static gint xs_sldb_gettime(gchar *pcStr, gint *piPos)
79 { 67 {
80 gint iResult, iTemp; 68 gint iResult, iTemp;
81 69
82 /* Check if it starts with a digit */ 70 /* Check if it starts with a digit */
83 if (isdigit(pcStr[*piPos])) { 71 if (isdigit(pcStr[*piPos])) {
109 97
110 return iResult; 98 return iResult;
111 } 99 }
112 100
113 101
102 /* Parse one SLDB definition line, return SLDB node
103 */
114 t_xs_sldb_node * xs_sldb_read_entry(gchar *inLine) 104 t_xs_sldb_node * xs_sldb_read_entry(gchar *inLine)
115 { 105 {
116 size_t linePos, savePos, tmpI, tmpLen; 106 gint linePos, savePos, i, tmpLen;
107 gboolean iOK;
117 t_xs_sldb_node *tmpNode; 108 t_xs_sldb_node *tmpNode;
118 109
119 /* Allocate new node */ 110 /* Allocate new node */
120 if ((tmpNode = xs_sldb_node_new()) == NULL) { 111 tmpNode = (t_xs_sldb_node *) g_malloc0(sizeof(t_xs_sldb_node));
121 XSERR("Error allocating new node. Fatal error.\n"); 112 if (!tmpNode) {
113 xs_error("Error allocating new node. Fatal error.\n");
122 return NULL; 114 return NULL;
123 } 115 }
124 116
125 /* Get hash value */ 117 /* Get hash value */
126 #if (XS_MD5HASH_LENGTH != 16) 118 linePos = 0;
127 #error Mismatch in hashcode length. Check against xs_md5.h and fix here. 119 for (i = 0; i < XS_MD5HASH_LENGTH; i++, linePos += 2) {
128 #endif 120 sscanf(&inLine[linePos], "%2x",
129 sscanf(&inLine[0], "%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 121 (guint *) &(tmpNode->md5Hash[i]));
130 (guint *) & (tmpNode->md5Hash[0]), (guint *) & (tmpNode->md5Hash[1]), 122 }
131 (guint *) & (tmpNode->md5Hash[2]), (guint *) & (tmpNode->md5Hash[3]), 123
132 (guint *) & (tmpNode->md5Hash[4]), (guint *) & (tmpNode->md5Hash[5]),
133 (guint *) & (tmpNode->md5Hash[6]), (guint *) & (tmpNode->md5Hash[7]),
134 (guint *) & (tmpNode->md5Hash[8]), (guint *) & (tmpNode->md5Hash[9]),
135 (guint *) & (tmpNode->md5Hash[10]), (guint *) & (tmpNode->md5Hash[11]),
136 (guint *) & (tmpNode->md5Hash[12]), (guint *) & (tmpNode->md5Hash[13]),
137 (guint *) & (tmpNode->md5Hash[14]), (guint *) & (tmpNode->md5Hash[15]));
138
139 /* Get playtimes */ 124 /* Get playtimes */
140 if (inLine[linePos] != 0) { 125 if (inLine[linePos] != 0) {
141 if (inLine[linePos] != '=') { 126 if (inLine[linePos] != '=') {
142 XSERR("'=' expected in SongLengthDB file '%s' line #%d, column #%d\n", 127 xs_error("'=' expected on column #%d.\n", linePos);
143 dbFilename, lineNum, linePos);
144
145 xs_sldb_node_free(tmpNode); 128 xs_sldb_node_free(tmpNode);
146 return NULL; 129 return NULL;
147 } else { 130 } else {
148 /* First playtime is after '=' */ 131 /* First playtime is after '=' */
149 savePos = ++linePos; 132 savePos = ++linePos;
158 else 141 else
159 iOK = FALSE; 142 iOK = FALSE;
160 } 143 }
161 144
162 if (!iOK) { 145 if (!iOK) {
163 XSERR("Invalid plaaplaa\n"); 146 xs_error("Invalid sub-tune length.\n");
164 xs_sldb_node_free(tmpNode); 147 xs_sldb_node_free(tmpNode);
165 return NULL; 148 return NULL;
166 } 149 }
167 150
168 /* Allocate memory for lengths */ 151 /* Allocate memory for lengths */
169 tmpNode->sLengths = (gint *) g_malloc0(tmpNode->nLengths * sizeof(gint)); 152 tmpNode->sLengths = (gint *) g_malloc0(tmpNode->nLengths * sizeof(gint));
170 if (!tmpNode->sLengths) { 153 if (!tmpNode->sLengths) {
171 XSERR("Could not allocate memory for SongLengthDB entry.\n"); 154 xs_error("Could not allocate memory for node.\n");
172 xs_sldb_node_free(tmpNode); 155 xs_sldb_node_free(tmpNode);
173 return NULL; 156 return NULL;
174 } 157 }
175 158
176 /* Read lengths in */ 159 /* Read lengths in */
177 tmpI = 0; linePos = savePos; iOK = TRUE; 160 i = 0;
161 linePos = savePos;
162 iOK = TRUE;
178 while ((linePos < tmpLen) && iOK) { 163 while ((linePos < tmpLen) && iOK) {
179 xs_findnext(inLine, &linePos); 164 xs_findnext(inLine, &linePos);
180 165
181 if (tmpI < tmpNode->nLengths) { 166 if (i < tmpNode->nLengths) {
182 tmpNode->sLengths[tmpI] = xs_sldb_gettime(inLine, &linePos); 167 tmpNode->sLengths[i] = xs_sldb_gettime(inLine, &linePos);
183 tmpI++; 168 i++;
184 } else 169 } else
185 iOK = FALSE; 170 iOK = FALSE;
186 } 171 }
187 172
188 if (!iOK) { 173 if (!iOK) {
197 } 182 }
198 183
199 184
200 /* Read database to memory 185 /* Read database to memory
201 */ 186 */
202 gint xs_sldb_read(t_xs_sldb * db, gchar * dbFilename) 187 gint xs_sldb_read(t_xs_sldb *db, gchar *dbFilename)
203 { 188 {
204 FILE *inFile; 189 FILE *inFile;
205 gchar inLine[XS_BUF_SIZE]; 190 gchar inLine[XS_BUF_SIZE];
206 size_t lineNum, linePos; 191 gint lineNum;
207 gboolean iOK;
208 t_xs_sldb_node *tmpNode; 192 t_xs_sldb_node *tmpNode;
209 assert(db); 193 assert(db);
210 194
211 /* Try to open the file */ 195 /* Try to open the file */
212 if ((inFile = fopen(dbFilename, "ra")) == NULL) { 196 if ((inFile = fopen(dbFilename, "ra")) == NULL) {
213 XSERR("Could not open SongLengthDB '%s'\n", dbFilename); 197 xs_error("Could not open SongLengthDB '%s'\n", dbFilename);
214 return -1; 198 return -1;
215 } 199 }
216 200
217 /* Read and parse the data */ 201 /* Read and parse the data */
218 lineNum = 0; 202 lineNum = 0;
219 203
220 while (!feof(inFile)) { 204 while (!feof(inFile)) {
205 gint linePos;
221 fgets(inLine, XS_BUF_SIZE, inFile); 206 fgets(inLine, XS_BUF_SIZE, inFile);
222 inLine[XS_BUF_SIZE - 1] = 0; 207 inLine[XS_BUF_SIZE - 1] = 0;
223 linePos = 0; 208 linePos = 0;
224 lineNum++; 209 lineNum++;
225 210
226 /* Check if it is datafield */ 211 /* Check if it is datafield */
227 if (isxdigit(inLine[linePos])) { 212 if (isxdigit(inLine[linePos])) {
228 size_t tmpI;
229
230 /* Check the length of the hash */ 213 /* Check the length of the hash */
231 for (tmpI = 0; isxdigit(inLine[linePos]); linePos++, tmpI++); 214 gint hashLen;
232 215 for (hashLen = 0; isxdigit(inLine[linePos]); hashLen++, linePos++);
233 if (tmpI != XS_MD5HASH_LENGTH_CH) { 216
234 XSERR("Invalid hash in SongLengthDB file '%s' line #%d!\n", dbFilename, lineNum); 217 if (hashLen != XS_MD5HASH_LENGTH_CH) {
218 xs_error("Invalid MD5-hash in SongLengthDB file '%s' line #%d!\n",
219 dbFilename, lineNum);
235 } else { 220 } else {
236 /* Parse and add node to db */ 221 /* Parse and add node to db */
237 if ((tmpNode = xs_sldb_read_entry(inLine)) != NULL) 222 if ((tmpNode = xs_sldb_read_entry(inLine)) != NULL) {
238 xs_sldb_node_insert(db, tmpNode); 223 xs_sldb_node_insert(db, tmpNode);
224 } else {
225 xs_error("Invalid entry in SongLengthDB file '%s' line #%d!\n",
226 dbFilename, lineNum);
227 }
239 } 228 }
240 } else if ((inLine[0] != ';') && (inLine[0] != '[')) { 229 } else if ((inLine[linePos] != ';') && (inLine[linePos] != '[')) {
241 XSERR("Invalid line in SongLengthDB file '%s' line #%d\n", dbFilename, lineNum); 230 xs_error("Invalid line in SongLengthDB file '%s' line #%d\n",
231 dbFilename, lineNum);
242 } 232 }
243 233
244 } 234 }
245 235
246 /* Close the file */ 236 /* Close the file */
255 * negative if testHash1 < testHash2 245 * negative if testHash1 < testHash2
256 * positive if testHash1 > testHash2 246 * positive if testHash1 > testHash2
257 */ 247 */
258 static gint xs_sldb_cmphash(t_xs_md5hash testHash1, t_xs_md5hash testHash2) 248 static gint xs_sldb_cmphash(t_xs_md5hash testHash1, t_xs_md5hash testHash2)
259 { 249 {
260 register gint i, res = 0; 250 gint i, d;
261 251
262 /* Compute difference of hashes */ 252 /* Compute difference of hashes */
263 for (i = 0; (i < XS_MD5HASH_LENGTH) && (!res); i++) 253 for (i = 0, d = 0; (i < XS_MD5HASH_LENGTH) && !d; i++)
264 res = (testHash1[i] - testHash2[i]); 254 d = (testHash1[i] - testHash2[i]);
265 255
266 return res; 256 return d;
267 } 257 }
268 258
269 259
270 /* Get node from db index via binary search 260 /* Get node from db index via binary search
271 */ 261 */
443 { 433 {
444 FILE *inFile; 434 FILE *inFile;
445 t_xs_md5state inState; 435 t_xs_md5state inState;
446 t_xs_psidv1_header psidH; 436 t_xs_psidv1_header psidH;
447 t_xs_psidv2_header psidH2; 437 t_xs_psidv2_header psidH2;
448 #ifdef XS_BUF_DYNAMIC
449 guint8 *songData; 438 guint8 *songData;
450 #else
451 guint8 songData[XS_SIDBUF_SIZE];
452 #endif
453 guint8 ib8[2], i8; 439 guint8 ib8[2], i8;
454 gint iIndex, iRes; 440 gint iIndex, iRes;
455 441
456 /* Try to open the file */ 442 /* Try to open the file */
457 if ((inFile = fopen(pcFilename, "rb")) == NULL) 443 if ((inFile = fopen(pcFilename, "rb")) == NULL)
485 psidH2.startPage = fgetc(inFile); 471 psidH2.startPage = fgetc(inFile);
486 psidH2.pageLength = fgetc(inFile); 472 psidH2.pageLength = fgetc(inFile);
487 psidH2.reserved = xs_rd_be16(inFile); 473 psidH2.reserved = xs_rd_be16(inFile);
488 } 474 }
489 475
490 #ifdef XS_BUF_DYNAMIC
491 /* Allocate buffer */ 476 /* Allocate buffer */
492 songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE * sizeof(guint8)); 477 songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE * sizeof(guint8));
493 if (!songData) { 478 if (!songData) {
494 fclose(inFile); 479 fclose(inFile);
495 return -3; 480 return -3;
496 } 481 }
497 #endif
498 482
499 /* Read data to buffer */ 483 /* Read data to buffer */
500 iRes = fread(songData, sizeof(guint8), XS_SIDBUF_SIZE, inFile); 484 iRes = fread(songData, sizeof(guint8), XS_SIDBUF_SIZE, inFile);
501 fclose(inFile); 485 fclose(inFile);
502 486
509 } else { 493 } else {
510 /* Append "as is" */ 494 /* Append "as is" */
511 xs_md5_append(&inState, songData, iRes); 495 xs_md5_append(&inState, songData, iRes);
512 } 496 }
513 497
514 #ifdef XS_BUF_DYNAMIC
515 /* Free buffer */ 498 /* Free buffer */
516 g_free(songData); 499 g_free(songData);
517 #endif
518 500
519 /* Append header data to hash */ 501 /* Append header data to hash */
520 #define XSADDHASH(QDATAB) { ib8[0] = (QDATAB & 0xff); ib8[1] = (QDATAB >> 8); xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); } 502 #define XSADDHASH(QDATAB) { ib8[0] = (QDATAB & 0xff); ib8[1] = (QDATAB >> 8); xs_md5_append(&inState, (guint8 *) &ib8, sizeof(ib8)); }
521 503
522 XSADDHASH(psidH.initAddress) 504 XSADDHASH(psidH.initAddress)
551 } 533 }
552 534
553 535
554 /* Get song lengths 536 /* Get song lengths
555 */ 537 */
556 t_xs_sldb_node *xs_sldb_get(t_xs_sldb * db, gchar * pcFilename) 538 t_xs_sldb_node *xs_sldb_get(t_xs_sldb *db, gchar *pcFilename)
557 { 539 {
558 t_xs_sldb_node *pResult; 540 t_xs_sldb_node *pResult;
559 t_xs_md5hash dbHash; 541 t_xs_md5hash dbHash;
560 542
561 /* Get the hash and then look up from db */ 543 /* Get the hash and then look up from db */