static inline int match_record(ErlNifEnv* env, int arity, const ERL_NIF_TERM *tuple, State *st){ EncRecord *records = enc_records_base(st->records); EncField *fields = enc_fields_base(st->records); int i, k; for(i = 0; i < st->records->records_cnt; i++){ if(records[i].tag == tuple[0] && records[i].arity == (arity -1)){ unsigned fds_offset = records[i].fds_offset; unsigned bin_size = 0; b_putc('{', st); for(k = 0; k < records[i].arity; k++){ EncField field = fields[fds_offset + k]; bin_size += field.size; //FIXME { b_puts(field.size, st->records->bin.data + field.offset, st); if(!match_term(env, tuple[k+1], st)) return 0; } b_putc('}', st); return 1; } } return 0; }
ERL_NIF_TERM make_encoder_resource_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]){ unsigned rs_len, fs_len, bin_sz; enif_get_uint(env, argv[0], &rs_len); enif_get_uint(env, argv[1], &fs_len); enif_get_uint(env, argv[4], &bin_sz); PrivData* priv = (PrivData*)enif_priv_data(env); unsigned resource_sz = enc_resource_size(rs_len, fs_len); EncEntry *enc_entry = (EncEntry*)enif_alloc_resource(priv->encoder_RSTYPE, resource_sz); //memset(enc_entry, 0, resource_sz); enc_entry->records_cnt = rs_len; enc_entry->fields_cnt = fs_len; if(!enif_alloc_binary(bin_sz + 1, &enc_entry->bin)) goto error; //memset(enc_entry->bin.data, 0, bin_sz + 1); ErlNifBinary ebin; enif_inspect_binary(env, argv[5], &ebin); memcpy(enc_entry->bin.data, ebin.data , ebin.size); ERL_NIF_TERM list, head, tail; list = argv[2]; int i = 0; while(enif_get_list_cell(env, list, &head, &tail)){ const ERL_NIF_TERM *tuple; int arity; unsigned ip; enif_get_tuple(env, head, &arity, &tuple); EncRecord *records = enc_records_base(enc_entry); records[i].tag = tuple[0]; enif_get_uint(env, tuple[1], &ip); records[i].fds_offset = ip; enif_get_uint(env, tuple[2], &ip); records[i].arity = ip; i++; list = tail; } list = argv[3]; i = 0; while(enif_get_list_cell(env, list, &head, &tail)){ const ERL_NIF_TERM *tuple; int arity; unsigned ip; enif_get_tuple(env, head, &arity, &tuple); EncField *fields = enc_fields_base(enc_entry); enif_get_uint(env, tuple[0], &ip); fields[i].offset = ip; enif_get_uint(env, tuple[1], &ip); fields[i].size = ip; i++; list = tail; } list = argv[6]; if(!enif_get_list_length(env, list, &(enc_entry->ignored_len))) goto error; enc_entry->ignored = (ERL_NIF_TERM*)enif_alloc(enc_entry->ignored_len*sizeof(ERL_NIF_TERM)); i = 0; while(enif_get_list_cell(env, list, &head, &tail)){ // ignored term should be atoms if(enif_is_atom(env, head)){ enc_entry->ignored[i] = head; }else{ enif_free(enc_entry->ignored); goto error; } i++; list = tail; } ERL_NIF_TERM ret = enif_make_resource(env, (void *)enc_entry); enif_release_resource(enc_entry); return ret; error: enif_release_resource(enc_entry); return enif_make_badarg(env); }