⚡ optimize builtin_split.
This commit is contained in:
parent
fb25a4973c
commit
824a31ef55
|
@ -317,57 +317,33 @@ nasal_ref builtin_fout(nasal_ref* local,nasal_gc& gc)
|
||||||
}
|
}
|
||||||
nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
nasal_ref builtin_split(nasal_ref* local,nasal_gc& gc)
|
||||||
{
|
{
|
||||||
nasal_ref deli_val=local[1];
|
nasal_ref delimeter=local[1];
|
||||||
nasal_ref str_val=local[2];
|
nasal_ref str=local[2];
|
||||||
if(deli_val.type!=vm_str)
|
if(delimeter.type!=vm_str)
|
||||||
return builtin_err("split","\"separator\" must be string");
|
return builtin_err("split","\"separator\" must be string");
|
||||||
if(str_val.type!=vm_str)
|
if(str.type!=vm_str)
|
||||||
return builtin_err("split","\"str\" must be string");
|
return builtin_err("split","\"str\" must be string");
|
||||||
std::string& delimeter=deli_val.str();
|
std::string& deli=delimeter.str();
|
||||||
std::string& source=str_val.str();
|
std::string& s=str.str();
|
||||||
size_t delimeter_len=delimeter.length();
|
|
||||||
size_t source_len=source.length();
|
|
||||||
|
|
||||||
// avoid being sweeped
|
// avoid being sweeped
|
||||||
nasal_ref res=gc.temp=gc.alloc(vm_vec);
|
nasal_ref res=gc.temp=gc.alloc(vm_vec);
|
||||||
std::vector<nasal_ref>& vec=res.vec().elems;
|
std::vector<nasal_ref>& vec=res.vec().elems;
|
||||||
|
|
||||||
if(!delimeter_len)
|
if(!deli.length())
|
||||||
{
|
{
|
||||||
for(size_t i=0;i<source_len;++i)
|
for(auto i:s)
|
||||||
vec.push_back(gc.newstr(source[i]));
|
vec.push_back(gc.newstr(i));
|
||||||
gc.temp=nil;
|
gc.temp=nil;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
std::string::size_type last=s.find_first_not_of(deli,0);
|
||||||
std::string tmp="";
|
std::string::size_type pos=s.find_first_of(deli,last);
|
||||||
for(size_t i=0;i<source_len;++i)
|
while(pos!=std::string::npos || last!=std::string::npos)
|
||||||
{
|
{
|
||||||
bool check_delimeter=false;
|
vec.push_back(gc.newstr(s.substr(last,pos-last)));
|
||||||
if(source[i]==delimeter[0])
|
last=s.find_first_not_of(deli,pos);
|
||||||
for(size_t j=0;j<delimeter_len;++j)
|
pos=s.find_first_of(deli,last);
|
||||||
{
|
|
||||||
if(i+j>=source_len || source[i+j]!=delimeter[j])
|
|
||||||
break;
|
|
||||||
if(j==delimeter_len-1)
|
|
||||||
check_delimeter=true;
|
|
||||||
}
|
|
||||||
if(check_delimeter)
|
|
||||||
{
|
|
||||||
if(tmp.length())
|
|
||||||
{
|
|
||||||
vec.push_back(gc.newstr(tmp));
|
|
||||||
tmp="";
|
|
||||||
}
|
|
||||||
i+=delimeter_len-1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
tmp+=source[i];
|
|
||||||
}
|
|
||||||
if(tmp.length())
|
|
||||||
{
|
|
||||||
vec.push_back(gc.newstr(tmp));
|
|
||||||
tmp="";
|
|
||||||
}
|
}
|
||||||
gc.temp=nil;
|
gc.temp=nil;
|
||||||
return res;
|
return res;
|
||||||
|
|
Loading…
Reference in New Issue