minimizes temp garbage for llParseStringKeepNulls()
and uses common routine for llParseStringKeepNulls()/llParseString2List()avinationmerge
parent
6e7f1a3ac1
commit
faaef1b498
|
@ -5877,74 +5877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
|
public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
return ParseString2List(str, separators, in_spacers, false);
|
||||||
LSL_List ret = new LSL_List();
|
|
||||||
LSL_List spacers = new LSL_List();
|
|
||||||
if (in_spacers.Length > 0 && separators.Length > 0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < in_spacers.Length; i++)
|
|
||||||
{
|
|
||||||
object s = in_spacers.Data[i];
|
|
||||||
for (int j = 0; j < separators.Length; j++)
|
|
||||||
{
|
|
||||||
if (separators.Data[j].ToString() == s.ToString())
|
|
||||||
{
|
|
||||||
s = null;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s != null)
|
|
||||||
{
|
|
||||||
spacers.Add(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
object[] delimiters = new object[separators.Length + spacers.Length];
|
|
||||||
separators.Data.CopyTo(delimiters, 0);
|
|
||||||
spacers.Data.CopyTo(delimiters, separators.Length);
|
|
||||||
bool dfound = false;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
dfound = false;
|
|
||||||
int cindex = -1;
|
|
||||||
string cdeli = "";
|
|
||||||
for (int i = 0; i < delimiters.Length; i++)
|
|
||||||
{
|
|
||||||
int index = str.IndexOf(delimiters[i].ToString());
|
|
||||||
bool found = index != -1;
|
|
||||||
if (found && String.Empty != delimiters[i].ToString())
|
|
||||||
{
|
|
||||||
if ((cindex > index) || (cindex == -1))
|
|
||||||
{
|
|
||||||
cindex = index;
|
|
||||||
cdeli = delimiters[i].ToString();
|
|
||||||
}
|
|
||||||
dfound = dfound || found;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cindex != -1)
|
|
||||||
{
|
|
||||||
if (cindex > 0)
|
|
||||||
{
|
|
||||||
ret.Add(new LSL_String(str.Substring(0, cindex)));
|
|
||||||
}
|
|
||||||
// Cannot use spacers.Contains() because spacers may be either type String or LSLString
|
|
||||||
for (int j = 0; j < spacers.Length; j++)
|
|
||||||
{
|
|
||||||
if (spacers.Data[j].ToString() == cdeli)
|
|
||||||
{
|
|
||||||
ret.Add(new LSL_String(cdeli));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
str = str.Substring(cindex + cdeli.Length);
|
|
||||||
}
|
|
||||||
} while (dfound);
|
|
||||||
if (str != "")
|
|
||||||
{
|
|
||||||
ret.Add(new LSL_String(str));
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public LSL_Integer llOverMyLand(string id)
|
public LSL_Integer llOverMyLand(string id)
|
||||||
|
@ -8616,8 +8549,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// The function returns an ordered list
|
// The function returns an ordered list
|
||||||
// representing the tokens found in the supplied
|
// representing the tokens found in the supplied
|
||||||
// sources string. If two successive tokenizers
|
// sources string. If two successive tokenizers
|
||||||
// are encountered, then a NULL entry is added
|
// are encountered, then a null-string entry is
|
||||||
// to the list.
|
// added to the list.
|
||||||
//
|
//
|
||||||
// It is a precondition that the source and
|
// It is a precondition that the source and
|
||||||
// toekizer lisst are non-null. If they are null,
|
// toekizer lisst are non-null. If they are null,
|
||||||
|
@ -8625,7 +8558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// while their lengths are being determined.
|
// while their lengths are being determined.
|
||||||
//
|
//
|
||||||
// A small amount of working memoryis required
|
// A small amount of working memoryis required
|
||||||
// of approximately 8*#tokenizers.
|
// of approximately 8*#tokenizers + 8*srcstrlen.
|
||||||
//
|
//
|
||||||
// There are many ways in which this function
|
// There are many ways in which this function
|
||||||
// can be implemented, this implementation is
|
// can be implemented, this implementation is
|
||||||
|
@ -8641,109 +8574,109 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// and eliminates redundant tokenizers as soon
|
// and eliminates redundant tokenizers as soon
|
||||||
// as is possible.
|
// as is possible.
|
||||||
//
|
//
|
||||||
// The implementation tries to avoid any copying
|
// The implementation tries to minimize temporary
|
||||||
// of arrays or other objects.
|
// garbage generation.
|
||||||
// </remarks>
|
// </remarks>
|
||||||
|
|
||||||
public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
|
public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
|
||||||
|
{
|
||||||
|
return ParseString2List(src, separators, spacers, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
|
||||||
{
|
{
|
||||||
int srclen = src.Length;
|
int srclen = src.Length;
|
||||||
int seplen = separators.Length;
|
int seplen = separators.Length;
|
||||||
object[] separray = separators.Data;
|
object[] separray = separators.Data;
|
||||||
int spclen = spacers.Length;
|
int spclen = spacers.Length;
|
||||||
object[] spcarray = spacers.Data;
|
object[] spcarray = spacers.Data;
|
||||||
|
int dellen = 0;
|
||||||
|
string[] delarray = new string[seplen+spclen];
|
||||||
|
|
||||||
int outlen = 0;
|
int outlen = 0;
|
||||||
LSL_String[] outarray = new LSL_String[srclen*2+1];
|
string[] outarray = new string[srclen*2+1];
|
||||||
|
|
||||||
int i, j, lastUsed;
|
int i, j;
|
||||||
|
string d;
|
||||||
|
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Point to beginning of current non-delimeter string.
|
* Convert separator and spacer lists to C# strings.
|
||||||
|
* Also filter out null strings so we don't hang.
|
||||||
*/
|
*/
|
||||||
lastUsed = 0;
|
for (i = 0; i < seplen; i ++) {
|
||||||
|
d = separray[i].ToString();
|
||||||
|
if (d.Length > 0) {
|
||||||
|
delarray[dellen++] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seplen = dellen;
|
||||||
|
|
||||||
|
for (i = 0; i < spclen; i ++) {
|
||||||
|
d = spcarray[i].ToString();
|
||||||
|
if (d.Length > 0) {
|
||||||
|
delarray[dellen++] = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan through source string from beginning to end.
|
* Scan through source string from beginning to end.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < srclen;) {
|
for (i = 0;;) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See if rest of string (starting at i) matches any separator.
|
* Find earliest delimeter in src starting at i (if any).
|
||||||
*/
|
*/
|
||||||
string rest = src.Substring(i);
|
int earliestDel = -1;
|
||||||
for (j = 0; j < seplen; j ++) {
|
int earliestSrc = srclen;
|
||||||
string sep = separray[j].ToString();
|
string earliestStr = null;
|
||||||
if ((sep.Length > 0) && rest.StartsWith(sep)) {
|
for (j = 0; j < dellen; j ++) {
|
||||||
|
d = delarray[j];
|
||||||
/*
|
if (d != null) {
|
||||||
* Separator matched, output string from end of last delimeter to beginning of this one.
|
int index = src.IndexOf(d, i);
|
||||||
*/
|
if (index < 0) {
|
||||||
outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
|
delarray[j] = null; // delim nowhere in src, don't check it anymore
|
||||||
|
} else if (index < earliestSrc) {
|
||||||
/*
|
earliestSrc = index; // where delimeter starts in source string
|
||||||
* Remove separator from input string.
|
earliestDel = j; // where delimeter is in delarray[]
|
||||||
*/
|
earliestStr = d; // the delimeter string from delarray[]
|
||||||
i += sep.Length;
|
if (index == i) break; // can't do any better than found at beg of string
|
||||||
|
}
|
||||||
/*
|
|
||||||
* Next non-delimeter starts where this separator left off.
|
|
||||||
*/
|
|
||||||
lastUsed = i;
|
|
||||||
goto nextsrc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See if rest of string (starting at i) matches any spacer.
|
* Output source string starting at i through start of earliest delimeter.
|
||||||
*/
|
*/
|
||||||
for (j = 0; j < spclen; j ++) {
|
if (keepNulls || (earliestSrc > i)) {
|
||||||
string spc = spcarray[j].ToString();
|
outarray[outlen++] = src.Substring(i, earliestSrc - i);
|
||||||
if ((spc.Length > 0) && rest.StartsWith(spc)) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Spacer matched, output string from end of last delimeter to beginning of this one.
|
|
||||||
* Then output the spacer itself.
|
|
||||||
*/
|
|
||||||
outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
|
|
||||||
outarray[outlen++] = new LSL_String(spc);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove spacer from input string.
|
|
||||||
*/
|
|
||||||
i += spc.Length;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Next non-delimeter starts where this spacer left off.
|
|
||||||
*/
|
|
||||||
lastUsed = i;
|
|
||||||
goto nextsrc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Didn't match any separator or spacer, skip over it and it
|
* If no delimeter found at or after i, we're done scanning.
|
||||||
* becomes part of the non-delimeter string starting with
|
|
||||||
* lastUsed.
|
|
||||||
*/
|
*/
|
||||||
i ++;
|
if (earliestDel < 0) break;
|
||||||
nextsrc:;
|
|
||||||
|
/*
|
||||||
|
* If delimeter was a spacer, output the spacer.
|
||||||
|
*/
|
||||||
|
if (earliestDel >= seplen) {
|
||||||
|
outarray[outlen++] = earliestStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Output last non-delimeter (including a possible null string if
|
* Look at rest of src string following delimeter.
|
||||||
* delimeter ran to end of source string).
|
|
||||||
*/
|
*/
|
||||||
outarray[outlen++] = new LSL_String(src.Substring(lastUsed));
|
i = earliestSrc + earliestStr.Length;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make up an exact-sized output array suitable for an LSL_List object.
|
* Make up an exact-sized output array suitable for an LSL_List object.
|
||||||
*/
|
*/
|
||||||
object[] outlist = new object[outlen];
|
object[] outlist = new object[outlen];
|
||||||
for (i = 0; i < outlen; i ++) {
|
for (i = 0; i < outlen; i ++) {
|
||||||
outlist[i] = outarray[i];
|
outlist[i] = new LSL_String(outarray[i]);
|
||||||
}
|
}
|
||||||
return new LSL_List(outlist);
|
return new LSL_List(outlist);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue