Esempio n. 1
0
		/// <summary>
		/// Private mehtod implementing all replace methods. Just one of <paramref name="replacement"/> or <paramref name="callback" /> should be used.
		/// </summary>
        /// <param name="context">Current <see cref="ScriptContext"/>. Must not be null.</param>
        /// <param name="self">Instance of object that called the replace method (replace pattern may contain $this)</param>
        /// <param name="definedVariables"></param>
        /// <param name="pattern"></param>
        /// <param name="replacement"></param>
        /// <param name="callback"></param>
        /// <param name="data"></param>
        /// <param name="limit"></param>
        /// <param name="count"></param>
		/// <returns>String or an array.</returns>
		private static object Replace(ScriptContext/*!*/context, DObject self, Dictionary<string, object> definedVariables, object pattern, object replacement, PhpCallback callback,
			object data, int limit, ref int count)
		{
			// if we have no replacement and no callback, matches are deleted (replaced by an empty string)
			if (replacement == null && callback == null)
				replacement = String.Empty;

			// exactly one of replacement or callback is valid now
			Debug.Assert(replacement != null ^ callback != null);

			// get eval info if it has been captured - is needed even if we do not need them later
            SourceCodeDescriptor descriptor = context.GetCapturedSourceCodeDescriptor();

			// PHP's behaviour for undocumented limit range
			if (limit < -1)
				limit = 0;
            
            PhpArray replacement_array = replacement as PhpArray;

			string replacement_string = null;
			if (replacement_array == null && replacement != null)
				replacement_string = Core.Convert.ObjectToString(replacement);

			// we should return new array, if there is an array passed as subject, it should remain unchanged:
			object data_copy = PhpVariable.DeepCopy(data);

            PhpArray pattern_array = pattern as PhpArray;
            if (pattern_array == null)
            {
                // string pattern
                // string replacement

                if (replacement_array != null)
                {
                    // string pattern and array replacement not allowed:
                    PhpException.InvalidArgument("replacement", LibResources.GetString("replacement_array_pattern_not"));
                    return null;
                }

                // pattern should be treated as string and therefore replacement too:
                return SimpleReplace(self, definedVariables, pattern, replacement_string, callback, data_copy, limit, descriptor, ref count);
            }
            else if (replacement_array == null)
            {
                // array  pattern
                // string replacement

                using (var pattern_enumerator = pattern_array.GetFastEnumerator())
                    while (pattern_enumerator.MoveNext())
                    {
                        data_copy = SimpleReplace(self, definedVariables, pattern_enumerator.CurrentValue, replacement_string,
                                    callback, data_copy, limit, descriptor, ref count);
                    }
            }
            else //if (replacement_array != null)
            {
                // array pattern
                // array replacement

                var replacement_enumerator = replacement_array.GetFastEnumerator();
                bool replacement_valid = true;

                using (var pattern_enumerator = pattern_array.GetFastEnumerator())
                    while (pattern_enumerator.MoveNext())
                    {
                        // replacements are in array, move to next item and take it if possible, in other case take empty string:
                        if (replacement_valid && replacement_enumerator.MoveNext())
                        {
                            replacement_string = Core.Convert.ObjectToString(replacement_enumerator.CurrentValue);
                        }
                        else
                        {
                            replacement_string = string.Empty;
                            replacement_valid = false;  // end of replacement_enumerator, do not call MoveNext again!
                        }

                        data_copy = SimpleReplace(self, definedVariables, pattern_enumerator.CurrentValue, replacement_string,
                                    callback, data_copy, limit, descriptor, ref count);
                    }
            }
            
			// return resulting array or string assigned to data
			return data_copy;
		}