%module{ZeroMQ}; %package{ZeroMQ}; %{ #include INCLUDE: const-xs.inc %} %loadplugin{Cloning}; // catch the error_t exceptions with a helpful message %exception{ZMQException}{zmq::error_t}{stdmessage}; ///////////////////////////////////////////////////////////////////////// %name{ZeroMQ::Context} class context_t %catch{ZMQException} { %PreventCloning; %name{new} context_t(int io_threads = 1); ~context_t(); }; ///////////////////////////////////////////////////////////////////////// %name{ZeroMQ::Socket} class socket_t %catch{ZMQException} { %PreventCloning; %name{new} socket_t(context_t& context, int type); ~socket_t(); %{ void socket_t::getsockopt(option_name) int option_name; PPCODE: dXSTARG; size_t len = sizeof(int64_t); try { switch (option_name) { case ZMQ_RCVMORE: case ZMQ_HWM: case ZMQ_SWAP: case ZMQ_AFFINITY: { int64_t rv = 123; THIS->getsockopt(option_name, (void*)&rv, &len); XPUSHi((IV)rv); } break; case ZMQ_IDENTITY: { void* rv; Newx(rv, 255, char); len = 255; THIS->getsockopt(option_name, (void*)&rv, &len); XPUSHs(sv_2mortal(newSVpv((char*)rv, len))); Safefree(rv); } break; case ZMQ_RATE: case ZMQ_RECOVERY_IVL: case ZMQ_MCAST_LOOP: case ZMQ_SNDBUF: case ZMQ_RCVBUF: { uint64_t rv = 123; // Note: sizeof(uint64_t) == sizeof(int64_t) so this isn't strictly necessary: len = sizeof(uint64_t); THIS->getsockopt(option_name, (void*)&rv, &len); XPUSHu((UV)rv); } break; default: XPUSHs(&PL_sv_undef); break; }; } /* end try */ catch (zmq::error_t& e) { croak("Caught C++ exception of type or derived from 'zmq::error_t': %s", e.what()); } catch (...) { croak("Caught C++ exception of unknown type"); } %} void setsockopt(int option_name, char* option_value, size_t %length{option_value}) %code{% dXSTARG; try { switch (option_name) { case ZMQ_HWM: case ZMQ_SWAP: case ZMQ_AFFINITY: { int64_t v = atoi(option_value); THIS->setsockopt(option_name, (void*)&v, sizeof(int64_t)); } break; case ZMQ_IDENTITY: case ZMQ_SUBSCRIBE: case ZMQ_UNSUBSCRIBE: { THIS->setsockopt(option_name, (void*)option_value, length(option_value)); } break; case ZMQ_RATE: case ZMQ_RECOVERY_IVL: case ZMQ_MCAST_LOOP: case ZMQ_SNDBUF: case ZMQ_RCVBUF: { uint64_t v = atoi(option_value); THIS->setsockopt(option_name, (void*)&v, sizeof(uint64_t)); } break; //default: /*throw zmq::error_t(); // reads errnum...*/ }; } /* end try */ catch (zmq::error_t& e) { croak("Caught C++ exception of type or derived from 'zmq::error_t': %s", e.what()); } catch (...) { croak("Caught C++ exception of unknown type"); } %}; //void socket_t::setsockopt(int option_name, const void *option_value, size_t option_len) void bind(char* endpoint); void connect(char* endpoint); bool send(message_t& msg, int flags = 0); //bool recv(message_t* msg, int flags = 0); // FIXME needs exception handling... {% void socket_t::recv(flags = 0) int flags; PPCODE: message_t* rv = new message_t(); try { if (!THIS->recv(rv, flags)) { delete rv; XPUSHs(&PL_sv_undef); } else { XPUSHmortal; sv_setref_pv(ST(0), "ZeroMQ::Message", (void*)rv); } } catch (zmq::error_t& e) { delete rv; croak("Caught C++ exception of type or derived from 'zmq::error_t': %s", e.what()); } catch (...) { delete rv; croak("Caught C++ exception of unknown type"); } %} }; ///////////////////////////////////////////////////////////////////////// %name{ZeroMQ::Message} class message_t %catch{ZMQException} { %PreventCloning; %name{new} message_t(char* data, size_t %length{data}) %code{% /* Note: we need to copy data and provide a cleanup function */ RETVAL = new zmq::message_t(data, length(data), NULL); %}; //%name{new} message_t(); //%name{new} message_t(size_t size_); //%name{new} message_t(MsgData* data, size_t size_, free_fn *ffn_, void *hint_ = NULL); ~message_t(); size_t size(); //MsgData* data(); %{ void message_t::data() PPCODE: XPUSHs(sv_2mortal(newSVpv((char*)THIS->data(), THIS->size()))); %} };