コード例 #1
0
ファイル: as_output.c プロジェクト: s-u/iotools
SEXP dybuf_collect(SEXP s) {
    dybuf_info_t *d = (dybuf_info_t*) RAW(VECTOR_ELT(s, 1));
    unsigned long total = 0;
    char *dst;
    SEXP head = VECTOR_ELT(s, 0), res;
    if (d->con) {
	long wr;
	/* FIXME: should we try partial sends as well ? */
	if ((wr = R_WriteConnection(d->con, d->data, d->pos)) != d->pos)
	    Rf_error("write failed, expected %lu, got %ld", d->pos, wr);
	d->pos = 0;
	return R_NilValue;
    }
    while (d->tail != head) {
	total += LENGTH(CAR(head));
	head = CDR(head);
    }
    total += d->pos;
    dst = (char*) RAW(res = PROTECT(allocVector(RAWSXP, total)));
    head = VECTOR_ELT(s, 0);
    while (d->tail != head) {
	int l = LENGTH(CAR(head));
	memcpy(dst, RAW(CAR(head)), l);
	dst += l;
	head = CDR(head);
    }
    if (d->pos) memcpy(dst, RAW(CAR(head)), d->pos);
    UNPROTECT(1);
    return res;
}
コード例 #2
0
std::streamsize connection_sink::write(const char* s, std::streamsize n) {
  size_t write_size;

  if ((write_size = R_WriteConnection(con_, (void*)s, n)) !=
      static_cast<size_t>(n)) {
    Rcpp::stop("write failed, expected %l, got %l", n, write_size);
  }
  return write_size;
}
コード例 #3
0
ファイル: as_output.c プロジェクト: s-u/iotools
void dybuf_add(SEXP s, const char *data, unsigned long len) {
    dybuf_info_t *d = (dybuf_info_t*) RAW(VECTOR_ELT(s, 1));
    unsigned long n = (d->pos + len > d->size) ? (d->size - d->pos) : len;
    if (!len) return;
    /* printf("[%lu/%lu] %lu\n", d->pos, d->size, len); */
    if (n) {
	memcpy(d->data + d->pos, data, n);
	d->pos += n;
	if (len == n) return;
	data += n;
	len -= n;
    }
    /* printf("[%lu/%lu] filled, need %lu more", d->pos, d->size, len); */

    /* if the output is connection-based, flush */
    if (d->con) {
	long wr;
	/* FIXME: should we try partial sends as well ? */
	if ((wr = R_WriteConnection(d->con, d->data, d->pos)) != d->pos)
	    Rf_error("write failed, expected %lu, got %ld", d->pos, wr);
	d->pos = 0;
	/* if the extra content is substantially big, don't even
	   bother storing it and send right away */
	if (len > (d->size / 2)) {
	    /* FIXME: (actually FIX R): WriteConnection should be using const void* */
	    if ((wr = R_WriteConnection(d->con, (void*) data, len)) != len)
		Rf_error("write failed, expected %lu, got %ld", len, wr);
	} else { /* otherwise copy into the buffer */
	    memcpy(d->data, data, len);
	    d->pos = len;
	}
    } else { /* need more buffers */
	SEXP nb;
	while (len > d->size) d->size *= 2;
	/* printf(", creating %lu more\n", d->size); */
	d->tail = SETCDR(d->tail, list1(nb = allocVector(RAWSXP, d->size)));
	memcpy(d->data = (char*) RAW(nb), data, len);
	d->pos = len;
    }
}