~ubuntu-branches/ubuntu/saucy/libdvdnav/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/02-hurd.patch/src/remap.c

  • Committer: Package Import Robot
  • Author(s): Daniel Baumann
  • Date: 2011-09-09 17:52:30 UTC
  • Revision ID: package-import@ubuntu.com-20110909175230-v7sxhda7c12i2bjv
Tags: 4.1.4-1219-3
Adding patch from Svante Signell <svante.signell@telia.com> to fix
FTBFS on hurd (Closes: #641028).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of libdvdnav, a DVD navigation library.
 
3
 *
 
4
 * libdvdnav is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2 of the License, or
 
7
 * (at your option) any later version.
 
8
 *
 
9
 * libdvdnav is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License along
 
15
 * with libdvdnav; if not, write to the Free Software Foundation, Inc.,
 
16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
17
 */
 
18
 
 
19
#ifdef HAVE_CONFIG_H
 
20
#include "config.h"
 
21
#endif
 
22
 
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
#include <stdio.h>
 
26
 
 
27
#ifndef _MSC_VER
 
28
#include <sys/param.h>
 
29
#include <sys/fcntl.h>
 
30
#else
 
31
#ifndef MAXPATHLEN
 
32
#define MAXPATHLEN 255
 
33
#endif
 
34
#endif /* _MSC_VER */
 
35
 
 
36
#include <inttypes.h>
 
37
#include <limits.h>
 
38
#include <sys/time.h>
 
39
#include "dvdnav/dvdnav.h"
 
40
#include <dvdread/nav_types.h>
 
41
#include <dvdread/ifo_types.h>
 
42
#include "remap.h"
 
43
#include "vm/decoder.h"
 
44
#include "vm/vm.h"
 
45
#include "dvdnav_internal.h"
 
46
 
 
47
struct block_s {
 
48
    int domain;
 
49
    int title;
 
50
    int program;
 
51
    unsigned long start_block;
 
52
    unsigned long end_block;
 
53
};
 
54
 
 
55
struct remap_s {
 
56
    char *title;
 
57
    int maxblocks;
 
58
    int nblocks;
 
59
    int debug;
 
60
    struct block_s *blocks;
 
61
};
 
62
 
 
63
static remap_t* remap_new( char *title) {
 
64
    remap_t *map = malloc( sizeof(remap_t));
 
65
    map->title = strdup(title);
 
66
    map->maxblocks = 0;
 
67
    map->nblocks = 0;
 
68
    map->blocks = NULL;
 
69
    map->debug = 0;
 
70
    return map;
 
71
}
 
72
 
 
73
static int compare_block( block_t *a, block_t *b) {
 
74
    /* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */
 
75
    if (a->domain < b->domain) {
 
76
        return -1;
 
77
    } else if (a->domain > b->domain) {
 
78
        return 1;
 
79
    }
 
80
 
 
81
    if (a->title < b->title) {
 
82
        return -1;
 
83
    } else if (a->title > b->title) {
 
84
        return 1;
 
85
    }
 
86
 
 
87
    if (a->program < b->program) {
 
88
        return -1;
 
89
    } else if (a->program > b->program) {
 
90
        return 1;
 
91
    }
 
92
 
 
93
    if (a->end_block < b->start_block) {
 
94
        return -1;
 
95
    } else if (a->start_block > b->end_block) {
 
96
        /*
 
97
         * if a->start_block == b->end_block then the two regions
 
98
         * aren't strictly overlapping, but they should be merged
 
99
         * anyway since there are zero blocks between them
 
100
         */
 
101
        return 1;
 
102
    }
 
103
 
 
104
    return 0;
 
105
}
 
106
 
 
107
static block_t *findblock( remap_t *map, block_t *key) {
 
108
    int lb = 0;
 
109
    int ub = map->nblocks - 1;
 
110
    int mid;
 
111
    int res;
 
112
 
 
113
    while (lb <= ub) {
 
114
        mid = lb + (ub - lb)/2;
 
115
        res = compare_block( key, &map->blocks[mid]);
 
116
        if (res < 0) {
 
117
            ub = mid-1;
 
118
        } else if (res > 0) {
 
119
            lb = mid+1;
 
120
        } else {
 
121
            return &map->blocks[mid];
 
122
        }
 
123
    }
 
124
    return NULL;
 
125
}
 
126
 
 
127
static void mergeblock( block_t *b, block_t tmp) {
 
128
    if (tmp.start_block < b->start_block) b->start_block = tmp.start_block;
 
129
    if (tmp.end_block > b->end_block) b->end_block = tmp.end_block;
 
130
}
 
131
 
 
132
static void remap_add_node( remap_t *map, block_t block) {
 
133
    block_t *b;
 
134
    int n;
 
135
    b = findblock( map, &block);
 
136
    if (b) {
 
137
        /* overlaps an existing block */
 
138
        mergeblock( b, block);
 
139
    } else {
 
140
        /* new block */
 
141
        if (map->nblocks >= map->maxblocks) {
 
142
            map->maxblocks += 20;
 
143
            map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks);
 
144
        }
 
145
        n = map->nblocks++;
 
146
        while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) {
 
147
            map->blocks[ n] = map->blocks[ n-1];
 
148
            n--;
 
149
        }
 
150
        map->blocks[ n] = block;
 
151
    }
 
