Skip to content

Instantly share code, notes, and snippets.

@argv0
Created April 7, 2010 22:52
Show Gist options
  • Save argv0/359552 to your computer and use it in GitHub Desktop.
Save argv0/359552 to your computer and use it in GitHub Desktop.
#include <string.h>
#include <string>
#include "riakserver_pb_nifs.h"
#include "riakserver.pb.h"
template <class T>
ERL_NIF_TERM pb_obj_to_binary(ErlNifEnv *env, const T& obj) {
ErlNifBinary res;
enif_alloc_binary(env, obj.ByteSize(), &res);
obj.SerializeToArray(res.data, res.size);
return enif_make_binary(env, &res);
}
template <class T>
inline ERL_NIF_TERM to_enb(const T& in, ErlNifBinary *out, ErlNifEnv *env) {
unsigned sz = in.size();
enif_alloc_binary(env, sz, out);
memcpy(out->data, in.c_str(), sz);
return enif_make_binary(env,out);
}
extern "C" {
ERL_NIF_TERM encode_riakobject_pb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
ERL_NIF_TERM decode_riakobject_pb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]);
static ErlNifFunc nif_funcs[] = {
{"encode_riakobject_pb", 1, encode_riakobject_pb},
{"decode_riakobject_pb", 1, decode_riakobject_pb},
};
ERL_NIF_INIT(riakserver_pb,nif_funcs,NULL,NULL,NULL,NULL);
ERL_NIF_TERM encode_riakobject_pb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
const ERL_NIF_TERM *in_elts;
int arity = 0;
if (enif_get_tuple(env, argv[0], &arity, &in_elts)) {
ErlNifBinary bucket, key, val;
if (!enif_inspect_binary(env, in_elts[1], &bucket)) return enif_make_badarg(env);
if (!enif_inspect_binary(env, in_elts[2], &key)) return enif_make_badarg(env);
if (!enif_inspect_binary(env, in_elts[3], &val)) return enif_make_badarg(env);
RiakObject_PB pb_obj;
pb_obj.set_key(key.data, key.size);
pb_obj.set_bucket(bucket.data, bucket.size);
pb_obj.set_val(val.data, val.size);
return pb_obj_to_binary(env, pb_obj);
}
return enif_make_badarg(env);
}
ERL_NIF_TERM decode_riakobject_pb(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
static ERL_NIF_TERM record_tag = enif_make_atom(env, "riakobject_pb");
ErlNifBinary input_bin, bucket, key, val;
RiakObject_PB obj;
if (enif_inspect_binary(env, argv[0], &input_bin))
if (!obj.ParseFromArray(input_bin.data, input_bin.size))
return enif_make_badarg(env);
return enif_make_tuple4(env,
record_tag,
to_enb(obj.bucket(), &bucket, env),
to_enb(obj.key(), &key, env),
to_enb(obj.val(), &val, env));
return enif_make_atom(env, "error");
}
} // extern "C"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment