shithub: treason

Download patch

ref: 53cbe4d7f606040ea5cec9669524582b6c6f2526
parent: 3ca28bcf70c149cfefa97adb810ba4da2420023a
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Mar 2 05:22:42 EST 2021

added stream_sub.c

--- /dev/null
+++ b/stream_sub.c
@@ -1,0 +1,130 @@
+#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,
+};