static void test_knp_msg() { kbuffer msg1, msg2; kstr str; uint32_t i32; uint64_t i64; kbuffer_init(&msg1, 0); kbuffer_init(&msg2, 0); kstr_init(&str); knp_msg_write_uint32(&msg1, 3); knp_msg_write_uint64(&msg1, 4); kstr_append_cstr(&str, "hello"); knp_msg_write_kstr(&msg1, &str); kbuffer_write(&msg2, msg1.data, msg1.len); assert(! knp_msg_read_uint32(&msg2, &i32) && i32 == 3); assert(! knp_msg_read_uint64(&msg2, &i64) && i64 == 4); assert(! knp_msg_read_kstr(&msg2, &str) && strcmp(str.data, "hello") == 0); assert(knp_msg_read_uint32(&msg2, &i32)); kbuffer_clean(&msg1); kbuffer_clean(&msg2); kstr_free(&str); }
void *kbuffer_new(t_symbol *s, int argc, t_atom *argv) { #if MSP t_kbuffer *x = (t_kbuffer *)newobject(kbuffer_class); dsp_setup((t_pxobject *)x,1); outlet_new((t_object *)x, "signal"); outlet_new((t_object *)x, "signal"); #endif #if PD t_kbuffer *x = (t_kbuffer *)pd_new(kbuffer_class); outlet_new(&x->x_obj, gensym("signal")); outlet_new(&x->x_obj, gensym("signal")); #endif x->srate = sys_getsr(); if( x->srate == 0 ){ error("zero sampling rate - set to 44100"); x->srate = 44100; } x->ksrate = atom_getfloatarg(0,argc,argv); x->duration = atom_getfloatarg(1,argc,argv)/1000.0; if(x->ksrate <= 0) x->ksrate = 128; if(x->duration <= 0) x->duration = 10.; kbuffer_init(x,0); return (x); }
/* This function retrieves the current working directory. The path will have a * trailing delimiter. */ void kpath_getcwd(kstr *path) { #ifdef __WINDOWS__ #define getcwd _getcwd #endif int buf_size = 256; char *ret; kbuffer buf; kbuffer_init(&buf); while (1) { kbuffer_grow(&buf, buf_size); ret = getcwd((char *) buf.data, buf_size); if (ret == NULL) { /* Buffer is too small. Double it. */ if (errno == ERANGE) buf_size *= 2; /* Oops. */ else kerror_fatal("cannot get current working directory: %s", kerror_syserror()); } else break; } kstr_assign_buf(path, buf.data, strlen((char *) buf.data)); kpath_add_delim(path, KPATH_FORMAT_NATIVE); kbuffer_clean(&buf); }
static void test_b64() { kbuffer a, b, c; kbuffer_init(&a, 0); kbuffer_init(&b, 0); kbuffer_init(&c, 0); kbuffer_write(&a, "testing", sizeof("testing")); bin2b64(&a, &b); b642bin(&b, &c, 0); assert(strcmp(a.data, c.data) == 0); kbuffer_clean(&a); kbuffer_clean(&b); kbuffer_clean(&c); }
void kbuffer_dsp(t_kbuffer *x, t_signal **sp, short *count) { // DSP CONFIG #if MSP x->in_connected = count[0]; #endif #if PD x->in_connected = 1; #endif if(x->srate != sp[0]->s_sr){ x->srate = sp[0]->s_sr; kbuffer_init(x,1); } dsp_add(kbuffer_perform, 5, x, sp[0]->s_vec, sp[1]->s_vec, sp[2]->s_vec, sp[0]->s_n); }
/* This function sends a message to the server. * This function sets the KMO error string. It returns 0, -1, -2, or -3. */ static int knp_query_send_msg(struct knp_query *query, uint32_t msg_type, kbuffer *payload, k3p_proto *k3p) { int error = 0; kbuffer msg; kbuffer_init(&msg, 100); kmod_log_msg(3, "knp_query_send_msg() called.\n"); /* Try. */ do { /* Validate the payload size. */ if (payload->len > KNP_MAX_PAYLOAD_SIZE) { kmo_seterror("outgoing KNP message is too big (%d bytes)", payload->len); error = -1; break; } /* Send the message. */ kbuffer_write32(&msg, KNP_MAJOR_VERSION); kbuffer_write32(&msg, KNP_MINOR_VERSION); kbuffer_write32(&msg, msg_type); kbuffer_write32(&msg, payload->len); kbuffer_write(&msg, payload->data, payload->len); if (knp_log) { knp_log_msg("INPUT", KNP_MAJOR_VERSION, KNP_MINOR_VERSION, msg_type, payload, &query->server_addr, query->server_port); } error = knp_query_ssl_transfer(query, 0, msg.data, msg.len, "cannot send KNP message", k3p); if (error) break; } while (0); if (error) knp_query_disconnect(query); kbuffer_clean(&msg); return error; }
/* This function asks the proxy to connect us to the end server. * This function sets the KMO error string. It returns 0, -1, -2 or -3. */ static int knp_handle_proxy(struct knp_query *query, k3p_proto *k3p, kstr *proxy_login, kstr *proxy_pwd) { int error = 0; int first_line = 1; struct kmo_data_transfer *transfer = &query->transfer; kstr msg; kstr str; kmod_log_msg(3, "knp_handle_proxy() called.\n"); kstr_init(&msg); kstr_init(&str); /* Try. */ do { /* Connect to the specified server and port. */ kstr_sf(&msg, "CONNECT %s:%d HTTP/1.0\r\n", query->server_addr.data, query->server_port); /* Using the following "user:pwd" credentials encoded in base 64. */ if (proxy_login->slen > 0 || proxy_pwd->slen > 0) { kbuffer in, out; kbuffer_init(&in, 100); kbuffer_init(&out, 100); kbuffer_write(&in, proxy_login->data, proxy_login->slen); kbuffer_write(&in, ":", 1); kbuffer_write(&in, proxy_pwd->data, proxy_pwd->slen); bin2b64(&in, &out); kstr_append_cstr(&msg, "Proxy-Authorization: basic "); kstr_append_buf(&msg, out.data, out.len); kstr_append_cstr(&msg, "\r\n"); kbuffer_clean(&in); kbuffer_clean(&out); } /* An empty line marks the end of the request. */ kstr_append_cstr(&msg, "\r\n"); /* Send the message to the proxy. */ transfer->read_flag = 0; transfer->buf = msg.data; transfer->min_len = transfer->max_len = msg.slen; error = knp_exec_transfer(transfer, k3p); if (error) break; if (transfer->status != KMO_COMM_TRANS_COMPLETED) { assert(transfer->status == KMO_COMM_TRANS_ERROR); kmo_seterror("proxy error: %s", kmo_data_transfer_err(transfer)); knp_query_handle_conn_error(query, transfer->err_msg ? KMO_SERROR_MISC : KMO_SERROR_TIMEOUT); error = -1; break; } /* Receive the reply from the server, char by char to avoid reading past * the HTTP reply data. */ kstr_clear(&msg); while (1) { char c; transfer->read_flag = 1; transfer->buf = &c; transfer->min_len = transfer->max_len = 1; error = knp_exec_transfer(transfer, k3p); if (error) break; if (transfer->status != KMO_COMM_TRANS_COMPLETED) { assert(transfer->status == KMO_COMM_TRANS_ERROR); kmo_seterror("proxy error: %s", kmo_data_transfer_err(transfer)); knp_query_handle_conn_error(query, transfer->err_msg ? KMO_SERROR_MISC : KMO_SERROR_TIMEOUT); error = -1; break; } kstr_append_char(&msg, c); /* We reached the end of a line. */ if (msg.slen >= 2 && msg.data[msg.slen - 2] == '\r' && msg.data[msg.slen - 1] == '\n') { /* This is the response line. Parse it. */ if (first_line) { int reply_code; /* Expecting "HTTP/x.x ddd <string>\r\n" */ if (msg.slen < 16 || msg.data[0] != 'H' || msg.data[1] != 'T' || msg.data[2] != 'T' || msg.data[3] != 'P' || ! is_digit(msg.data[9]) || ! is_digit(msg.data[10]) || ! is_digit(msg.data[11])) { kmo_seterror("invalid proxy HTTP reply"); error = -1; break; } /* Get the numeric code. */ reply_code = atoi(msg.data + 9); /* Not 200, it didn't work. */ if (reply_code != 200) { /* Get the reason. */ kstr_assign_buf(&str, msg.data + 13, msg.slen - 2 - 13); kmo_seterror("the proxy refuses to connect: %s (code %d)", str.data, reply_code); error = -1; break; } first_line = 0; } /* The server is sending us some unwanted line. Ignore it. */ else if (msg.slen != 2) { /* Void. */ } /* We reached the end of the reply. The next bytes received will be SSL bytes. */ else { break; } /* Clear the line buffer. */ kstr_clear(&msg); } /* It's too long. */ else if (msg.slen > 1000) { kmo_seterror("HTTP reply too long"); error = -1; break; } } if (error) break; } while (0); kstr_free(&msg); kstr_free(&str); return error; }
struct anp_msg* anp_msg_new() { struct anp_msg *self = (struct anp_msg *) kcalloc(sizeof(struct anp_msg)); kbuffer_init(&self->payload); karray_init(&self->element_array); return self; }
/* This function dumps the content of a ANP message buffer in the string * specified. This function sets the KMOD error string when it encounters an * error in the buffer. It returns -1 on failure. */ int anp_dump(kbuffer *buf, kstr *dump_str) { int error = 0; kstr work_str; kstr data_str; kbuffer bin_buf; kstr_init(&work_str); kstr_init(&data_str); kbuffer_init(&bin_buf); kstr_reset(dump_str); while (! kbuffer_eof(buf)) { uint8_t type = buf->data[buf->pos]; if (type == ANP_UINT32) { uint32_t val; error = anp_read_uint32(buf, &val); if (error) break; kstr_sf(&work_str, "uint32> %u\n", val); kstr_append_kstr(dump_str, &work_str); } else if (type == ANP_UINT64) { uint64_t val; error = anp_read_uint64(buf, &val); if (error) break; kstr_sf(&work_str, "uint64> "PRINTF_64"u\n", val); kstr_append_kstr(dump_str, &work_str); } else if (type == ANP_STR) { error = anp_read_kstr(buf, &data_str); if (error) break; kstr_sf(&work_str, "string %u> ", data_str.slen); kstr_append_kstr(dump_str, &work_str); kstr_append_kstr(dump_str, &data_str); kstr_append_cstr(dump_str, "\n"); } else if (type == ANP_BIN) { error = anp_read_bin(buf, &bin_buf); if (error) break; kstr_sf(&work_str, "binary %u> ", bin_buf.len); kstr_append_kstr(dump_str, &work_str); kstr_append_cstr(dump_str, "\n"); } else { kmod_set_error("invalid ANP identifier (%u)\n", type); error = -1; break; } } kstr_clean(&work_str); kstr_clean(&data_str); kbuffer_clean(&bin_buf); /* Reset the buffer position to 0. */ buf->pos = 0; return error; }