Redesigned how server commands work. The "plugins" command will be back soon.
8 void CFunction::Set(funcid_t funcid, CPlugin *plugin)
13 m_errorstate = SP_ERROR_NONE;
16 int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
18 IPluginContext *ctx = m_pPlugin->m_ctx.base;
22 ctx->PushCell(params[num_params]);
25 return ctx->Execute(m_funcid, result);
28 IPlugin *CFunction::GetParentPlugin()
33 CFunction::CFunction(funcid_t funcid, CPlugin *plugin) :
34 m_funcid(funcid), m_pPlugin(plugin), m_curparam(0),
35 m_errorstate(SP_ERROR_NONE)
39 int CFunction::PushCell(cell_t cell)
41 if (m_curparam >= SP_MAX_EXEC_PARAMS)
43 return SetError(SP_ERROR_PARAMS_MAX);
46 m_info[m_curparam].marked = false;
47 m_params[m_curparam] = cell;
53 int CFunction::PushCellByRef(cell_t *cell, int flags)
55 if (m_curparam >= SP_MAX_EXEC_PARAMS)
57 return SetError(SP_ERROR_PARAMS_MAX);
60 return PushArray(cell, 1, NULL, flags);
63 int CFunction::PushFloat(float number)
65 cell_t val = *(cell_t *)&number;
70 int CFunction::PushFloatByRef(float *number, int flags)
72 return PushCellByRef((cell_t *)number, flags);
75 int CFunction::PushArray(cell_t *inarray, unsigned int cells, cell_t **phys_addr, int copyback)
77 if (m_curparam >= SP_MAX_EXEC_PARAMS)
79 return SetError(SP_ERROR_PARAMS_MAX);
82 IPluginContext *ctx = m_pPlugin->m_ctx.base;
83 ParamInfo *info = &m_info[m_curparam];
86 if ((err=ctx->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
91 info->flags = inarray ? copyback : 0;
93 info->size = cells * sizeof(cell_t);
94 m_params[m_curparam] = info->local_addr;
99 memcpy(info->phys_addr, inarray, sizeof(cell_t) * cells);
100 info->orig_addr = inarray;
102 info->orig_addr = info->phys_addr;
107 *phys_addr = info->phys_addr;
113 int CFunction::PushString(const char *string)
115 return _PushString(string, SM_PARAM_STRING_COPY, 0, strlen(string)+1);
118 int CFunction::PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags)
120 return _PushString(buffer, sz_flags, cp_flags, length);
123 int CFunction::_PushString(const char *string, int sz_flags, int cp_flags, size_t len)
125 if (m_curparam >= SP_MAX_EXEC_PARAMS)
127 return SetError(SP_ERROR_PARAMS_MAX);
130 IPluginContext *base = m_pPlugin->m_ctx.base;
131 ParamInfo *info = &m_info[m_curparam];
132 size_t cells = (len + sizeof(cell_t) - 1) / sizeof(cell_t);
135 if ((err=base->HeapAlloc(cells, &info->local_addr, &info->phys_addr)) != SP_ERROR_NONE)
137 return SetError(err);
141 m_params[m_curparam] = info->local_addr;
142 m_curparam++; /* Prevent a leak */
144 if (!(sz_flags & SM_PARAM_STRING_COPY))
146 goto skip_localtostr;
149 if (sz_flags & SM_PARAM_STRING_UTF8)
151 if ((err=base->StringToLocalUTF8(info->local_addr, len, string, NULL)) != SP_ERROR_NONE)
153 return SetError(err);
156 if ((err=base->StringToLocal(info->local_addr, len, string)) != SP_ERROR_NONE)
158 return SetError(err);
163 info->flags = cp_flags;
164 info->orig_addr = (cell_t *)string;
167 return SP_ERROR_NONE;
170 void CFunction::Cancel()
177 IPluginContext *base = m_pPlugin->m_ctx.base;
181 if (m_info[m_curparam].marked)
183 base->HeapRelease(m_info[m_curparam].local_addr);
184 m_info[m_curparam].marked = false;
188 m_errorstate = SP_ERROR_NONE;
191 int CFunction::Execute(cell_t *result)
194 if (m_errorstate != SP_ERROR_NONE)
201 //This is for re-entrancy!
202 cell_t temp_params[SP_MAX_EXEC_PARAMS];
203 ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
204 unsigned int numparams = m_curparam;
205 bool docopies = true;
209 //Save the info locally, then reset it for re-entrant calls.
210 memcpy(temp_params, m_params, numparams * sizeof(cell_t));
211 memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
215 if ((err = CallFunction(temp_params, numparams, result)) != SP_ERROR_NONE)
220 IPluginContext *base = m_pPlugin->m_ctx.base;
224 if (!temp_info[numparams].marked)
228 if (docopies && temp_info[numparams].flags)
230 if (temp_info[numparams].orig_addr)
232 if (temp_info[numparams].size == sizeof(cell_t))
234 *temp_info[numparams].orig_addr = *temp_info[numparams].phys_addr;
236 memcpy(temp_info[numparams].orig_addr,
237 temp_info[numparams].phys_addr,
238 temp_info[numparams].size);
242 base->HeapPop(temp_info[numparams].local_addr);
243 temp_info[numparams].marked = false;
249 cell_t *CFunction::GetAddressOfPushedParam(unsigned int param)
251 if (m_errorstate != SP_ERROR_NONE
252 || param >= m_curparam
253 || !m_info[param].marked)
258 return m_info[param].phys_addr;