add filters

This commit is contained in:
hummypkg 2011-06-03 10:27:40 +00:00 committed by HummyPkg
parent 9f637857c8
commit 2e2d35cf7e
4 changed files with 129 additions and 24 deletions

58
epg.c
View File

@ -21,6 +21,7 @@ read_section(struct epg *epg)
if (memcmp(h.magic, SECTION_MAGIC, sizeof(h.magic)))
{
printf("Section header magic mismatch.\n");
hexdump(epg->bin + epg->offset, 64, 0);
return NULL;
}
@ -105,10 +106,23 @@ dump_data(struct data *d)
DUMPINT(d, u1.u.descriptors_loop_length);
}
static inline int
check_filter(struct epgfilter *f, enum epgfiltertype type,
unsigned int id, char *str __attribute__((unused)))
{
if (!f)
return 1;
for (; f; f = f->next)
if (f->type == type && f->num != id)
return 0;
return 1;
}
void
parse(char *epgpath,
void (*callback)(struct epg *, struct section *, struct data *,
struct descriptor **, void *), void *val)
struct descriptor **, void *), void *val, struct epgfilter *filter)
{
struct descriptor *dslist[3];
struct epg *epg;
@ -127,6 +141,16 @@ parse(char *epgpath,
send = epg->offset - 11 + s->u1.u.length - 4;
if (!check_filter(filter, FILTER_SERVICE, s->service_id, NULL))
{
/* Skip this service. */
epg->offset += s->total_length - 14;
/* Skip padding bytes... */
while (epg->bin[epg->offset] == 'U')
epg->offset++;
continue;
}
while (epg->offset < send)
{
struct data *d;
@ -135,9 +159,18 @@ parse(char *epgpath,
if (!(d = read_data(epg)))
break;
dend = epg->offset + d->u1.u.descriptors_loop_length;
if (!check_filter(filter, FILTER_EVENT, d->event_id,
NULL))
{
/* Skip this event. */
epg->offset = dend;
continue;
}
dslist[0] = dslist[1] = dslist[2] = NULL;
dend = epg->offset + d->u1.u.descriptors_loop_length;
while (epg->offset < dend)
{
struct descriptor *ds;
@ -145,6 +178,14 @@ parse(char *epgpath,
if (!(ds = read_descriptor_header(epg)))
continue;
if (!check_filter(filter, FILTER_DESCRIPTOR,
ds->tag, NULL))
{
skip_descriptor(epg, ds);
free_descriptor(ds);
continue;
}
switch (ds->tag)
{
case DS_SHORT_EVENT:
@ -187,3 +228,16 @@ parse(char *epgpath,
close_file(epg);
}
void
add_epgfilter(struct epgfilter **filter, enum epgfiltertype type,
unsigned int num, char *str)
{
struct epgfilter *f = malloc(sizeof(struct epgfilter));
f->type = type;
f->num = num;
f->str = str;
f->next = *filter;
*filter = f;
}

14
epg.h
View File

@ -59,3 +59,17 @@ struct data {
} u1;
};
enum epgfiltertype {
FILTER_SERVICE = 0,
FILTER_EVENT,
FILTER_DESCRIPTOR
};
struct epgfilter {
enum epgfiltertype type;
unsigned int num;
char *str;
struct epgfilter *next;
};

4
lint.h
View File

@ -20,6 +20,8 @@ void safeprintf(char *, ...);
struct epg *open_file(char *);
void close_file(struct epg *);
void add_epgfilter(struct epgfilter **, enum epgfiltertype,
unsigned int, char *);
struct section *read_section(struct epg *);
void dump_section(struct section *);
@ -29,7 +31,7 @@ void dump_data(struct data *);
void parse(char *,
void (*)(struct epg *, struct section *, struct data *,
struct descriptor **, void *), void *);
struct descriptor **, void *), void *, struct epgfilter *);
struct descriptor *read_descriptor_header(struct epg *);
void read_descriptor(struct epg *, struct descriptor *);

77
main.c
View File

@ -25,7 +25,7 @@ syntax()
{
fprintf(stderr, "Humax EPG Tool v%s, by af123, 2011.\n\n", version);
fprintf(stderr,
"Syntax: epg [options] <command>...\n");
"Syntax: epg [options] [filters] <command>...\n\n");
fprintf(stderr,
" Options:\n"
" -b Brief output.\n"
@ -33,8 +33,15 @@ syntax()
" -f<file> Specify alternate EPG data file.\n"
" -h Show help text.\n"
" -p Parsable output.\n"
"\n"
);
fprintf(stderr,
" Filters: (can be specified multiple times, all must be true)\n"
" -D<descriptor type> Show only selected descriptor type.\n"
" -E<event id> Show only selected event.\n"
" -S<service id> Show only selected service.\n"
"\n"
);
fprintf(stderr, "\n");
fprintf(stderr,
" Commands:\n"
" dump Show a parsed summary of the EPG.\n"
@ -219,10 +226,29 @@ now(struct epg *epg __attribute__((unused)),
dump(epg, s, d, ds, NULL);
}
#define GETOPT \
do { \
if (*++cp == '\0' && argc < 2) \
{ \
fprintf(stderr, \
"No argument supplied for -%c\n", opt); \
exit(1); \
} \
else if (*cp == '\0') \
{ \
argc--, argv++; \
cp = argv[0]; \
} \
while (isspace((int)*cp)) \
cp++; \
} while (0)
int
main(int argc, char **argv)
{
char *epgpath = DEFAULT_EPG_FILE;
struct epgfilter *filter = NULL;
char *cp;
argc--, argv++;
@ -230,7 +256,8 @@ main(int argc, char **argv)
{
for (cp = &argv[0][1]; *cp; cp++)
{
switch (*cp)
char opt;
switch (opt = *cp)
{
case 'b':
sysopts |= SYSOPT_BRIEF;
@ -244,18 +271,8 @@ main(int argc, char **argv)
goto nextopt;
case 'f':
if (*++cp == '\0')
{
fprintf(stderr,
"No argument supplied for -f\n");
exit(1);
}
else
{
while (isspace((int)*cp))
cp++;
epgpath = strdup(cp);
}
GETOPT;
epgpath = strdup(cp);
goto nextopt;
case 'h':
@ -264,24 +281,42 @@ main(int argc, char **argv)
case 'p':
sysopts |= SYSOPT_PARSABLE;
break;
/* Filters */
case 'D':
GETOPT;
add_epgfilter(&filter, FILTER_DESCRIPTOR,
atoi(cp), NULL);
goto nextopt;
case 'E':
GETOPT;
add_epgfilter(&filter, FILTER_EVENT,
atoi(cp), NULL);
goto nextopt;
case 'S':
GETOPT;
add_epgfilter(&filter, FILTER_SERVICE,
atoi(cp), NULL);
goto nextopt;
}
}
nextopt:
argc--, argv++;
}
if (argc < 1)
return syntax();
if (!strcmp(argv[0], "dump"))
parse(epgpath, dump, NULL);
if (!strcmp(argv[0], "now"))
parse(epgpath, now, NULL);
parse(epgpath, dump, NULL, filter);
else if (!strcmp(argv[0], "now"))
parse(epgpath, now, NULL, filter);
else if (!strcmp(argv[0], "search") && argc > 1)
parse(epgpath, search, (void *)argv[1]);
parse(epgpath, search, (void *)argv[1], filter);
else if (!strcmp(argv[0], "searchall") && argc > 1)
parse(epgpath, searchall, (void *)argv[1]);
parse(epgpath, searchall, (void *)argv[1], filter);
else
syntax();