// Called from lua to get the metatable static int addon_pload_metatable(lua_State *L) { const char *key = luaL_checkstring(L, 2); struct addon_pload *ap = luaL_checkudata(L, 1, ADDON_PLOAD_METATABLE); struct analyzer_pload_buffer *p = ap->pload; if (!strcmp(key, "event")) { // Return the corresponding event addon_event_push(L, p->rel_event); } else if (!strcmp(key, "data")) { addon_data_push(L, p->data, p->type->analyzer->data_reg); } else if (!strcmp(key, "type") && p->type) { // Return the type table if any lua_newtable(L); // Add type name lua_pushliteral(L, "name"); lua_pushstring(L, p->type->name); lua_settable(L, -3); // Add type description lua_pushliteral(L, "description"); lua_pushstring(L, p->type->description); lua_settable(L, -3); // Add type extension lua_pushliteral(L, "extension"); lua_pushstring(L, p->type->extension); lua_settable(L, -3); // Add the class lua_pushliteral(L, "class"); switch (p->type->cls) { case analyzer_pload_class_unknown: lua_pushliteral(L, "unknown"); break; case analyzer_pload_class_application: lua_pushliteral(L, "application"); break; case analyzer_pload_class_audio: lua_pushliteral(L, "audio"); break; case analyzer_pload_class_image: lua_pushliteral(L, "image"); break; case analyzer_pload_class_video: lua_pushliteral(L, "video"); break; case analyzer_pload_class_document: lua_pushliteral(L, "document"); break; } lua_settable(L, -3); } else if (!strcmp(key, "container") && p->container) { addon_pload_push(L, p->container, NULL); } else { return 0; } return 1; }
// Called from C to open a pload static int addon_output_pload_open(void *obj, void **priv, struct pload *pload) { struct addon_instance_priv *p = obj; // Lock the output pom_mutex_lock(&p->lock); lua_getfield(p->L, LUA_REGISTRYINDEX, ADDON_INSTANCE); // Stack : self struct addon_output_pload_priv *ppriv = malloc(sizeof(struct addon_output_pload_priv)); if (!ppriv) { pom_mutex_unlock(&p->lock); pom_oom(sizeof(struct addon_output_pload_priv)); return POM_ERR; } memset(ppriv, 0, sizeof(struct addon_output_pload_priv)); *priv = ppriv; // Get the __pload_listener table lua_getfield(p->L, -1, "__pload_listener"); // Stack : self, __pload_listener // Get the open function lua_getfield(p->L, -1, "open"); // Stack : self, __pload_listener, open_func // Check if there is an open function if (lua_isnil(p->L, -1)) { pom_mutex_unlock(&p->lock); lua_pop(p->L, 3); // Stack : empty return POM_OK; } // Add self lua_pushvalue(p->L, -3); // Stack : self, __pload_listener, open_func, self // Create a new table for the pload priv and store it into __pload_listener lua_newtable(p->L); // Stack : self, __pload_listener, open_func, self, pload_priv_table // Add output_pload_data to it addon_pload_data_push(p->L); // Stack : self, __pload_listener, open_func, self, pload_priv_table, pload_data lua_setfield(p->L, -2, "__pload_data"); // Stack : self, __pload_listener, open_func, self, pload_priv_table // Add the new priv to the __pload_listener table lua_pushlightuserdata(p->L, ppriv); // Stack : self, __pload_listener, open_func, self, pload_priv_table, pload_priv lua_pushvalue(p->L, -2); // Stack : self, __pload_listener, open_func, self, pload_priv_table, pload_priv, pload_priv_table lua_settable(p->L, -6); // Stack : self, __pload_listener, open_func, self, pload_priv_table // Add the pload to the args addon_pload_push(p->L, pload, ppriv); // Stack : self, __pload_listener, open_func, self, pload_priv_table, pload // Call the open function addon_pcall(p->L, 3, 1); // Stack : self, __pload_listener, result int res = 0; if (!lua_isboolean(p->L, -1)) { pomlog(POMLOG_WARN "LUA coding error: pload open function result must be a boolean"); } else { res = lua_toboolean(p->L, -1); } if (!res) { // The payload doesn't need to be processed, remove the payload_priv_table and the __pload_data lua_pushlightuserdata(p->L, ppriv); // Stack : self, __pload_listener, result, pload_priv lua_pushnil(p->L); // Stack : self, __pload_listener, result, pload_priv, nil lua_settable(p->L, -4); // Stack : self, __pload_listener, result lua_pushnil(p->L); // Stack : self, __pload_listener, result, nil lua_setfield(p->L, -3, "__pload_data"); // Stack : self, __pload_listener, result } // Remove leftovers lua_pop(p->L, 3); // Stack : empty pom_mutex_unlock(&p->lock); return POM_OK; }