summaryrefslogtreecommitdiffstats
path: root/bitsplit.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2004-04-18 01:35:53 +0000
committerLennart Poettering <lennart@poettering.net>2004-04-18 01:35:53 +0000
commit783b56d54788f177881d68ae2ec7a7cb4bb38ac4 (patch)
tree77555207fa13c137e0c8dab8726f2ed96538e075 /bitsplit.c
parentf069d236c79a7cb89542eba5ddc454d03ead5394 (diff)
Initial commit
git-svn-id: file:///home/lennart/svn/public/vfax/trunk@3 541b366f-4dd8-0310-ae39-b2612fd50714
Diffstat (limited to 'bitsplit.c')
-rw-r--r--bitsplit.c104
1 files changed, 104 insertions, 0 deletions
diff --git a/bitsplit.c b/bitsplit.c
new file mode 100644
index 0000000..ee2074b
--- /dev/null
+++ b/bitsplit.c
@@ -0,0 +1,104 @@
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "bitsplit.h"
+#include "util.h"
+
+void bitsplit_init(struct bitsplit_state *s, int maxbits_in, int maxbits_out) {
+ assert(s && maxbits_in && maxbits_out);
+ assert(maxbits_in <= 8 && maxbits_out <= 8);
+
+ memset(s, 0, sizeof(struct bitsplit_state));
+ s->maxbits_in = maxbits_in;
+ s->maxbits_out = maxbits_out;
+}
+
+inline static int read_next_bit(struct bitsplit_state *s, uint8_t **src) {
+ assert(s);
+
+ if (!s->n_in) {
+ s->in = **src;
+ (*src)++;
+ s->n_in = s->maxbits_in;
+ }
+
+ return (s->in >> (-- (s->n_in))) & 1;
+}
+
+inline static void write_next_bit(struct bitsplit_state *s, uint8_t **dst, int bit) {
+ assert(s);
+
+ s->out = (s->out << 1) | (bit & 1);
+ s->n_out++;
+
+ if (s->n_out >= s->maxbits_out) {
+ **dst = s->out;
+ s->out = 0;
+ (*dst)++;
+ s->n_out = 0;
+ }
+}
+
+void bitsplit(struct bitsplit_state *s, uint8_t *src, size_t *src_l, uint8_t *dst, size_t *dst_l) {
+ uint8_t *save_dst = dst, *save_src = src;
+
+ assert(s && src && dst && src_l && dst_l);
+
+ while ((src < save_src+*src_l /*|| s->n_in*/) && (dst < save_dst+*dst_l /*|| s->n_out < s->maxbits_out*/)) {
+ int bit;
+
+ bit = read_next_bit(s, &src);
+ write_next_bit(s, &dst, bit);
+ }
+
+ *src_l = src - save_src;
+ *dst_l = dst - save_dst;
+}
+
+#if (TEST == 4)
+
+int main(int argc, char *argv[]) {
+ struct bitsplit_state s;
+
+ assert(argc >= 3);
+
+ bitsplit_init(&s, atoi(argv[1]), atoi(argv[2]));
+
+ for (;;) {
+ uint8_t in[1024];
+ uint8_t *i;
+
+ ssize_t r;
+
+ r = read(0, in, sizeof(in));
+ assert(r >= 0);
+
+ if (r == 0)
+ break;
+
+ i = in;
+
+ while (r) {
+ uint8_t out[1024];
+ size_t outl = sizeof(out);
+ size_t il = r;
+ ssize_t r2;
+
+ bitsplit(&s, i, &il, out, &outl);
+ i += il;
+ r -= il;
+
+ if (outl) {
+ r2 = loop_write(1, out, outl);
+ assert(r2 > 0);
+ }
+ }
+ }
+
+ return 0;
+}
+
+#endif