152
}
 
153
 
 
154
static int parseblock(char *buf, int *dom, int *tt, int *pg,
 
155
                      unsigned long *start, unsigned long *end) {
 
156
    long tmp;
 
157
    char *tok;
 
158
    char *epos;
 
159
    char *marker[]={"domain", "title", "program", "start", "end"};
 
160
    int st = 0;
 
161
    tok = strtok( buf, " ");
 
162
    while (st < 5) {
 
163
        if (strcmp(tok, marker[st])) return -st-1000;
 
164
        tok = strtok( NULL, " ");
 
165
        if (!tok) return -st-2000;
 
166
        tmp = strtol( tok, &epos, 0);
 
167
        if (*epos != 0 && *epos != ',') return -st-3000;
 
168
        switch (st) {
 
169
            case 0:
 
170
                *dom = (int)tmp;
 
171
                break;
 
172
            case 1:
 
173
                *tt = (int)tmp;
 
174
                break;
 
175
            case 2:
 
176
                *pg = (int)tmp;
 
177
                break;
 
178
            case 3:
 
179
                *start = tmp;
 
180
                break;
 
181
            case 4:
 
182
                *end = tmp;
 
183
                break;
 
184
        }
 
185
        st++;
 
186
        tok = strtok( NULL, " ");
 
187
    }
 
188
    return st;
 
189
}
 
190
 
 
191
remap_t* remap_loadmap( char *title) {
 
192
    char buf[160];
 
193
    char fname[MAXPATHLEN];
 
194
    char *home;
 
195
    int res;
 
196
    FILE *fp;
 
197
    block_t tmp;
 
198
    remap_t *map;
 
199
 
 
200
    memset(&tmp, 0, sizeof(tmp));
 
201
    /* Build the map filename */
 
202
    home = getenv("HOME");
 
203
    if(!home) {
 
204
        fprintf(MSG_OUT, "libdvdnav: Unable to find home directory" );
 
205
        return NULL;
 
206
    }
 
207
    snprintf(fname, sizeof(fname), "%s/.dvdnav/%s.map", home, title);
 
208
 
 
209
    /* Open the map file */
 
210
    fp = fopen( fname, "r");
 
211
    if (!fp) {
 
212
        fprintf(MSG_OUT, "libdvdnav: Unable to find map file '%s'\n", fname);
 
213
        return NULL;
 
214
    }
 
215
 
 
216
    /* Load the map file */
 
217
    map = remap_new( title);
 
218
    while (fgets( buf, sizeof(buf), fp) != NULL) {
 
219
        if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue;
 
220
        if (strncasecmp( buf, "debug", 5) == 0) {
 
221
            map->debug = 1;
 
222
        } else {
 
223
            res = parseblock( buf,
 
224
                &tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block);
 
225
            if (res != 5) {
 
226
                fprintf(MSG_OUT, "libdvdnav: Ignoring map line (%d): %s\n", res, buf);
 
227
                continue;
 
228
            }
 
229
            remap_add_node( map, tmp);
 
230
        }
 
231
    }
 
232
    fclose(fp);
 
233
 
 
234
    if (map->nblocks == 0 && map->debug == 0) {
 
235
        free(map);
 
236
        return NULL;
 
237
    }
 
238
    return map;
 
239
}
 
240
 
 
241
unsigned long remap_block(
 
242
        remap_t *map, int domain, int title, int program,
 
243
        unsigned long cblock, unsigned long offset)
 
244
{
 
245
    block_t key;
 
246
    block_t *b;
 
247
 
 
248
    if (map->debug) {
 
249
        fprintf(MSG_OUT, "libdvdnav: %s: domain %d, title %d, program %d, start %lx, next %lx\n",
 
250
            map->title, domain, title, program, cblock, cblock+offset);
 
251
    }
 
252
 
 
253
    key.domain = domain;
 
254
    key.title = title;
 
255
    key.program = program;
 
256
    key.start_block = key.end_block = cblock + offset;
 
257
    b = findblock( map, &key);
 
258
 
 
259
    if (b) {
 
260
       if (map->debug) {
 
261
           fprintf(MSG_OUT, "libdvdnav: Redirected to %lx\n", b->end_block);
 
262
       }
 
263
       return b->end_block - cblock;
 
264
    }
 
265
    return offset;
 
266
}