private ParseString ( string src, Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list separators, Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list spacers, bool keepNulls ) : Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list | ||
src | string | |
separators | Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list | |
spacers | Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list | |
keepNulls | bool | |
return | Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.list |
private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
{
int beginning = 0;
int srclen = src.Length;
int seplen = separators.Length;
object[] separray = separators.Data;
int spclen = spacers.Length;
object[] spcarray = spacers.Data;
int mlen = seplen + spclen;
int[] offset = new int[mlen + 1];
bool[] active = new bool[mlen];
// Initial capacity reduces resize cost
LSL_List tokens = new LSL_List();
// All entries are initially valid
for (int i = 0; i < mlen; i++)
active[i] = true;
offset[mlen] = srclen;
while (beginning < srclen)
{
int best = mlen;
// Scan for separators
int j;
for (j = 0; j < seplen; j++)
{
if (separray[j].ToString() == String.Empty)
active[j] = false;
if (active[j])
{
// scan all of the markers
if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
{
// not present at all
active[j] = false;
}
else
{
// present and correct
if (offset[j] < offset[best])
{
// closest so far
best = j;
if (offset[best] == beginning)
break;
}
}
}
}
// Scan for spacers
if (offset[best] != beginning)
{
for (j = seplen; (j < mlen) && (offset[best] > beginning); j++)
{
if (spcarray[j - seplen].ToString() == String.Empty)
active[j] = false;
if (active[j])
{
// scan all of the markers
if ((offset[j] = src.IndexOf(spcarray[j - seplen].ToString(), beginning)) == -1)
{
// not present at all
active[j] = false;
}
else
{
// present and correct
if (offset[j] < offset[best])
{
// closest so far
best = j;
}
}
}
}
}
// This is the normal exit from the scanning loop
if (best == mlen)
{
// no markers were found on this pass
// so we're pretty much done
if ((keepNulls) || ((srclen - beginning) > 0))
tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
break;
}
// Otherwise we just add the newly delimited token
// and recalculate where the search should continue.
if ((keepNulls) || ((offset[best] - beginning) > 0))
tokens.Add(new LSL_String(src.Substring(beginning, offset[best] - beginning)));
if (best < seplen)
{
beginning = offset[best] + (separray[best].ToString()).Length;
}
else
{
beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
string str = spcarray[best - seplen].ToString();
if ((keepNulls) || ((str.Length > 0)))
tokens.Add(new LSL_String(str));
}
}
// This an awkward an not very intuitive boundary case. If the
// last substring is a tokenizer, then there is an implied trailing
// null list entry. Hopefully the single comparison will not be too
// arduous. Alternatively the 'break' could be replced with a return
// but that's shabby programming.
if ((beginning == srclen) && (keepNulls))
{
if (srclen != 0)
tokens.Add(new LSL_String(""));
}
return tokens;
}