diff --git a/binding.gyp b/binding.gyp index 4912e28..b4f686c 100644 --- a/binding.gyp +++ b/binding.gyp @@ -16,6 +16,7 @@ 'src/storage_pool.cc', 'src/storage_volume.cc', # 'src/domain.cc', + 'src/libvirt_handle.cc' ], 'include_dirs' : [ " +#include "libvirt_handle.h" + +namespace NodeLibvirt { + + + +struct LibVirtHandlePrivate +{ + LibVirtHandlePrivate() { + data.connection = 0; + data.interface = 0; + data.network = 0; + } + + union Data { + virConnectPtr connection; + virInterfacePtr interface; + virNetworkPtr network; + } data; +}; + +LibVirtHandle::LibVirtHandle() + : d(new LibVirtHandlePrivate) +{ +} + +LibVirtHandle::LibVirtHandle(virConnectPtr connection) + : d(new LibVirtHandlePrivate) +{ + d->data.connection = connection; +} + +LibVirtHandle::LibVirtHandle(virInterfacePtr interface) + : d(new LibVirtHandlePrivate) +{ + d->data.interface = interface; +} + +LibVirtHandle::LibVirtHandle(virNetworkPtr network) + : d(new LibVirtHandlePrivate) +{ + d->data.network = network; +} + +LibVirtHandle::~LibVirtHandle() +{ +} + +void LibVirtHandle::Clear() +{ + d->data.connection = 0; + + if (d->data.interface) + virInterfaceFree(d->data.interface); + d->data.interface = 0; + + if (d->data.network) + virNetworkFree(d->data.network); + d->data.network = 0; +} + +virConnectPtr LibVirtHandle::ToConnection() const +{ + return d->data.connection; +} + +virInterfacePtr LibVirtHandle::ToInterface() const +{ + return d->data.interface; +} + +virNetworkPtr LibVirtHandle::ToNetwork() const +{ + return d->data.network; +} + +} // namespace NodeLibvirt diff --git a/src/libvirt_handle.h b/src/libvirt_handle.h new file mode 100644 index 0000000..9a6e5b3 --- /dev/null +++ b/src/libvirt_handle.h @@ -0,0 +1,33 @@ +#ifndef LIBVIRT_HANDLE_H +#define LIBVIRT_HANDLE_H + +#include +#include +using namespace std; + +namespace NodeLibvirt { + +class LibVirtHandlePrivate; +class LibVirtHandle +{ +public: + LibVirtHandle(); + ~LibVirtHandle(); + LibVirtHandle(virConnectPtr connection); + LibVirtHandle(virInterfacePtr interface); + LibVirtHandle(virNetworkPtr network); + + void Clear(); + + virConnectPtr ToConnection() const; + virInterfacePtr ToInterface() const; + virNetworkPtr ToNetwork() const; + +private: + shared_ptr d; + +}; + +} // namespace NodeLibvirt + +#endif // LIBVIRT_HANDLE_H diff --git a/src/worker_macros.h b/src/worker_macros.h new file mode 100644 index 0000000..a3f4f28 --- /dev/null +++ b/src/worker_macros.h @@ -0,0 +1,91 @@ +#ifndef WORKER_MACROS_H +#define WORKER_MACROS_H + +// UTIL +#define NLV_CATNX(A, B) A ## B +#define NLV_CAT(A, B) NLV_CATNX(A, B) + +// ASSERTIONS +#define NLV_WORKER_ASSERT_CONNECTION() \ + if (Handle().ToConnection() == NULL) { \ + SetErrorMessage("invalid connection"); \ + return; \ + } + +#define NLV_WORKER_ASSERT_INTERFACE() \ + if (Handle().ToInterface() == NULL) { \ + SetErrorMessage("invalid interface"); \ + return; \ + } + +#define NLV_WORKER_ASSERT_NETWORK() \ + if (Handle().ToNetwork() == NULL) { \ + SetErrorMessage("invalid network"); \ + return; \ + } + + +// METHOD HELPERS +#define NLV_WORKER_METHOD_NO_ARGS(Class, Method) \ +NAN_METHOD(Class::Method) { \ + NanScope(); \ + if (args.Length() == 1 && !args[0]->IsFunction()) { \ + NanThrowTypeError("You must specify a function as first argument"); \ + NanReturnUndefined(); \ + } \ + NanCallback *callback = new NanCallback(args[0].As()); \ + Class *object = ObjectWrap::Unwrap(args.This()); \ + NanAsyncQueueWorker(new Method##Worker(callback, object->handle_)); \ + NanReturnUndefined(); \ +} + +// WORKER DEFINITIONS +#define NLV_PRIMITIVE_RETURN_WORKER(Method, HandleType, Type) \ + class Method##Worker : public PrimitiveReturnWorker { \ + public: \ + Method##Worker(NanCallback *callback, HandleType handle) \ + : PrimitiveReturnWorker(callback, handle) {} \ + void Execute(); \ + }; + +#define NLV_LOOKUP_BY_VALUE_WORKER(Class, Method) \ + class Method##Worker : public LookupInstanceByValueWorker { \ + public: \ + Method##Worker(NanCallback *callback, const LibVirtHandle &handle, const std::string &value) \ + : LookupInstanceByValueWorker(callback, handle, value) {} \ + void Execute(); \ + }; + +// EXECUTE HELPERS +#define NLV_INT_RETURN_EXECUTE(Class, Method, Accessor) \ + void Class::Method##Worker::Execute() { \ + HYPERVISOR_ASSERT_CONNECTION(); \ + int result = Accessor(Handle().ToConnection()); \ + if (result == -1) { \ + SetVirError(virGetLastError()); \ + return; \ + } \ + data_ = result; \ + } + +#define NLV_BOOL_RETURN_EXECUTE(Class, Method, Accessor) \ + void Class::Method##Worker::Execute() { \ + HYPERVISOR_ASSERT_CONNECTION(); \ + int result = Accessor(Handle().ToConnection()); \ + if (result == -1) { \ + SetVirError(virGetLastError()); \ + return; \ + } \ + data_ = static_cast(result); \ + } + +#define NLV_LOOKUP_BY_VALUE_EXECUTE(Class, Method, Accessor) \ + void Class::Method##Worker::Execute() { \ + lookupHandle_ = Accessor(Handle().ToConnection(), value_.c_str()); \ + if (lookupHandle_.NLV_CAT(To, Class)() == NULL) { \ + SetVirError(virGetLastError()); \ + return; \ + } \ + } + +#endif // WORKER_MACROS_H