Move the guts of Format to a helper function
This commit is contained in:
parent
936bdc47f0
commit
1ff13c59cf
@ -194,80 +194,12 @@ static cell_t sm_formatex(IPluginContext *pCtx, const cell_t *params)
|
||||
return static_cast<cell_t>(res);
|
||||
}
|
||||
|
||||
class StaticCharBuf
|
||||
{
|
||||
char *buffer;
|
||||
size_t max_size;
|
||||
public:
|
||||
StaticCharBuf() : buffer(NULL), max_size(0)
|
||||
{
|
||||
}
|
||||
~StaticCharBuf()
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
char* GetWithSize(size_t len)
|
||||
{
|
||||
if (len > max_size)
|
||||
{
|
||||
buffer = (char *)realloc(buffer, len);
|
||||
max_size = len;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
static char g_formatbuf[2048];
|
||||
static StaticCharBuf g_extrabuf;
|
||||
static cell_t sm_format(IPluginContext *pCtx, const cell_t *params)
|
||||
{
|
||||
char *buf, *fmt, *destbuf;
|
||||
cell_t start_addr, end_addr, maxparam;
|
||||
size_t res, maxlen;
|
||||
int arg = 4;
|
||||
bool copy = false;
|
||||
char *__copy_buf;
|
||||
|
||||
pCtx->LocalToString(params[1], &destbuf);
|
||||
pCtx->LocalToString(params[3], &fmt);
|
||||
|
||||
maxlen = static_cast<size_t>(params[2]);
|
||||
start_addr = params[1];
|
||||
end_addr = params[1] + maxlen;
|
||||
maxparam = params[0];
|
||||
|
||||
for (cell_t i=3; i<=maxparam; i++)
|
||||
{
|
||||
if ((params[i] >= start_addr) && (params[i] <= end_addr))
|
||||
{
|
||||
copy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy)
|
||||
{
|
||||
if (maxlen > sizeof(g_formatbuf))
|
||||
{
|
||||
__copy_buf = g_extrabuf.GetWithSize(maxlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
__copy_buf = g_formatbuf;
|
||||
}
|
||||
}
|
||||
|
||||
buf = (copy) ? __copy_buf : destbuf;
|
||||
res = atcprintf(buf, maxlen, fmt, pCtx, params, &arg);
|
||||
|
||||
if (copy)
|
||||
{
|
||||
memcpy(destbuf, __copy_buf, res+1);
|
||||
}
|
||||
|
||||
return static_cast<cell_t>(res);
|
||||
return InternalFormat(pCtx, params, 0);
|
||||
}
|
||||
|
||||
static char g_vformatbuf[2048];
|
||||
static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
int vargPos = static_cast<int>(params[4]);
|
||||
@ -301,7 +233,7 @@ static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
if (copy)
|
||||
{
|
||||
destination = g_formatbuf;
|
||||
destination = g_vformatbuf;
|
||||
} else {
|
||||
pContext->LocalToString(params[1], &destination);
|
||||
}
|
||||
@ -313,7 +245,7 @@ static cell_t sm_vformat(IPluginContext *pContext, const cell_t *params)
|
||||
/* Perform copy-on-write if we need to */
|
||||
if (copy)
|
||||
{
|
||||
pContext->StringToLocal(params[1], maxlen, g_formatbuf);
|
||||
pContext->StringToLocal(params[1], maxlen, g_vformatbuf);
|
||||
}
|
||||
|
||||
return total;
|
||||
|
@ -29,11 +29,13 @@
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#include "common_logic.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sm_platform.h>
|
||||
#include "stringutil.h"
|
||||
#include "sprintf.h"
|
||||
#include <am-string.h>
|
||||
#include "TextParsers.h"
|
||||
|
||||
@ -361,3 +363,76 @@ char *UTIL_TrimWhitespace(char *str, size_t &len)
|
||||
return str;
|
||||
}
|
||||
|
||||
class StaticCharBuf
|
||||
{
|
||||
char *buffer;
|
||||
size_t max_size;
|
||||
public:
|
||||
StaticCharBuf() : buffer(NULL), max_size(0)
|
||||
{
|
||||
}
|
||||
~StaticCharBuf()
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
char* GetWithSize(size_t len)
|
||||
{
|
||||
if (len > max_size)
|
||||
{
|
||||
buffer = (char *)realloc(buffer, len);
|
||||
max_size = len;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
};
|
||||
|
||||
static char g_formatbuf[2048];
|
||||
static StaticCharBuf g_extrabuf;
|
||||
cell_t InternalFormat(IPluginContext *pCtx, const cell_t *params, int start)
|
||||
{
|
||||
char *buf, *fmt, *destbuf;
|
||||
cell_t start_addr, end_addr, maxparam;
|
||||
size_t res, maxlen;
|
||||
int arg = start + 4;
|
||||
bool copy = false;
|
||||
char *__copy_buf;
|
||||
|
||||
pCtx->LocalToString(params[start + 1], &destbuf);
|
||||
pCtx->LocalToString(params[start + 3], &fmt);
|
||||
|
||||
maxlen = static_cast<size_t>(params[start + 2]);
|
||||
start_addr = params[start + 1];
|
||||
end_addr = params[start + 1] + maxlen;
|
||||
maxparam = params[0];
|
||||
|
||||
for (cell_t i = (start + 3); i <= maxparam; i++)
|
||||
{
|
||||
if ((params[i] >= start_addr) && (params[i] <= end_addr))
|
||||
{
|
||||
copy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy)
|
||||
{
|
||||
if (maxlen > sizeof(g_formatbuf))
|
||||
{
|
||||
__copy_buf = g_extrabuf.GetWithSize(maxlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
__copy_buf = g_formatbuf;
|
||||
}
|
||||
}
|
||||
|
||||
buf = (copy) ? __copy_buf : destbuf;
|
||||
res = atcprintf(buf, maxlen, fmt, pCtx, params, &arg);
|
||||
|
||||
if (copy)
|
||||
{
|
||||
memcpy(destbuf, __copy_buf, res+1);
|
||||
}
|
||||
|
||||
return static_cast<cell_t>(res);
|
||||
}
|
||||
|
@ -43,5 +43,9 @@ size_t UTIL_DecodeHexString(unsigned char *buffer, size_t maxlength, const char
|
||||
void UTIL_StripExtension(const char *in, char *out, int outSize);
|
||||
char *UTIL_TrimWhitespace(char *str, size_t &len);
|
||||
|
||||
// Internal copying Format helper, expects (char[] buffer, int maxlength, const char[] format, any ...) starting at |start|
|
||||
// i.e. you can stuff your own params before |buffer|.
|
||||
cell_t InternalFormat(IPluginContext *pCtx, const cell_t *params, int start);
|
||||
|
||||
#endif /* _INCLUDE_SOURCEMOD_COMMON_STRINGUTIL_H_ */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user