ref: d696956ababd5fdec5bcb51373896468c310161d
dir: /stream_sub.c/
#include <u.h> #include <libc.h> #include <bio.h> #include <ctype.h> #include "misc.h" #include "stream.h" extern Streamops subops; int subopenfd(int fd, Stream *s, int *failed) { if(fd < 0) return -1; s->type = Ssubtitles; s->timebase.denum = 1; s->timebase.num = 1; s->b = Bfdopen(fd, OREAD); memmove(&s->ops, &subops, sizeof(subops)); *failed = 0; return 0; } Stream * subopen(char *path, int *num, int *failed) { Stream *s; if((s = calloc(1, sizeof(*s))) == nil){ *failed = 1; return nil; } *num = 1; if(subopenfd(open(path, OREAD), s, failed) != 0){ free(s); s = nil; } return s; } static int subts2ns(char *s, char **e, uvlong *ns) { if(strlen(s) < 9){ werrstr("timestamp too short"); goto err; } *ns = 0; s--; do{ s++; *ns *= 60; *ns += strtod(s, &s)*1000000000.0; if(*s == ','){ *ns += strtod(s+1, &s)*1000000.0; break; } }while(*s == ':'); *e = s; return 0; err: werrstr("subts2ns: %r"); return -1; } static int subread(Stream *s, Streamframe *f) { uvlong end; char *x; int i, n; Brdline(s->b, '\n'); /* index */ if((x = Brdline(s->b, '\n')) == nil){ /* timestamp */ f->sz = 0; return 0; } if((n = Blinelen(s->b)) < 1){ werrstr("unexpected empty line"); goto err; } x[n-1] = 0; if(subts2ns(x, &x, &f->timestamp) != 0) goto err; while(isspace(*x)) x++; if(strncmp(x, "-->", 3) != 0){ werrstr("no timestamp delimeter: %s", x); goto err; } x += 3; if(subts2ns(x, &x, &end) != 0) goto err; f->dt = end - f->timestamp; for(i = 0; i < nelem(f->lines); i++){ if((x = Brdstr(s->b, '\n', 1)) == nil || *x == 0){ free(x); break; } f->lines[i] = x; } f->nlines = i; s->timestamp = f->timestamp; return 0; err: werrstr("subread: %r"); return -1; } static void subclose(Stream *s) { Bterm(s->b); free(s->buf); } Streamops subops = { .open = subopen, .read = subread, .close = subclose, };