1
0
Fork 0

Codechange: hide SQString internals behind std::string_view/std::span

pull/14211/head
Rubidium 2025-05-03 19:31:39 +02:00 committed by rubidium42
parent 635ca3739f
commit 588b0de3de
8 changed files with 34 additions and 25 deletions

View File

@ -583,7 +583,7 @@ SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
SQObjectPtr &o = stack_get(v, idx);
SQObjectType type = type(o);
switch(type) {
case OT_STRING: return _string(o)->_len;
case OT_STRING: return _string(o)->View().size();
case OT_TABLE: return _table(o)->CountUsed();
case OT_ARRAY: return _array(o)->Size();
case OT_USERDATA: return _userdata(o)->_size;

View File

@ -18,12 +18,13 @@
#include "../../../safeguards.h"
bool str2num(const SQChar *s,SQObjectPtr &res)
bool str2num(std::string_view s,SQObjectPtr &res)
{
SQChar *end;
if(strstr(s,".")){
SQFloat r = SQFloat(strtod(s,&end));
if(s == end) return false;
if(s.find('.') != std::string_view::npos){
SQChar *end;
std::string str{s};
SQFloat r = SQFloat(strtod(str.c_str(),&end));
if(str.c_str() == end) return false;
res = r;
return true;
}
@ -632,12 +633,12 @@ static SQInteger string_slice(HSQUIRRELVM v)
SQInteger sidx,eidx;
SQObjectPtr o;
if(SQ_FAILED(get_slice_params(v,sidx,eidx,o)))return -1;
SQInteger slen = _string(o)->_len;
SQInteger slen = _string(o)->View().size();
if(sidx < 0)sidx = slen + sidx;
if(eidx < 0)eidx = slen + eidx;
if(eidx < sidx) return sq_throwerror(v,"wrong indexes");
if(eidx > slen) return sq_throwerror(v,"slice out of range");
v->Push(SQString::Create(_ss(v),std::string_view(&_stringval(o)[sidx],eidx-sidx)));
v->Push(SQString::Create(_ss(v),_stringval(o).substr(sidx,eidx-sidx)));
return 1;
}
@ -662,10 +663,10 @@ static SQInteger string_find(HSQUIRRELVM v)
#define STRING_TOFUNCZ(func) static SQInteger string_##func(HSQUIRRELVM v) \
{ \
SQObject str=stack_get(v,1); \
SQInteger len=_string(str)->_len; \
const SQChar *sThis=_stringval(str); \
std::string_view sThis=_stringval(str); \
size_t len=sThis.size(); \
std::span<char> sNew=(_ss(v)->GetScratchPad(len)); \
for(SQInteger i=0;i<len;i++) sNew[i]=func(sThis[i]); \
for(size_t i=0;i<len;i++) sNew[i]=func(sThis[i]); \
v->Push(SQString::Create(_ss(v),std::string_view(sNew.data(), len))); \
return 1; \
}

View File

@ -270,10 +270,13 @@ bool WriteObject(HSQUIRRELVM v,SQUserPointer up,SQWRITEFUNC write,SQObjectPtr &o
{
_CHECK_IO(SafeWrite(v,write,up,&type(o),sizeof(SQObjectType)));
switch(type(o)){
case OT_STRING:
_CHECK_IO(SafeWrite(v,write,up,&_string(o)->_len,sizeof(SQInteger)));
_CHECK_IO(SafeWrite(v,write,up,_stringval(o),_string(o)->_len));
case OT_STRING: {
auto str = _string(o)->Span();
SQInteger len = str.size();
_CHECK_IO(SafeWrite(v,write,up,&len,sizeof(len)));
_CHECK_IO(SafeWrite(v,write,up,str.data(),len));
break;
}
case OT_INTEGER:
_CHECK_IO(SafeWrite(v,write,up,&_integer(o),sizeof(SQInteger)));break;
case OT_FLOAT:
@ -294,11 +297,11 @@ bool ReadObject(HSQUIRRELVM v,SQUserPointer up,SQREADFUNC read,SQObjectPtr &o)
switch(t){
case OT_STRING:{
SQInteger len;
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(SQInteger)));
_CHECK_IO(SafeRead(v,read,up,&len,sizeof(len)));
_CHECK_IO(SafeRead(v,read,up,_ss(v)->GetScratchPad(len).data(),len));
o=SQString::Create(_ss(v),std::string_view(_ss(v)->GetScratchPad(-1).data(),len));
}
break;
}
case OT_INTEGER:{
SQInteger i;
_CHECK_IO(SafeRead(v,read,up,&i,sizeof(SQInteger))); o = i; break;

View File

@ -138,7 +138,7 @@ struct SQObjectPtr;
#define _refcounted(obj) ((obj)._unVal.pRefCounted)
#define _rawval(obj) ((obj)._unVal.raw)
#define _stringval(obj) (obj)._unVal.pString->_val
#define _stringval(obj) (obj)._unVal.pString->View()
#define _userdataval(obj) (obj)._unVal.pUserData->_val
#define tofloat(num) ((type(num)==OT_INTEGER)?(SQFloat)_integer(num):_float(num))

View File

@ -553,8 +553,7 @@ SQString *SQStringTable::Add(std::string_view new_string)
auto slot = string_table_hash(new_string) & (_numofslots-1);
SQString *s;
for (s = _strings[slot]; s; s = s->_next){
if(static_cast<size_t>(s->_len) == len && (!memcmp(new_string.data(),s->_val,len)))
return s; //found
if(s->View() == new_string) return s; //found
}
SQString *t=(SQString *)SQ_MALLOC(len+sizeof(SQString));
@ -608,7 +607,7 @@ void SQStringTable::Remove(SQString *bs)
else
_strings[h] = s->_next;
_slotused--;
SQInteger slen = s->_len;
size_t slen = s->View().size();
s->~SQString();
SQ_FREE(s,sizeof(SQString) + slen);
return;

View File

@ -12,8 +12,12 @@ public:
void Release() override;
SQSharedState *_sharedstate;
SQString *_next; //chain for the string table
SQInteger _len;
std::size_t _hash;
std::string_view View() const { return std::string_view(this->_val, this->_len); }
std::span<char> Span() { return std::span<char>(this->_val, this->_len); }
private:
SQInteger _len;
SQChar _val[1];
};

View File

@ -197,7 +197,7 @@ bool SQVM::ObjCmp(const SQObjectPtr &o1,const SQObjectPtr &o2,SQInteger &result)
SQObjectPtr res;
switch(type(o1)){
case OT_STRING:
_RET_SUCCEED(strcmp(_stringval(o1),_stringval(o2)));
_RET_SUCCEED(_stringval(o1).compare(_stringval(o2)));
case OT_INTEGER:
/* FS#3954: wrong integer comparison */
_RET_SUCCEED((_integer(o1)<_integer(o2))?-1:(_integer(o1)==_integer(o2))?0:1);
@ -1284,9 +1284,10 @@ bool SQVM::FallBackGet(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPt
case OT_STRING:
if(sq_isnumeric(key)){
SQInteger n=tointeger(key);
if(abs((int)n)<_string(self)->_len){
if(n<0)n=_string(self)->_len-n;
dest=SQInteger(_stringval(self)[n]);
std::string_view str = _stringval(self);
if(std::abs(n) < static_cast<SQInteger>(str.size())){
if(n<0)n=str.size()+n;
dest=SQInteger(str[n]);
return true;
}
return false;

View File

@ -36,6 +36,7 @@
#define vsprintf SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define vsnprintf SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define strcmp SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define strncmp SAFEGUARD_DO_NOT_USE_THIS_METHOD
#ifdef strcasecmp
#undef strcasecmp