comparison 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
comparison
equal deleted inserted replaced
95:e7ebabe059b9 96:2fcb4f228308
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <sys/param.h>
5 #include <sys/fcntl.h>
6 #include <assert.h>
7 #include "remap.h"
8
9 struct block_s {
10 int domain;
11 int title;
12 int program;
13 unsigned long start_block;
14 unsigned long end_block;
15 };
16
17 struct remap_s {
18 char *title;
19 int maxblocks;
20 int nblocks;
21 int debug;
22 struct block_s *blocks;
23 };
24
25 remap_t* remap_new( char *title) {
26 remap_t *map = malloc( sizeof(remap_t));
27 map->title = strdup(title);
28 map->maxblocks = 0;
29 map->nblocks = 0;
30 map->blocks = NULL;
31 map->debug = 0;
32 return map;
33 }
34
35 static int compare_block( block_t *a, block_t *b) {
36 /* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */
37 if (a->domain < b->domain) {
38 return -1;
39 } else if (a->domain > b->domain) {
40 return 1;
41 }
42
43 if (a->title < b->title) {
44 return -1;
45 } else if (a->title > b->title) {
46 return 1;
47 }
48
49 if (a->program < b->program) {
50 return -1;
51 } else if (a->program > b->program) {
52 return 1;
53 }
54
55 if (a->end_block < b->start_block) {
56 return -1;
57 } else if (a->start_block > b->end_block) {
58 /*
59 * if a->start_block == b->end_block then the two regions
60 * aren't strictly overlapping, but they should be merged
61 * anyway since there are zero blocks between them
62 */
63 return 1;
64 }
65
66 return 0;
67 }
68
69 static block_t *findblock( remap_t *map, block_t *key) {
70 int lb = 0;
71 int ub = map->nblocks - 1;
72 int mid;
73 int res;
74
75 while (lb <= ub) {
76 mid = lb + (ub - lb)/2;
77 res = compare_block( key, &map->blocks[mid]);
78 if (res < 0) {
79 ub = mid-1;
80 } else if (res > 0) {
81 lb = mid+1;
82 } else {
83 return &map->blocks[mid];
84 }
85 }
86 return NULL;
87 }
88
89 static void mergeblock( block_t *b, block_t tmp) {
90 if (tmp.start_block < b->start_block) b->start_block = tmp.start_block;
91 if (tmp.end_block > b->end_block) b->end_block = tmp.end_block;
92 }
93
94 static void remap_add_node( remap_t *map, block_t block) {
95 block_t *b;
96 int n;
97 b = findblock( map, &block);
98 if (b) {
99 /* overlaps an existing block */
100 mergeblock( b, block);
101 } else {
102 /* new block */
103 if (map->nblocks >= map->maxblocks) {
104 map->maxblocks += 20;
105 map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks);
106 }
107 n = map->nblocks++;
108 while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {
109 map->blocks[ n] = map->blocks[ n-1];
110 n--;
111 }
112 map->blocks[ n] = block;
113 }
114 }
115
116 int parseblock(
117 char *buf, int *dom, int *tt, int *pg,
118 unsigned long *start, unsigned long *end)
119 {
120 long tmp;
121 char *tok;
122 char *epos;
123 char *marker[]={"domain", "title", "program", "start", "end"};
124 int st = 0;
125 tok = strtok( buf, " ");
126 while (st < 5) {
127 if (strcmp(tok, marker[st])) return -st-1000;
128 tok = strtok( NULL, " ");
129 if (!tok) return -st-2000;
130 tmp = strtol( tok, &epos, 0);
131 if (*epos != 0 && *epos != ',') return -st-3000;
132 switch (st) {
133 case 0:
134 *dom = (int)tmp;
135 break;
136 case 1:
137 *tt = (int)tmp;
138 break;
139 case 2:
140 *pg = (int)tmp;
141 break;
142 case 3:
143 *start = tmp;
144 break;
145 case 4:
146 *end = tmp;
147 break;
148 }
149 st++;
150 tok = strtok( NULL, " ");
151 }
152 return st;
153 }
154
155 remap_t* remap_loadmap( char *title) {
156 char buf[160];
157 char fname[MAXPATHLEN];
158 char *home;
159 int res;
160 FILE *fp;
161 block_t tmp;
162 remap_t *map;
163
164 /* Build the map filename */
165 home = getenv("HOME"); assert(home);
166 strncpy(fname, home, sizeof(fname));
167 strncat(fname, "/.xine/", sizeof(fname));
168 strncat(fname, title, sizeof(fname));
169 strncat(fname, ".map", sizeof(fname));
170
171 printf("Loading %s.\n", fname);
172 /* Open the map file */
173 fp = fopen( fname, "r");
174 if (!fp) {
175 printf("Unable to find map file '%s'\n", fname);
176 return NULL;
177 }
178
179 /* Load the map file */
180 map = remap_new( title);
181 while (fgets( buf, sizeof(buf), fp) != NULL) {
182 if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue;
183 if (strncasecmp( buf, "debug", 5) == 0) {
184 map->debug = 1;
185 } else {
186 res = parseblock( buf,
187 &tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block);
188 if (res != 5) {
189 printf("Ignoring map line (%d): %s\n", res, buf);
190 continue;
191 }
192 remap_add_node( map, tmp);
193 }
194 }
195
196 if (map->nblocks == 0 && map->debug == 0) return NULL;
197 return map;
198 }
199
200 unsigned long remap_block(
201 remap_t *map, int domain, int title, int program,
202 unsigned long cblock, unsigned long offset)
203 {
204 block_t key;
205 block_t *b;
206
207 if (map->debug) {
208 printf("%s: domain %d, title %d, program %d, start %lx, next %lx\n",
209 map->title, domain, title, program, cblock, cblock+offset);
210 }
211
212 key.domain = domain;
213 key.title = title;
214 key.program = program;
215 key.start_block = key.end_block = cblock + offset;
216 b = findblock( map, &key);
217
218 if (b) {
219 if (map->debug) {
220 printf("Redirected to %lx\n", b->end_block);
221 }
222 return b->end_block - cblock;
223 }
224 return offset;
225 }