static ssize_t data_allocator_fixed_t_delete(data_t *data, fastcall_delete *fargs){ // {{{ ssize_t ret; allocator_fixed_t *fdata = (allocator_fixed_t *)data->ptr; pthread_rwlock_wrlock(&fdata->rwlock); if(fdata->removed_items.type){ data_t d_offset = DATA_PTR_UINTT(&fargs->offset); data_t d_copy; fastcall_copy r_copy = { { 3, ACTION_COPY }, &d_copy }; if( (ret = data_query(&d_offset, &r_copy)) < 0) goto exit; fastcall_push r_push = { { 3, ACTION_PUSH }, &d_copy }; if(data_query(&fdata->removed_items, &r_push) != 0){ ret = -EFAULT; goto exit; } } // TODO move items //ret = allocator_removelastid(fdata); exit: pthread_rwlock_unlock(&fdata->rwlock); return ret; } // }}}
static ssize_t data_allocator_fixed_t_create(data_t *data, fastcall_create *fargs){ // {{{ ssize_t ret; allocator_fixed_t *fdata = (allocator_fixed_t *)data->ptr; pthread_rwlock_wrlock(&fdata->rwlock); if(fdata->removed_items.type){ data_t d_offset = DATA_PTR_UINTT(&fargs->offset); data_t d_copy; fastcall_pop r_pop = { { 3, ACTION_POP }, &d_copy }; if( (ret = data_query(&fdata->removed_items, &r_pop)) == 0) goto exit; fastcall_transfer r_transfer = { { 3, ACTION_TRANSFER }, &d_offset }; ret = data_query(&d_copy, &r_transfer); goto exit; } ret = allocator_getnewid(fdata, &fargs->offset); exit: pthread_rwlock_unlock(&fdata->rwlock); return ret; } // }}}
static ssize_t data_triplet_format_single_t_lookup(data_t *data, fastcall_crud *fargs) { // {{{ ssize_t ret; data_t converted; data_t storage_item; triplet_format_t *fdata = (triplet_format_t *)data->ptr; // fetch value from storage fastcall_lookup r_lookup = { { 4, ACTION_LOOKUP }, fargs->key, &storage_item }; if( (ret = data_query(&fdata->storage, &r_lookup)) < 0) return ret; // prepare copy of template holder_copy(ret, &converted, &fdata->slave); if(ret < 0) goto exit; fastcall_convert_from r_convert = { { 5, ACTION_CONVERT_FROM }, &storage_item, FORMAT(packed) }; if( (ret = data_query(&converted, &r_convert)) < 0) goto exit; *fargs->value = converted; exit: data_free(&storage_item); return ret; } // }}}
static ssize_t data_timestamp_t_convert_from(data_t *dst, fastcall_convert_from *fargs){ // {{{ char buffer[DEF_BUFFER_SIZE] = { 0 }; timestamp_t *fdata; if(fargs->src == NULL) return -EINVAL; if(dst->ptr == NULL){ // no buffer, alloc new if(data_timestamp_t_alloc(dst, NULL) != 0) return -ENOMEM; } fdata = (timestamp_t *)dst->ptr; switch( fargs->format ){ case FORMAT(config):; case FORMAT(human):; fastcall_read r_read_str = { { 5, ACTION_READ }, 0, &buffer, sizeof(buffer) - 1 }; if(data_query(fargs->src, &r_read_str) != 0) return -EFAULT; return timestamp_from_string(&fdata->time, buffer, r_read_str.buffer_size); case FORMAT(clean):; case FORMAT(binary):; fastcall_read r_read = { { 5, ACTION_READ }, 0, &fdata->time, sizeof(fdata->time) }; return data_query(fargs->src, &r_read); default: break; }; return -ENOSYS; } // }}}
static ssize_t data_timestamp_t_convert_to(data_t *src, fastcall_convert_to *fargs){ // {{{ ssize_t ret; char buffer[DEF_BUFFER_SIZE]; uintmax_t buffer_size = sizeof(buffer); uintmax_t transfered = 0; timestamp_t *fdata = (timestamp_t *)src->ptr; time_t time_val = timestamp_gettime(fdata); if(fargs->dest == NULL || fdata == NULL) return -EINVAL; switch( fargs->format ){ case FORMAT(native):; case FORMAT(packed):; fastcall_write r_write = { { 5, ACTION_WRITE }, 0, &time_val, sizeof(time_val) }; ret = data_query(fargs->dest, &r_write); transfered = r_write.buffer_size; break; default: if( (ret = timestamp_to_string(time_val, buffer, &buffer_size, fargs->format)) != 0) return ret; fastcall_write r_write2 = { { 5, ACTION_WRITE }, 0, &buffer, buffer_size }; ret = data_query(fargs->dest, &r_write2); transfered = r_write.buffer_size; break; } if(fargs->header.nargs >= 5) fargs->transfered = transfered; return ret; } // }}}
ssize_t action_write_to_fast(void *userdata, request_t *request, f_hash_to_fast callback){ // {{{ ssize_t ret; data_t *r_buffer; data_t *r_size; uintmax_t offset = 0; uintmax_t size = ~0; hash_data_get(ret, TYPE_UINTT, offset, request, HK(offset)); if( (r_size = hash_data_find(request, HK(size))) != NULL){ data_get(ret, TYPE_UINTT, size, r_size); } if( (r_buffer = hash_data_find(request, HK(buffer))) == NULL) return -EINVAL; data_t d_slice = DATA_SLICET(userdata, offset, size); // FIXME fastcall_convert_to r_convert = { { 5, ACTION_CONVERT_TO }, &d_slice, FORMAT(native) }; ret = data_query(r_buffer, &r_convert); fastcall_write r_write = { { 5, ACTION_WRITE }, 0, &r_convert.transfered, sizeof(r_convert.transfered) }; if(r_size) data_query(r_size, &r_write); return ret; } // }}}
ssize_t data_default_compare (data_t *data1, fastcall_compare *fargs){ // {{{ ssize_t ret; char buffer1[DEF_BUFFER_SIZE], buffer2[DEF_BUFFER_SIZE]; uintmax_t buffer1_size, buffer2_size, cmp_size; uintmax_t offset1, offset2, goffset1, goffset2; if(fargs->data2 == NULL) return -EINVAL; goffset1 = goffset2 = 0; buffer1_size = buffer2_size = 0; do { if(buffer1_size == 0){ fastcall_read r_read = { { 5, ACTION_READ }, goffset1, &buffer1, sizeof(buffer1) }; if( (ret = data_query(data1, &r_read)) < -1) return ret; if(ret == -1 && buffer2_size != 0){ fargs->result = 1; break; } buffer1_size = r_read.buffer_size; goffset1 += r_read.buffer_size; offset1 = 0; } if(buffer2_size == 0){ fastcall_read r_read = { { 5, ACTION_READ }, goffset2, &buffer2, sizeof(buffer2) }; if( (ret = data_query(fargs->data2, &r_read)) < -1) return ret; if(ret == -1 && buffer1_size != 0){ fargs->result = 2; break; } if(ret == -1){ fargs->result = 0; break; } buffer2_size = r_read.buffer_size; goffset2 += r_read.buffer_size; offset2 = 0; } cmp_size = MIN(buffer1_size, buffer2_size); if( (ret = memcmp(buffer1 + offset1, buffer2 + offset2, cmp_size)) != 0){ fargs->result = (ret < 0) ? 1 : 2; break; } offset1 += cmp_size; offset2 += cmp_size; buffer1_size -= cmp_size; buffer2_size -= cmp_size; }while(1); return 0; } // }}}
static ssize_t data_list_t_convert_to(data_t *src, fastcall_convert_to *fargs){ // {{{ ssize_t ret = 0; ssize_t qret; list_chunk_t *chunk; list_t *fdata = (list_t *)src->ptr; data_t sl_output = DATA_SLIDERT(fargs->dest, 0); switch(fargs->format){ case FORMAT(packed):; for(chunk = fdata->head; chunk; chunk = chunk->cnext){ // remove ref_t from top hash_t r_key[] = { { 0, DATA_HASHKEYT(HK(data)) }, hash_end }; data_t d_key = DATA_PTR_HASHT(r_key); fastcall_control r_control = { { 5, ACTION_CONTROL }, HK(data), &d_key, NULL }; if( (ret = data_query(&chunk->data, &r_control)) < 0) break; data_t d_data = DATA_PTR_DATAT(r_control.value); fastcall_convert_to r_convert = { { 5, ACTION_CONVERT_TO }, &sl_output, FORMAT(packed) }; ret = data_query(&d_data, &r_convert); data_slider_t_set_offset(&sl_output, r_convert.transfered, SEEK_CUR); if(ret < 0) break; } // terminate list data_t terminator = { TYPE_LISTENDT, NULL }; data_t d_data = DATA_PTR_DATAT(&terminator); fastcall_convert_to r_convert = { { 5, ACTION_CONVERT_TO }, &sl_output, FORMAT(packed) }; qret = data_query(&d_data, &r_convert); data_slider_t_set_offset(&sl_output, r_convert.transfered, SEEK_CUR); if(qret < 0) ret = qret; break; default: return -ENOSYS; } if(fargs->header.nargs >= 5) fargs->transfered = data_slider_t_get_offset(&sl_output); return ret; } // }}}
uint64_t MurmurHash64A ( data_t *data, unsigned int seed ){ fastcall_length r_len = { { 4, ACTION_LENGTH }, 0, FORMAT(clean) }; if( data_query(data, &r_len) != 0 ) return 0; char buffer[8*BUFFER_ROUNDS]; uintmax_t offset = 0; const uint64_t *p; const uint64_t *p_end; const uint64_t m = 0xc6a4a7935bd1e995; const int r = 47; uint64_t h = seed ^ (r_len.length * m); while(1){ fastcall_read r_read = { { 5, ACTION_READ }, offset, &buffer, sizeof(buffer) }; if(data_query(data, &r_read) != 0) return 0; p = (const uint64_t *)buffer; p_end = p + (r_read.buffer_size / 8); offset += r_read.buffer_size; while(p != p_end) { uint64_t k = *p++; k *= m; k ^= k >> r; k *= m; h ^= k; h *= m; } if(r_read.buffer_size != sizeof(buffer)) break; } const unsigned char * p2 = (const unsigned char*)p; switch(r_len.length & 7) { case 7: h ^= (uint64_t)p2[6] << 48; case 6: h ^= (uint64_t)p2[5] << 40; case 5: h ^= (uint64_t)p2[4] << 32; case 4: h ^= (uint64_t)p2[3] << 24; case 3: h ^= (uint64_t)p2[2] << 16; case 2: h ^= (uint64_t)p2[1] << 8; case 1: h ^= (uint64_t)p2[0]; h *= m; }; h ^= h >> r; h *= m; h ^= h >> r; return h; }
static ssize_t data_pcre_t_enum(data_t *data, fastcall_enum *fargs){ // {{{ ssize_t ret; int ovector[1 * 3]; void *data_ptr; uintmax_t data_size; data_t freeit; data_t *deref; uintmax_t offset = 0; pcre_t *fdata = (pcre_t *)data->ptr; if(fdata->data == NULL) return errorn(ENOSYS); if( (ret = data_make_flat(fdata->data, FORMAT(native), &freeit, &data_ptr, &data_size)) < 0){ data_free(&freeit); return ret; } // deref fdata->data data_realholder(ret, fdata->data, deref); if(ret < 0){ data_free(&freeit); return ret; } while(1){ if(pcre_exec( fdata->re, NULL, data_ptr, data_size, offset, fdata->options, ovector, (sizeof(ovector) / sizeof(ovector[0])) ) < 0) goto exit; data_t d_item = DATA_HEAP_SLICET(deref, ovector[0], ovector[1] - ovector[0]); fastcall_push r_push_item = { { 3, ACTION_PUSH }, &d_item }; ret = data_query(fargs->dest, &r_push_item); data_free(&d_item); if(ret < 0) goto exit; offset = ovector[1]; } ret = 0; exit:; fastcall_push r_push_end = { { 3, ACTION_PUSH }, NULL }; data_query(fargs->dest, &r_push_end); data_free(&freeit); return ret; } // }}}
static ssize_t data_uint16_t_convert_from(data_t *dst, fastcall_convert_from *fargs){ // {{{ ssize_t ret; char *endptr; char buffer[DEF_BUFFER_SIZE]; uintmax_t transfered = 0; if(fargs->src == NULL) return -EINVAL; #ifndef OPTIMIZE_UINT if(dst->ptr == NULL){ // no buffer, alloc new if( (dst->ptr = malloc(sizeof(uint16_t))) == NULL) return -ENOMEM; } #endif switch( fargs->format ){ case FORMAT(config):; case FORMAT(human):; // TODO fix it for slider_t fastcall_read r_read_str = { { 5, ACTION_READ }, 0, &buffer, sizeof(buffer) - 1 }; if( (ret = data_query(fargs->src, &r_read_str)) < 0){ // TODO memleak return ret; } buffer[r_read_str.buffer_size] = '\0'; SET_TYPE_UINT16T(dst) = (void *)((uintmax_t)((uint16_t )strtoul(buffer, &endptr, 10))); transfered = (endptr - buffer); break; case FORMAT(native):; case FORMAT(packed):; if(fargs->src->type == dst->type){ SET_TYPE_UINT16T(dst) = (void *)((uintmax_t) DEREF_TYPE_UINT16T(fargs->src)); ret = 0; }else{ fastcall_read r_read = { { 5, ACTION_READ }, 0, &buffer, sizeof(uint16_t) }; if( (ret = data_query(fargs->src, &r_read)) < 0){ // TODO memleak return ret; } SET_TYPE_UINT16T(dst) = (void *)((uintmax_t)(*((uint16_t *)buffer))); } transfered = sizeof(uint16_t); break; default: return -ENOSYS; }; if(fargs->header.nargs >= 5) fargs->transfered = transfered; return 0; } // }}}
static ssize_t data_length_t_handler(data_t *data, fastcall_header *hargs){ // {{{ ssize_t ret; length_t *fdata = (length_t *)data->ptr; fastcall_length r_len = { { 4, ACTION_LENGTH }, 0, fdata->format }; if( (ret = data_query(&fdata->data, &r_len)) < 0) return ret; data_t d_length = DATA_PTR_UINTT(&r_len.length); return data_query(&d_length, hargs); } // }}}
static ssize_t chm_imp_unload (mphf_t *mphf){ // {{{ chm_imp_t *data = (chm_imp_t *)&mphf->data; // save .params chm_imp_param_write(mphf); fastcall_free r_free = { { 2, ACTION_FREE } }; data_query(&data->be_g, &r_free); data_query(&data->be_e, &r_free); data_query(&data->be_v, &r_free); return 0; } // }}}
static ssize_t allocator_new(allocator_fixed_t **pfdata, hash_t *config){ // {{{ ssize_t ret; data_t *sample; allocator_fixed_t *fdata; if((fdata = calloc(1, sizeof(allocator_fixed_t))) == NULL) return error("calloc failed"); pthread_rwlock_init(&fdata->rwlock, NULL); // get removed items tracker hash_holder_consume(ret, fdata->removed_items, config, HK(removed_items)); hash_holder_consume(ret, fdata->storage, config, HK(storage)); if(ret != 0){ ret = error("invalid storage supplied"); goto error; } hash_data_get(ret, TYPE_UINTT, fdata->item_size, config, HK(item_size)); if(ret != 0){ if( (sample = hash_data_find(config, HK(item_sample))) == NULL){ ret = error("no item_size nor item_sample supplied"); goto error; } fastcall_length r_len = { { 4, ACTION_LENGTH }, 0, FORMAT(binary) }; if( data_query(sample, &r_len) != 0 ){ ret = error("bad item_sample"); goto error; } fdata->item_size = r_len.length; } if(fdata->item_size == 0){ ret = error("bad item size"); goto error; } // get last id fastcall_length r_len = { { 4, ACTION_LENGTH }, 0, FORMAT(clean) }; if( data_query(&fdata->storage, &r_len) != 0){ ret = error("bad underlying storage"); goto error; } fdata->last_id = r_len.length / fdata->item_size; *pfdata = fdata; return 0; error: allocator_destroy(fdata); return ret; } // }}}
ssize_t data_default_enum (data_t *data, fastcall_enum *fargs){ // {{{ ssize_t ret; data_t immortal = DATA_IMMORTALT(data); fastcall_create r_create = { { 4, ACTION_CREATE }, NULL, &immortal }; fastcall_create r_end = { { 4, ACTION_CREATE }, NULL, NULL }; ret = data_query(fargs->dest, &r_create); data_query(fargs->dest, &r_end); return ret; } // }}}
static ssize_t chm_imp_destroy (mphf_t *mphf){ // {{{ chm_imp_t *data = (chm_imp_t *)&mphf->data; fastcall_resize r_resize = { { 3, ACTION_RESIZE }, 0 }; if(data_query(&data->be_g, &r_resize) < 0) return error("g array resize failed"); if(data_query(&data->be_e, &r_resize) < 0) return error("e array resize failed"); if(data_query(&data->be_v, &r_resize) < 0) return error("v array resize failed"); return 0; } // }}}
ssize_t ipc_shmem_query (ipc_t *ipc, request_t *request){ // {{{ ssize_t ret; uintmax_t f_async = 0; data_t *buffer; ipc_shmem_block *block; ipc_shmem_userdata *userdata = (ipc_shmem_userdata *)ipc->userdata; // check async state switch(userdata->forced_state){ case FORCE_SYNC: break; // already == 0 case FORCE_ASYNC: f_async = 1; break; case FORCE_NONE: hash_data_get(ret, TYPE_UINTT, f_async, request, HK(async)); break; }; buffer = hash_data_find(request, userdata->buffer); // send request if( (block = shmem_get_block(userdata, STATUS_FREE, STATUS_WRITING)) == NULL) return error("strange error"); // write data to ipc memory data_t d_ipcmem = DATA_RAW(userdata->shmdata + block->data_rel_ptr, userdata->shmaddr->item_size); fastcall_convert_to r_convert = { { 4, ACTION_CONVERT_TO }, &d_ipcmem, FORMAT(packed) }; if( (ret = data_query(buffer, &r_convert)) < 0) return error("can not write buffer to ipc memory"); //block->size = r_read.buffer_size; block->return_result = (f_async == 0) ? 1 : 0; if( (ret = shmem_block_status(userdata, block, STATUS_WRITING, STATUS_WRITTEN)) < 0) return ret; if(f_async == 0){ // synchronous request // wait for answer sem_wait(&block->sem_done); // read request back if(userdata->return_result != 0){ fastcall_convert_from r_convert_from = { { 5, ACTION_CONVERT_FROM }, &d_ipcmem, FORMAT(packed) }; data_query(buffer, &r_convert_from); } ret = 0; if(shmem_block_status(userdata, block, STATUS_EXEC_DONE, STATUS_FREE) < 0) return error("strange error 3"); }else{ ret = 0; // success } return ret; } // }}}
static ssize_t data_triplet_format_t_lookup(data_t *data, fastcall_crud *fargs) { // {{{ ssize_t ret; uintmax_t offset; data_t converted; data_t d_key; data_t *d_key_ptr = &d_key; data_t storage_item; triplet_format_t *fdata = (triplet_format_t *)data->ptr; // fetch value from storage data_t sl_key = DATA_SLICET(fargs->key, 1, ~0); fastcall_lookup r_lookup = { { 4, ACTION_LOOKUP }, &sl_key, &storage_item }; if( (ret = data_query(&fdata->storage, &r_lookup)) < 0) return ret; // get offset for this data if(helper_key_current(fargs->key, &d_key) < 0) { d_key_ptr = fargs->key; data_get(ret, TYPE_UINTT, offset, d_key_ptr); } else { data_get(ret, TYPE_UINTT, offset, d_key_ptr); data_free(&d_key); } if(ret < 0) return ret; data_t sl_value = DATA_SLICET(&storage_item, offset, ~0); fastcall_unpack r_unpack = { { 4, ACTION_UNPACK }, offset == 0 ? &storage_item : &sl_value, &converted, FORMAT(packed) }; if( (ret = data_query(&fdata->slave, &r_unpack)) < 0) goto exit; *fargs->value = converted; exit: data_free(&storage_item); return ret; } // }}}
/*static ssize_t data_env_t_copy(data_t *src, fastcall_copy *fargs){ // {{{ env_t *fdata = (env_t *)src->ptr; env_t *new_fdata = NULL; if(fargs->dest == NULL) return -EINVAL; if(fdata){ if( (new_fdata = malloc(sizeof(env_t))) == NULL) return -EINVAL; new_fdata->key = fdata->key; } fargs->dest->type = src->type; fargs->dest->ptr = new_fdata; return 0; } // }}}*/ static ssize_t data_env_t_convert_from(data_t *dst, fastcall_convert_from *fargs){ // {{{ ssize_t ret; env_t *fdata; if(dst->ptr != NULL) return data_env_t_handler(dst, (fastcall_header *)fargs); // already inited - pass to underlying data if(fargs->src == NULL) return -EINVAL; if( (ret = data_env_t_alloc(dst, NULL)) != 0) return ret; fdata = (env_t *)dst->ptr; switch(fargs->format){ case FORMAT(config):; case FORMAT(human):; data_t hkey = DATA_PTR_HASHKEYT(&fdata->key); fastcall_convert_from r_convert = { { 4, ACTION_CONVERT_FROM }, fargs->src, fargs->format }; return data_query(&hkey, &r_convert); default: break; } return -ENOSYS; } // }}}
static void allocator_destroy(allocator_fixed_t *fdata){ // {{{ fastcall_free r_free = { { 2, ACTION_FREE } }; data_query(&fdata->storage, &r_free); pthread_rwlock_destroy(&fdata->rwlock); free(fdata); } // }}}
ssize_t container_write (container_t *container, uintmax_t offset, void *buf, uintmax_t buf_size, uintmax_t *pwritten){ // {{{ ssize_t ret = -1; // EOF uintmax_t written = 0; container_process( container, offset, buf_size, do{ fastcall_write r_write; r_write.header.nargs = 5; r_write.header.action = ACTION_WRITE; r_write.offset = chunk_offset; r_write.buffer = buf + written; r_write.buffer_size = chunk_size; if( (ret = data_query(chunk_data, &r_write)) < 0) return ret; written += r_write.buffer_size; }while(0) ); if(pwritten) *pwritten = written; return ret; } // }}}
ssize_t container_read (container_t *container, uintmax_t offset, void *buf, uintmax_t buf_size, uintmax_t *pbuf_size){ // {{{ ssize_t ret = -1; // EOF uintmax_t read = 0; container_process( container, offset, buf_size, do{ fastcall_read r_read; r_read.header.nargs = 5; r_read.header.action = ACTION_READ; r_read.offset = chunk_offset; r_read.buffer = buf + read; r_read.buffer_size = chunk_size; if( (ret = data_query(chunk_data, &r_read)) < 0) return ret; read += r_read.buffer_size; }while(0) ); if(pbuf_size) *pbuf_size = read; return ret; } // }}}
ssize_t data_default_write (data_t *data, fastcall_write *fargs){ // {{{ ssize_t ret; fastcall_view r_view = { { 6, ACTION_VIEW }, FORMAT(native) }; if( (ret = data_query(data, &r_view)) < 0) return ret; if(r_view.length == 0){ fargs->buffer_size = 0; data_free(&r_view.freeit); return -1; // EOF } if(fargs->buffer == NULL || fargs->offset > r_view.length){ data_free(&r_view.freeit); return -EINVAL; // invalid range } fargs->buffer_size = MIN(fargs->buffer_size, r_view.length - fargs->offset); if(fargs->buffer_size == 0){ data_free(&r_view.freeit); return -1; // EOF } memcpy(r_view.ptr + fargs->offset, fargs->buffer, fargs->buffer_size); data_free(&r_view.freeit); return 0; } // }}}
static void chunk_free(container_chunk_t *chunk){ // {{{ if( (chunk->flags & CHUNK_DONT_FREE) == 0){ fastcall_free r_free = { { 2, ACTION_FREE } }; data_query(&chunk->data, &r_free); } free(chunk); } // }}}
ssize_t default_transfer(data_t *src, data_t *dest, uintmax_t read_offset, uintmax_t write_offset, uintmax_t size, uintmax_t *ptransfered){ // {{{ ssize_t ret; uintmax_t roffset = read_offset; uintmax_t woffset = write_offset; uintmax_t bytes_written = 0; uintmax_t bytes_read; char buffer[DEF_BUFFER_SIZE]; // first read fastcall_read r_read = { { 5, ACTION_READ }, roffset, &buffer, MIN(size, sizeof(buffer)) }; if( (ret = data_query(src, &r_read)) < 0) // EOF return too return ret; bytes_read = r_read.buffer_size; roffset += r_read.buffer_size; size -= r_read.buffer_size; goto start; do { fastcall_read r_read = { { 5, ACTION_READ }, roffset, &buffer, MIN(size, sizeof(buffer)) }; if( (ret = data_query(src, &r_read)) < -1) return ret; if(ret == -1) // EOF from read side break; bytes_read = r_read.buffer_size; roffset += r_read.buffer_size; size -= r_read.buffer_size; start:; fastcall_write r_write = { { 5, ACTION_WRITE }, woffset, &buffer, bytes_read }; if( (ret = data_query(dest, &r_write)) < -1) return ret; if(ret == -1) // EOF from write side break; bytes_written += r_write.buffer_size; woffset += r_write.buffer_size; }while(size > 0); if(ptransfered) *ptransfered = bytes_written; return 0; } // }}}
static ssize_t chm_imp_param_write(mphf_t *mphf){ // {{{ chm_imp_t *data = (chm_imp_t *)&mphf->data; fastcall_write r_write = { { 5, ACTION_WRITE }, 0, &data->params, sizeof(data->params) }; if(data_query(&data->be_g, &r_write) < 0) return error("params write failed"); return 0; } // }}}
static ssize_t data_triplet_format_single_t_enum(data_t *data, fastcall_enum *fargs) { // {{{ ssize_t ret; triplet_format_t *fdata = (triplet_format_t *)data->ptr; if(data_is_void(&fdata->storage)) return -EINVAL; enum_userdata userdata = { &fdata->slave, fargs }; data_t iot = DATA_IOT(&userdata, (f_io_func)&data_triplet_format_single_t_iter_iot); fastcall_enum r_enum = { { 3, ACTION_ENUM }, &iot }; ret = data_query(&fdata->storage, &r_enum); // last fastcall_create r_end = { { 3, ACTION_CREATE }, NULL, NULL }; data_query(fargs->dest, &r_end); return ret; } // }}}
static ssize_t data_action_t_convert_to(data_t *src, fastcall_convert_to *fargs){ // {{{ ssize_t ret; action_t value; uintmax_t transfered; keypair_t *kp; char *string = "(unknown)"; if(fargs->dest == NULL || src->ptr == NULL) return -EINVAL; value = *(action_t *)src->ptr; switch(fargs->format){ case FORMAT(config):; case FORMAT(clean):; case FORMAT(human):; // find in static keys first for(kp = &actions[0]; kp->key_str != NULL; kp++){ if(kp->key_val == value){ string = kp->key_str; goto found; } } found:; fastcall_write r_write = { { 5, ACTION_WRITE }, 0, string, strlen(string) }; ret = data_query(fargs->dest, &r_write); transfered = r_write.buffer_size; break; case FORMAT(binary):; fastcall_write r_write2 = { { 5, ACTION_WRITE }, 0, &value, sizeof(value) }; ret = data_query(fargs->dest, &r_write2); transfered = r_write.buffer_size; break; default: return -ENOSYS; } if(fargs->header.nargs >= 5) fargs->transfered = transfered; return ret; } // }}}
static ssize_t data_timestamp_t_convert_from(data_t *dst, fastcall_convert_from *fargs){ // {{{ ssize_t ret; char buffer[DEF_BUFFER_SIZE]; uintmax_t transfered; timestamp_t *fdata; if(fargs->src == NULL) return -EINVAL; if(dst->ptr == NULL){ // no buffer, alloc new if( (dst->ptr = malloc(sizeof(timestamp_t))) == NULL) return -ENOMEM; } fdata = (timestamp_t *)dst->ptr; switch( fargs->format ){ case FORMAT(config):; case FORMAT(human):; fastcall_read r_read_str = { { 5, ACTION_READ }, 0, &buffer, sizeof(buffer) - 1 }; if( (ret = data_query(fargs->src, &r_read_str)) < 0) return ret; ret = timestamp_from_string(fdata, buffer, &r_read_str.buffer_size); transfered = r_read_str.buffer_size; break; case FORMAT(native):; case FORMAT(packed):; fdata->now = 0; fastcall_read r_read = { { 5, ACTION_READ }, 0, &fdata->time, sizeof(fdata->time) }; ret = data_query(fargs->src, &r_read); transfered = r_read.buffer_size; break; default: return -ENOSYS; }; if(fargs->header.nargs >= 5) fargs->transfered = transfered; return ret; } // }}}
static ssize_t data_length_t_free(data_t *data, fastcall_free *hargs){ // {{{ length_t *fdata = (length_t *)data->ptr; fastcall_free r_free = { { 2, ACTION_FREE } }; data_query(&fdata->data, &r_free); free(fdata); data->ptr = NULL; return 0; } // }}}