int strm_ary_eq(strm_array a, strm_array b) { strm_int i, len; if (a == b) return TRUE; if (strm_ary_len(a) != strm_ary_len(b)) return FALSE; for (i=0, len=strm_ary_len(a); i<len; i++) { if (!strm_value_eq(strm_ary_ptr(a)[i], strm_ary_ptr(b)[i])) { return FALSE; } } return TRUE; }
static int ary_correl(strm_stream* strm, int argc, strm_value* args, strm_value* ret) { strm_value* v; int i, len; double sx, sy, sxx, syy, sxy; strm_get_args(strm, argc, args, "a", &v, &len); sx = sy = sxx = syy = sxy = 0; for (i=0; i<len; i++) { strm_value data = v[i]; strm_value* dv; double dx, dy; if (!strm_array_p(data) || strm_ary_len(data) != 2) { /* skip invalid data */ continue; } dv = strm_ary_ptr(data); dx = strm_value_flt(dv[0]) - sx; sx += dx / (i+1); dy = strm_value_flt(dv[1]) - sy; sy += dy / (i+1); sxx += i * dx * dx / (i+1); syy += i * dy * dy / (i+1); sxy += i * dx * dy / (i+1); } sxx = sqrt(sxx / (len-1)); syy = sqrt(syy / (len-1)); sxy /= (len-1) * sxx * syy; *ret = strm_flt_value(sxy); return STRM_OK; }
static int iter_rbk(strm_stream* strm, strm_value data) { struct rbk_data *d = strm->data; strm_value k, v; khiter_t i; int r; if (!strm_array_p(data) || strm_ary_len(data) != 2) { strm_raise(strm, "reduce_by_key element must be a key-value pair"); return STRM_NG; } k = strm_ary_ptr(data)[0]; v = strm_ary_ptr(data)[1]; i = kh_put(rbk, d->tbl, k, &r); if (r < 0) { /* r<0 operation failed */ return STRM_NG; } if (r != 0) { /* key does not exist */ kh_value(d->tbl, i) = v; } else { strm_value args[3]; args[0] = k; args[1] = kh_value(d->tbl, i); args[2] = v; if (strm_funcall(strm, d->func, 3, args, &v) == STRM_NG) { return STRM_NG; } kh_value(d->tbl, i) = v; } return STRM_OK; }
static int iter_correl(strm_stream* strm, strm_value data) { struct correl_data* d = strm->data; strm_value *v; double dx, dy; if (!strm_array_p(data) || strm_ary_len(data) != 2) { strm_raise(strm, "invalid data"); return STRM_NG; } v = strm_ary_ptr(data); if (!strm_number_p(v[0]) || !strm_number_p(v[1])) { strm_raise(strm, "correl() requires [num, num]"); return STRM_NG; } d->n++; dx = strm_value_flt(v[0]) - d->sx; d->sx += dx / d->n; dy = strm_value_flt(v[1]) - d->sy; d->sy += dy / d->n; d->sxx += (d->n-1) * dx * dx / d->n; d->syy += (d->n-1) * dy * dy / d->n; d->sxy += (d->n-1) * dx * dy / d->n; return STRM_OK; }
static int arr_exec(strm_stream* strm, strm_value data) { struct array_data *arrd = strm->data; if (arrd->n == strm_ary_len(arrd->arr)) { strm_stream_close(strm); return STRM_OK; } strm_emit(strm, strm_ary_ptr(arrd->arr)[arrd->n++], arr_exec); return STRM_OK; }
static int arr_exec(strm_task* task, strm_value data) { struct array_data *arrd = task->data; if (arrd->n == strm_ary_len(arrd->arr)) { strm_task_close(task); return STRM_OK; } strm_emit(task, strm_ary_ptr(arrd->arr)[arrd->n++], arr_exec); return STRM_OK; }
strm_string strm_inspect(strm_value v) { if (strm_string_p(v)) { strm_string str = strm_value_str(v); return str_dump(str, str_dump_len(str)); } else if (strm_array_p(v)) { char *buf = malloc(32); strm_int i, bi = 0, capa = 32; strm_array a = strm_value_ary(v); for (i=0; i<strm_ary_len(a); i++) { strm_string str = strm_inspect(strm_ary_ptr(a)[i]); strm_string key = (strm_ary_headers(a) && strm_string_p(strm_ary_ptr(strm_ary_headers(a))[i])) ? strm_value_str(strm_ary_ptr(strm_ary_headers(a))[i]) : strm_str_null; strm_int slen = (key ? (strm_str_len(key)+1) : 0) + strm_str_len(str) + 3; if (bi+slen > capa) { capa *= 2; buf = realloc(buf, capa); } if (bi == 0) { buf[bi++] = '['; } else { buf[bi++] = ','; buf[bi++] = ' '; } if (key) { if (!str_symbol_p(key)) { key = str_dump(key, str_dump_len(key)); } memcpy(buf+bi, strm_str_ptr(key), strm_str_len(key)); bi += strm_str_len(key); buf[bi++] = ':'; } memcpy(buf+bi, strm_str_ptr(str), strm_str_len(str)); bi += strm_str_len(str); } buf[bi++] = ']'; return strm_str_new(buf, bi); } else { return strm_to_str(v); } }
static int flatmap_len(strm_array ary) { strm_value* v = strm_ary_ptr(ary); strm_int i, len, n = 0; len = strm_ary_len(ary); for (i=0; i<len; i++) { if (strm_array_p(v[i])) { n += flatmap_len(v[i]); } else { n++; } } return n; }
static int flatmap_push(strm_stream* strm, strm_array ary, strm_value func, strm_value** p) { strm_value* v = strm_ary_ptr(ary); strm_int i, len; len = strm_ary_len(ary); for (i=0; i<len; i++) { if (strm_array_p(v[i])) { if (flatmap_push(strm, v[i], func, p) == STRM_NG) { return STRM_NG; } } else { if (strm_funcall(strm, func, 1, &v[i], *p) == STRM_NG) { return STRM_NG; } *p += 1; } } return STRM_OK; }
static int iter_flatmap(strm_stream* strm, strm_value data) { struct map_data* d = strm->data; strm_value val; strm_int i, len; strm_value* e; if (strm_funcall(strm, d->func, 1, &data, &val) == STRM_NG) { return STRM_NG; } if (!strm_array_p(val)) { strm_raise(strm, "no array given for flatmap"); return STRM_NG; } len = strm_ary_len(val); e = strm_ary_ptr(val); for (i=0; i<len; i++){ strm_emit(strm, e[i], NULL); } return STRM_OK; }
static int gen_cycle(strm_stream* strm, strm_value data) { struct cycle_data *d = strm->data; strm_value* p; strm_int i, len; d->count--; p = strm_ary_ptr(d->ary); len = strm_ary_len(d->ary); if (d->count != 0) { len--; } for (i=0; i<len; i++) { strm_emit(strm, p[i], NULL); } if (d->count == 0) { strm_stream_close(strm); } else { strm_emit(strm, p[i], gen_cycle); } return STRM_OK; }
static int csv_accept(strm_stream* strm, strm_value data) { strm_array ary; strm_string line = strm_value_str(data); strm_value *bp; const char *fbeg; const char *ptr; const char *pend; int fieldcnt; int in_quote = 0, all_str = 1; int i = 0; enum csv_type ftype; enum csv_type* types; struct csv_data *cd = strm->data; if (cd->prev) { strm_int len = strm_str_len(cd->prev)+strm_str_len(line)+1; char* tmp = malloc(len); memcpy(tmp, strm_str_ptr(cd->prev), strm_str_len(cd->prev)); *(tmp+strm_str_len(cd->prev)) = '\n'; memcpy(tmp+strm_str_len(cd->prev)+1, strm_str_ptr(line), strm_str_len(line)); line = strm_str_new(tmp, len); free(tmp); cd->prev = strm_str_null; } fieldcnt = count_fields(line); if (fieldcnt == -1) { cd->prev = line; return STRM_NG; } if (cd->n > 0 && fieldcnt != cd->n) return STRM_NG; ptr = strm_str_ptr(line); pend = ptr + strm_str_len(line); ary = strm_ary_new(NULL, fieldcnt); if (!ary) return STRM_NG; bp = (strm_value*)strm_ary_ptr(ary); types = cd->types; ftype = types ? types[0] : TYPE_UNSPC; for (fbeg=ptr; ptr<pend; ptr++) { if (in_quote) { if (*ptr == '\"') { if (ptr[1] == '\"') { ptr++; ftype = TYPE_ESC; continue; } in_quote = 0; } continue; } switch(*ptr) { case '\"': in_quote = 1; if (ptr == fbeg) { ftype = TYPE_STR; fbeg = ptr+1; } else { ftype = TYPE_ESC; } continue; case ',': *bp = csv_value(fbeg, ptr-fbeg, ftype); if (!strm_string_p(*bp)) all_str = 0; bp++; fbeg = ptr+1; i++; ftype = types ? types[i] : TYPE_UNSPC; break; default: continue; } } /* trim newline at the end */ if (ptr[-1] == '\n') { ptr--; } /* trim carriage return at the end */ if (ptr[-1] == '\r') { ptr--; } *bp = csv_value(fbeg, ptr-fbeg, ftype); if (!strm_string_p(*bp)) all_str = 0; /* check headers */ if (!cd->headers && !cd->types) { if (all_str) { cd->headers = ary; ary = strm_ary_null; } cd->n = fieldcnt; } if (ary) { /* set headers if any */ if (cd->headers) strm_ary_headers(ary) = cd->headers; if (!cd->types) { /* first data line (after optinal header line) */ if (cd->headers) { if (all_str) { /* data line is all string; emit header line */ strm_emit(strm, strm_ary_value(cd->headers), NULL); cd->headers = strm_ary_null; } else { /* intern header strings */ strm_array h = cd->headers; strm_value *p = strm_ary_ptr(h); int i; for (i=0; i<strm_ary_len(h); i++) { strm_string str = strm_value_str(p[i]); p[i] = strm_str_value(strm_str_intern_str(str)); } } } /* initialize types (determined by first data line) */ cd->types = malloc(sizeof(enum csv_type)*fieldcnt); if (!cd->types) return STRM_NG; for (i=0; i<fieldcnt; i++) { cd->types[i] = csv_type(strm_ary_ptr(ary)[i]); } } else { /* type check */ for (i=0; i<fieldcnt; i++) { if (cd->types[i] != csv_type(strm_ary_ptr(ary)[i])) { /* type mismatch (error); skip this line */ strm_raise(strm, "csv type mismatch"); return STRM_NG; } } } strm_emit(strm, strm_str_value(ary), NULL); } return STRM_OK; }