/* Copyright 2009 Myhailo Danylenko
This file is part of lua-lm.
lua-lm is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include <lua.h>
#include <lauxlib.h>
#include <loudmouth/loudmouth.h>
#include "config.h"
#include "lm_types.h"
#include "util.h"
void llm_callback_destroy (llm_callback_t *cb)
{
D ("Destroying callback %p", cb);
luaL_unref (cb->L, LUA_REGISTRYINDEX, cb->reference);
luaL_free (cb->L, cb);
}
#define LLM_CHECK(WHAT, LWHAT, TYPE) \
llm_##WHAT##_t *luaL_checklm_##WHAT (lua_State *L, int index) \
{ \
llm_##WHAT##_t *object = luaL_checkudata (L, index, "loudmouth." #LWHAT); \
luaL_argcheck (L, object != NULL, index, "loudmouth " #WHAT " expected"); \
return object; \
}
#define LLM_BLESS(WHAT, LWHAT, TYPE) \
llm_##WHAT##_t *bless_lm_##WHAT (lua_State *L, TYPE *WHAT) \
{ \
llm_##WHAT##_t *object; /* top of stack */ \
lua_pushliteral (L, LLM_OBJREGISTRY); /* 1 registry table name */ \
lua_rawget (L, LUA_REGISTRYINDEX); /* 1 registry table */ \
lua_pushlightuserdata (L, WHAT); /* 2 light userdata */ \
lua_rawget (L, -2); /* 2 object/nil */ \
if (!lua_isnil (L, -1)) { /* 2 object */ \
lua_remove (L, -2); /* 1 object */ \
object = lua_touserdata (L, -1); \
D ("Existing " #LWHAT " object %p requested", object); \
return object; \
} \
/* 2 nil */ \
lua_remove (L, -1); /* 1 registry table */ \
object = lua_newuserdata (L, sizeof (llm_##WHAT##_t)); /* 2 userdata */ \
luaL_getmetatable (L, "loudmouth." #LWHAT); /* 3 metatable */ \
lua_setmetatable (L, -2); /* 2 object */ \
lua_pushlightuserdata (L, WHAT); /* 3 light userdata */ \
lua_pushvalue (L, -2); /* 4 object */ \
lua_rawset (L, -4); /* 2 object */ \
lua_remove (L, -2); /* 1 object */ \
object->WHAT = WHAT; \
lm_##LWHAT##_ref (WHAT); \
D ("New " #LWHAT " object %p blessed", object); \
return object; \
}
#define LLM_DEFINE(WHAT, LWHAT, TYPE) \
LLM_CHECK (WHAT, LWHAT, TYPE) \
LLM_BLESS (WHAT, LWHAT, TYPE)
LLM_DEFINE (connection, connection, LmConnection)
LLM_DEFINE (message, message, LmMessage)
LLM_DEFINE (handler, message_handler, LmMessageHandler)
LLM_DEFINE (node, message_node, LmMessageNode)
LLM_DEFINE (proxy, proxy, LmProxy)
LLM_DEFINE (ssl, ssl, LmSSL)
LmMessageNode *luaL_checkLmMessageNode (lua_State *L, int index)
{
void *object;
luaL_argcheck (L, lua_type (L, index) == LUA_TUSERDATA, index, "loudmouth message or message node expected");
object = lua_touserdata (L, index);
lua_getmetatable (L, index);
luaL_getmetatable (L, "loudmouth.message");
luaL_getmetatable (L, "loudmouth.message_node");
if (lua_rawequal (L, -2, -3)) // Message
object = (void *) lm_message_get_node (((llm_message_t *) object)->message);
else if (lua_rawequal (L, -1, -3)) // Node
object = (void *) (((llm_node_t *) object)->node);
else
luaL_argerror (L, index, "loudmouth message or message node expected");
lua_pop (L, 3);
return (LmMessageNode *) object;
}
#undef LLM_DEFINE
#undef LLM_BLESS
#undef LLM_CHECK