diff options
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 201 |
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 | } |