diff remap.c @ 96:2fcb4f228308 src

Adding "Personalizing DVD Viewing" files from <kevin_smathers@hp.com> Not yet enabled. Will be enabled soon.
author jcdutton
date Tue, 17 Sep 2002 10:47:02 +0000
parents
children b6834e6359cf
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/remap.c	Tue Sep 17 10:47:02 2002 +0000
@@ -0,0 +1,225 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/fcntl.h>
+#include <assert.h>
+#include "remap.h"
+
+struct block_s {
+    int domain;
+    int title;
+    int program;
+    unsigned long start_block;
+    unsigned long end_block;
+};
+
+struct remap_s {
+    char *title;
+    int maxblocks;
+    int nblocks;
+    int debug;
+    struct block_s *blocks;
+};
+
+remap_t* remap_new( char *title) {
+    remap_t *map = malloc( sizeof(remap_t));
+    map->title = strdup(title);
+    map->maxblocks = 0;
+    map->nblocks = 0;
+    map->blocks = NULL;
+    map->debug = 0;
+    return map;
+}
+
+static int compare_block( block_t *a, block_t *b) {
+    /* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */
+    if (a->domain < b->domain) {
+	return -1;
+    } else if (a->domain > b->domain) {
+	return 1;
+    }
+
+    if (a->title < b->title) {
+	return -1;
+    } else if (a->title > b->title) {
+	return 1;
+    }
+
+    if (a->program < b->program) {
+	return -1;
+    } else if (a->program > b->program) {
+	return 1;
+    }
+
+    if (a->end_block < b->start_block) {
+	return -1;
+    } else if (a->start_block > b->end_block) {
+	/*
+	 * if a->start_block == b->end_block then the two regions
+	 * aren't strictly overlapping, but they should be merged 
+	 * anyway since there are zero blocks between them
+	 */
+	return 1;
+    }
+
+    return 0;
+}
+
+static block_t *findblock( remap_t *map, block_t *key) {
+    int lb = 0;
+    int ub = map->nblocks - 1;
+    int mid;
+    int res;
+
+    while (lb <= ub) {
+	mid = lb + (ub - lb)/2;
+	res = compare_block( key, &map->blocks[mid]);
+	if (res < 0) {
+	    ub = mid-1;
+	} else if (res > 0) {
+	    lb = mid+1;
+	} else {
+	    return &map->blocks[mid];
+	}
+    }
+    return NULL;
+}
+
+static void mergeblock( block_t *b, block_t tmp) {
+    if (tmp.start_block < b->start_block) b->start_block = tmp.start_block;
+    if (tmp.end_block > b->end_block) b->end_block = tmp.end_block;
+}
+
+static void remap_add_node( remap_t *map, block_t block) {
+    block_t *b;
+    int n;
+    b = findblock( map, &block);
+    if (b) {
+	/* overlaps an existing block */
+	mergeblock( b, block);
+    } else {
+        /* new block */
+	if (map->nblocks >= map->maxblocks) {
+	    map->maxblocks += 20;
+	    map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks);
+	}
+	n = map->nblocks++;
+	while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {
+	    map->blocks[ n] = map->blocks[ n-1];
+	    n--;
+	}
+	map->blocks[ n] = block;
+    }
+}
+
+int parseblock( 
+	char *buf, int *dom, int *tt, int *pg, 
+	unsigned long *start, unsigned long *end) 
+{
+    long tmp;
+    char *tok;
+    char *epos;
+    char *marker[]={"domain", "title", "program", "start", "end"};
+    int st = 0;
+    tok = strtok( buf, " ");
+    while (st < 5) {
+        if (strcmp(tok, marker[st])) return -st-1000;
+        tok = strtok( NULL, " ");
+        if (!tok) return -st-2000;
+        tmp = strtol( tok, &epos, 0);
+        if (*epos != 0 && *epos != ',') return -st-3000;
+        switch (st) {
+	    case 0:
+		*dom = (int)tmp;
+		break;
+	    case 1:
+		*tt = (int)tmp;
+		break;
+	    case 2:
+		*pg = (int)tmp;
+		break;
+	    case 3:
+		*start = tmp;
+		break;
+	    case 4:
+		*end = tmp;
+		break;
+	} 
+	st++;
+        tok = strtok( NULL, " ");
+    }
+    return st;
+}
+
+remap_t* remap_loadmap( char *title) {
+    char buf[160];
+    char fname[MAXPATHLEN];
+    char *home;
+    int res;
+    FILE *fp;
+    block_t tmp;
+    remap_t *map;
+
+    /* Build the map filename */
+    home = getenv("HOME"); assert(home);
+    strncpy(fname, home, sizeof(fname));
+    strncat(fname, "/.xine/", sizeof(fname));
+    strncat(fname, title, sizeof(fname));
+    strncat(fname, ".map", sizeof(fname));
+
+    printf("Loading %s.\n", fname);
+    /* Open the map file */
+    fp = fopen( fname, "r");
+    if (!fp) {
+	printf("Unable to find map file '%s'\n", fname);
+	return NULL;
+    }
+
+    /* Load the map file */
+    map = remap_new( title);
+    while (fgets( buf, sizeof(buf), fp) != NULL) {
+        if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue;
+        if (strncasecmp( buf, "debug", 5) == 0) {
+	    map->debug = 1;
+	} else {
+	    res = parseblock( buf, 
+		&tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block);
+	    if (res != 5) {
+		printf("Ignoring map line (%d): %s\n", res, buf);
+		continue;
+	    }
+	    remap_add_node( map, tmp);
+	}
+    }
+
+    if (map->nblocks == 0 && map->debug == 0) return NULL;
+    return map;
+}
+
+unsigned long remap_block( 
+	remap_t *map, int domain, int title, int program, 
+	unsigned long cblock, unsigned long offset) 
+{
+    block_t key;
+    block_t *b;
+
+    if (map->debug) {
+	printf("%s: domain %d, title %d, program %d, start %lx, next %lx\n",
+	    map->title, domain, title, program, cblock, cblock+offset);
+    }
+
+    key.domain = domain;
+    key.title = title;
+    key.program = program;
+    key.start_block = key.end_block = cblock + offset;
+    b = findblock( map, &key);
+    
+    if (b) {
+       if (map->debug) {
+	   printf("Redirected to %lx\n", b->end_block);
+       }
+       return b->end_block - cblock;
+    }
+    return offset;
+}