mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 19:45:11 +00:00
Still WIP-tier, also I need to make a way to index a multi-option list like a regular array with the forms thing, the current one-at-a-time idea is not great...
224 lines
4.5 KiB
C
224 lines
4.5 KiB
C
#include <XMPPCommand.h>
|
|
|
|
#include <Cytoplasm/Memory.h>
|
|
#include <Cytoplasm/Array.h>
|
|
#include <Cytoplasm/Str.h>
|
|
|
|
struct XMPPCommand {
|
|
XMPPCmdCallback callback;
|
|
char *node, *name;
|
|
|
|
char *form_instruction;
|
|
char *form_title;
|
|
|
|
/* TODO: On-the-fly generation of options */
|
|
Array *options;
|
|
XMPPOptionWriter otf;
|
|
};
|
|
|
|
XMPPCommand *
|
|
XMPPBasicCmd(char *node, char *name, XMPPCmdCallback callback_funct)
|
|
{
|
|
XMPPCommand *cmd;
|
|
|
|
if (!node || !name || !callback_funct)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
cmd = Malloc(sizeof(*cmd));
|
|
cmd->callback = callback_funct;
|
|
cmd->node = StrDuplicate(node);
|
|
cmd->name = StrDuplicate(name);
|
|
cmd->form_instruction = NULL;
|
|
cmd->form_title = NULL;
|
|
|
|
/* No options -> no form required */
|
|
cmd->options = NULL;
|
|
|
|
cmd->otf = NULL;
|
|
|
|
return cmd;
|
|
}
|
|
void
|
|
XMPPCmdOptionsCreator(XMPPCommand *cmd, XMPPOptionWriter writer)
|
|
{
|
|
if (!cmd)
|
|
{
|
|
return;
|
|
}
|
|
cmd->otf = writer;
|
|
}
|
|
|
|
void
|
|
XMPPSetFormTitle(XMPPCommand *cmd, char *title)
|
|
{
|
|
if (!cmd)
|
|
{
|
|
return;
|
|
}
|
|
Free(cmd->form_title);
|
|
cmd->form_title = StrDuplicate(title);
|
|
}
|
|
void
|
|
XMPPSetFormInstruction(XMPPCommand *cmd, char *instruction)
|
|
{
|
|
if (!cmd)
|
|
{
|
|
return;
|
|
}
|
|
Free(cmd->form_instruction);
|
|
cmd->form_instruction = StrDuplicate(instruction);
|
|
}
|
|
void
|
|
XMPPFreeCommand(XMPPCommand *cmd)
|
|
{
|
|
size_t i;
|
|
if (!cmd)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < ArraySize(cmd->options); i++)
|
|
{
|
|
XMPPOption *opt = ArrayGet(cmd->options, i);
|
|
XMPPFreeOption(opt);
|
|
}
|
|
ArrayFree(cmd->options);
|
|
|
|
XMPPSetFormInstruction(cmd, NULL);
|
|
XMPPSetFormTitle(cmd, NULL);
|
|
Free(cmd->node);
|
|
Free(cmd->name);
|
|
Free(cmd);
|
|
}
|
|
void
|
|
XMPPAddOption(XMPPCommand *cmd, XMPPOption *opt)
|
|
{
|
|
if (!cmd || !opt)
|
|
{
|
|
return;
|
|
}
|
|
if (!cmd->options)
|
|
{
|
|
cmd->options = ArrayCreate();
|
|
}
|
|
|
|
ArrayAdd(cmd->options, opt);
|
|
}
|
|
|
|
XMLElement *
|
|
XMPPFormifyCommand(XMPPCommandManager *m, XMPPCommand *cmd, char *from)
|
|
{
|
|
XMLElement *x, *field;
|
|
size_t i;
|
|
|
|
if (!cmd || !m)
|
|
{
|
|
return NULL;
|
|
}
|
|
if (cmd->otf)
|
|
{
|
|
for (i = 0; i < ArraySize(cmd->options); i++)
|
|
{
|
|
XMPPOption *opt = ArrayGet(cmd->options, i);
|
|
XMPPFreeOption(opt);
|
|
}
|
|
ArrayFree(cmd->options);
|
|
cmd->options = NULL;
|
|
|
|
cmd->otf(m, cmd, from);
|
|
}
|
|
if (!cmd->options)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
x = XMLCreateTag("x");
|
|
XMLAddAttr(x, "xmlns", "jabber:x:data");
|
|
XMLAddAttr(x, "type", "form");
|
|
|
|
if (cmd->form_title)
|
|
{
|
|
XMLElement *instr_xml, *instr_txt;
|
|
|
|
instr_xml = XMLCreateTag("title");
|
|
instr_txt = XMLCreateText(cmd->form_title);
|
|
XMLAddChild(instr_xml, instr_txt);
|
|
XMLAddChild(x, instr_xml);
|
|
}
|
|
if (cmd->form_instruction)
|
|
{
|
|
XMLElement *instr_xml, *instr_txt;
|
|
|
|
instr_xml = XMLCreateTag("instructions");
|
|
instr_txt = XMLCreateText(cmd->form_instruction);
|
|
XMLAddChild(instr_xml, instr_txt);
|
|
XMLAddChild(x, instr_xml);
|
|
}
|
|
/* TODO: Other fields */
|
|
|
|
for (i = 0; i < ArraySize(cmd->options); i++)
|
|
{
|
|
XMPPOption *opt = ArrayGet(cmd->options, i);
|
|
field = XMPPOptionToXML(opt);
|
|
|
|
XMLAddChild(x, field);
|
|
}
|
|
|
|
return x;
|
|
}
|
|
char *
|
|
XMPPGetCommandNode(XMPPCommand *cmd)
|
|
{
|
|
return cmd ? cmd->node : NULL;
|
|
}
|
|
char *
|
|
XMPPGetCommandDesc(XMPPCommand *cmd)
|
|
{
|
|
return cmd ? cmd->name : NULL;
|
|
}
|
|
bool
|
|
XMPPCommandRequiresForm(XMPPCommand *cmd)
|
|
{
|
|
return cmd ? (cmd->otf || !!cmd->options) : false;
|
|
}
|
|
void
|
|
XMPPExecuteCommand(XMPPCommandManager *m, XMPPCommand *cmd, char *from, XMLElement *to, XMLElement *form)
|
|
{
|
|
if (!m || !cmd || !from || !to)
|
|
{
|
|
return;
|
|
}
|
|
cmd->callback(m, from, form, to);
|
|
}
|
|
|
|
bool
|
|
XMPPVerifyForm(XMPPCommand *cmd, XMLElement *form)
|
|
{
|
|
size_t i;
|
|
if (!cmd || !form)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (i = 0; i < ArraySize(cmd->options); i++)
|
|
{
|
|
XMPPOption *opt = ArrayGet(cmd->options, i);
|
|
if (XMPPIsOptionRequired(opt))
|
|
{
|
|
/* Check in the form for a field with the right var */
|
|
char *var = XMPPOptionVar(opt);
|
|
XMLElement *field = XMLookForTKV(form, "field", "var", var);
|
|
|
|
if (!field)
|
|
{
|
|
/* Required field not found; die. */
|
|
return false;
|
|
}
|
|
/* TODO: Verify type, array membership, uniqueness, etc... */
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|