Ejemplo n.º 1
0
static size_t
channel_write_adb_hack(struct channel* c, size_t sz)
{
    size_t nr_removed = 0;

    while (nr_removed < sz) {
        struct iovec iov[2];
        char encbuf[4096];
        char* enc;
        char* encend;
        unsigned state;

        ringbuf_readable_iov(c->rb, iov, sz - nr_removed);
        enc = encbuf;
        encend = enc + sizeof (encbuf);
        state = c->leftover_escape;
        for (int i = 0; i < ARRAYSIZE(iov); ++i) {
            const char* in = iov[i].iov_base;
            const char* inend = in + iov[i].iov_len;
            adb_encode(&state, &enc, encend, &in, inend);
        }

        // If we left a byte in the ringbuffer, don't actually write
        // its first half now (since we wrote it before), but pretend
        // we did.
        size_t skip = (c->leftover_escape != 0);
        ssize_t nr_written =
            write_skip(c->fdh->fd, encbuf, enc - encbuf, skip);

        if (nr_written < 0 && nr_removed == 0)
            die_errno("write");
        if (nr_written < 0)
            break;

        size_t nr_encoded = 0;
        enc = encbuf;
        encend = enc + nr_written;
        state = c->leftover_escape;
        for (int i = 0; i < ARRAYSIZE(iov); ++i) {
            const char* in = iov[i].iov_base;
            const char* inend = in + iov[i].iov_len;
            adb_encode(&state, &enc, encend, &in, inend);
            nr_encoded += (in - (char*) iov[i].iov_base);
        }

        // If we wrote a partial encoded byte, leave the plain byte in
        // the ringbuf so that we know this channel still needs to
        // write.
        if (state != 0) {
            assert(nr_encoded > 0);
            nr_encoded -= 1;
        }

        ringbuf_note_removed(c->rb, nr_encoded);
        nr_removed += nr_encoded;
        c->leftover_escape = state;
    }

    return nr_removed;
}
Ejemplo n.º 2
0
void
ringbuf_dbg(const struct ringbuf* rb)
{
    struct iovec iov[2];
    ringbuf_readable_iov(rb, iov, ringbuf_size(rb));
    iovec_dbg(iov, ARRAYSIZE(iov));
}