aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs201
1 files changed, 67 insertions, 134 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index b9b3318..b335ae6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -5877,74 +5877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5877 5877
5878 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5878 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5879 { 5879 {
5880 m_host.AddScriptLPS(1); 5880 return ParseString2List(str, separators, in_spacers, false);
5881 LSL_List ret = new LSL_List();
5882 LSL_List spacers = new LSL_List();
5883 if (in_spacers.Length > 0 && separators.Length > 0)
5884 {
5885 for (int i = 0; i < in_spacers.Length; i++)
5886 {
5887 object s = in_spacers.Data[i];
5888 for (int j = 0; j < separators.Length; j++)
5889 {
5890 if (separators.Data[j].ToString() == s.ToString())
5891 {
5892 s = null;
5893 break;
5894 }
5895 }
5896 if (s != null)
5897 {
5898 spacers.Add(s);
5899 }
5900 }
5901 }
5902 object[] delimiters = new object[separators.Length + spacers.Length];
5903 separators.Data.CopyTo(delimiters, 0);
5904 spacers.Data.CopyTo(delimiters, separators.Length);
5905 bool dfound = false;
5906 do
5907 {
5908 dfound = false;
5909 int cindex = -1;
5910 string cdeli = "";
5911 for (int i = 0; i < delimiters.Length; i++)
5912 {
5913 int index = str.IndexOf(delimiters[i].ToString());
5914 bool found = index != -1;
5915 if (found && String.Empty != delimiters[i].ToString())
5916 {
5917 if ((cindex > index) || (cindex == -1))
5918 {
5919 cindex = index;
5920 cdeli = delimiters[i].ToString();
5921 }
5922 dfound = dfound || found;
5923 }
5924 }
5925 if (cindex != -1)
5926 {
5927 if (cindex > 0)
5928 {
5929 ret.Add(new LSL_String(str.Substring(0, cindex)));
5930 }
5931 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5932 for (int j = 0; j < spacers.Length; j++)
5933 {
5934 if (spacers.Data[j].ToString() == cdeli)
5935 {
5936 ret.Add(new LSL_String(cdeli));
5937 break;
5938 }
5939 }
5940 str = str.Substring(cindex + cdeli.Length);
5941 }
5942 } while (dfound);
5943 if (str != "")
5944 {
5945 ret.Add(new LSL_String(str));
5946 }
5947 return ret;
5948 } 5881 }
5949 5882
5950 public LSL_Integer llOverMyLand(string id) 5883 public LSL_Integer llOverMyLand(string id)
@@ -8616,8 +8549,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8616 // The function returns an ordered list 8549 // The function returns an ordered list
8617 // representing the tokens found in the supplied 8550 // representing the tokens found in the supplied
8618 // sources string. If two successive tokenizers 8551 // sources string. If two successive tokenizers
8619 // are encountered, then a NULL entry is added 8552 // are encountered, then a null-string entry is
8620 // to the list. 8553 // added to the list.
8621 // 8554 //
8622 // It is a precondition that the source and 8555 // It is a precondition that the source and
8623 // toekizer lisst are non-null. If they are null, 8556 // toekizer lisst are non-null. If they are null,
@@ -8625,7 +8558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8625 // while their lengths are being determined. 8558 // while their lengths are being determined.
8626 // 8559 //
8627 // A small amount of working memoryis required 8560 // A small amount of working memoryis required
8628 // of approximately 8*#tokenizers. 8561 // of approximately 8*#tokenizers + 8*srcstrlen.
8629 // 8562 //
8630 // There are many ways in which this function 8563 // There are many ways in which this function
8631 // can be implemented, this implementation is 8564 // can be implemented, this implementation is
@@ -8641,109 +8574,109 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8641 // and eliminates redundant tokenizers as soon 8574 // and eliminates redundant tokenizers as soon
8642 // as is possible. 8575 // as is possible.
8643 // 8576 //
8644 // The implementation tries to avoid any copying 8577 // The implementation tries to minimize temporary
8645 // of arrays or other objects. 8578 // garbage generation.
8646 // </remarks> 8579 // </remarks>
8647 8580
8648 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8581 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8649 { 8582 {
8583 return ParseString2List(src, separators, spacers, true);
8584 }
8585
8586 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8587 {
8650 int srclen = src.Length; 8588 int srclen = src.Length;
8651 int seplen = separators.Length; 8589 int seplen = separators.Length;
8652 object[] separray = separators.Data; 8590 object[] separray = separators.Data;
8653 int spclen = spacers.Length; 8591 int spclen = spacers.Length;
8654 object[] spcarray = spacers.Data; 8592 object[] spcarray = spacers.Data;
8593 int dellen = 0;
8594 string[] delarray = new string[seplen+spclen];
8655 8595
8656 int outlen = 0; 8596 int outlen = 0;
8657 LSL_String[] outarray = new LSL_String[srclen*2+1]; 8597 string[] outarray = new string[srclen*2+1];
8658 8598
8659 int i, j, lastUsed; 8599 int i, j;
8600 string d;
8660 8601
8661 m_host.AddScriptLPS(1); 8602 m_host.AddScriptLPS(1);
8662 8603
8663 /* 8604 /*
8664 * Point to beginning of current non-delimeter string. 8605 * Convert separator and spacer lists to C# strings.
8606 * Also filter out null strings so we don't hang.
8665 */ 8607 */
8666 lastUsed = 0; 8608 for (i = 0; i < seplen; i ++) {
8609 d = separray[i].ToString();
8610 if (d.Length > 0) {
8611 delarray[dellen++] = d;
8612 }
8613 }
8614 seplen = dellen;
8615
8616 for (i = 0; i < spclen; i ++) {
8617 d = spcarray[i].ToString();
8618 if (d.Length > 0) {
8619 delarray[dellen++] = d;
8620 }
8621 }
8667 8622
8668 /* 8623 /*
8669 * Scan through source string from beginning to end. 8624 * Scan through source string from beginning to end.
8670 */ 8625 */
8671 for (i = 0; i < srclen;) { 8626 for (i = 0;;) {
8672 8627
8673 /* 8628 /*
8674 * See if rest of string (starting at i) matches any separator. 8629 * Find earliest delimeter in src starting at i (if any).
8675 */ 8630 */
8676 string rest = src.Substring(i); 8631 int earliestDel = -1;
8677 for (j = 0; j < seplen; j ++) { 8632 int earliestSrc = srclen;
8678 string sep = separray[j].ToString(); 8633 string earliestStr = null;
8679 if ((sep.Length > 0) && rest.StartsWith(sep)) { 8634 for (j = 0; j < dellen; j ++) {
8680 8635 d = delarray[j];
8681 /* 8636 if (d != null) {
8682 * Separator matched, output string from end of last delimeter to beginning of this one. 8637 int index = src.IndexOf(d, i);
8683 */ 8638 if (index < 0) {
8684 outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed)); 8639 delarray[j] = null; // delim nowhere in src, don't check it anymore
8685 8640 } else if (index < earliestSrc) {
8686 /* 8641 earliestSrc = index; // where delimeter starts in source string
8687 * Remove separator from input string. 8642 earliestDel = j; // where delimeter is in delarray[]
8688 */ 8643 earliestStr = d; // the delimeter string from delarray[]
8689 i += sep.Length; 8644 if (index == i) break; // can't do any better than found at beg of string
8690 8645 }
8691 /*
8692 * Next non-delimeter starts where this separator left off.
8693 */
8694 lastUsed = i;
8695 goto nextsrc;
8696 } 8646 }
8697 } 8647 }
8698 8648
8699 /* 8649 /*
8700 * See if rest of string (starting at i) matches any spacer. 8650 * Output source string starting at i through start of earliest delimeter.
8701 */ 8651 */
8702 for (j = 0; j < spclen; j ++) { 8652 if (keepNulls || (earliestSrc > i)) {
8703 string spc = spcarray[j].ToString(); 8653 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8704 if ((spc.Length > 0) && rest.StartsWith(spc)) {
8705
8706 /*
8707 * Spacer matched, output string from end of last delimeter to beginning of this one.
8708 * Then output the spacer itself.
8709 */
8710 outarray[outlen++] = new LSL_String(src.Substring(lastUsed,i-lastUsed));
8711 outarray[outlen++] = new LSL_String(spc);
8712
8713 /*
8714 * Remove spacer from input string.
8715 */
8716 i += spc.Length;
8717
8718 /*
8719 * Next non-delimeter starts where this spacer left off.
8720 */
8721 lastUsed = i;
8722 goto nextsrc;
8723 }
8724 } 8654 }
8725 8655
8726 /* 8656 /*
8727 * Didn't match any separator or spacer, skip over it and it 8657 * If no delimeter found at or after i, we're done scanning.
8728 * becomes part of the non-delimeter string starting with
8729 * lastUsed.
8730 */ 8658 */
8731 i ++; 8659 if (earliestDel < 0) break;
8732 nextsrc:;
8733 }
8734 8660
8735 /* 8661 /*
8736 * Output last non-delimeter (including a possible null string if 8662 * If delimeter was a spacer, output the spacer.
8737 * delimeter ran to end of source string). 8663 */
8738 */ 8664 if (earliestDel >= seplen) {
8739 outarray[outlen++] = new LSL_String(src.Substring(lastUsed)); 8665 outarray[outlen++] = earliestStr;
8666 }
8667
8668 /*
8669 * Look at rest of src string following delimeter.
8670 */
8671 i = earliestSrc + earliestStr.Length;
8672 }
8740 8673
8741 /* 8674 /*
8742 * Make up an exact-sized output array suitable for an LSL_List object. 8675 * Make up an exact-sized output array suitable for an LSL_List object.
8743 */ 8676 */
8744 object[] outlist = new object[outlen]; 8677 object[] outlist = new object[outlen];
8745 for (i = 0; i < outlen; i ++) { 8678 for (i = 0; i < outlen; i ++) {
8746 outlist[i] = outarray[i]; 8679 outlist[i] = new LSL_String(outarray[i]);
8747 } 8680 }
8748 return new LSL_List(outlist); 8681 return new LSL_List(outlist);
8749 } 8682 }