private CallFromNative ( string function, object thisObject ) : object | ||
function | string | The name of the caller function. |
thisObject | object | The value of the "this" keyword within the function. |
return | object |
public TypedArrayInstance From(object source, FunctionInstance mapFn = null, object thisArg = null) { var items = TypeConverter.ToObject(Engine, source); var iterator = TypeUtilities.GetIterator(Engine, items); if (iterator != null) { // Loop. var values = new List <object>(); foreach (var value in TypeUtilities.Iterate(Engine, iterator)) { // Collect the values. values.Add(value); } // Convert the values into a typed array instance. var result = new TypedArrayInstance(this.InstancePrototype, this.type, Engine.ArrayBuffer.Construct(values.Count * BytesPerElement), 0, values.Count); for (int i = 0; i < values.Count; i++) { if (mapFn != null) { result[i] = mapFn.CallFromNative("from", thisArg, values[i], i); } else { result[i] = values[i]; } } return(result); } else { // There was no iterator symbol value, so fall back on the alternate method. int length = TypeConverter.ToInt32(items["length"]); var result = new TypedArrayInstance(this.InstancePrototype, this.type, Engine.ArrayBuffer.Construct(length * BytesPerElement), 0, length); for (int i = 0; i < length; i++) { if (mapFn != null) { result[i] = mapFn.CallFromNative("from", thisArg, items[i], i); } else { result[i] = items[i]; } } return(result); } }
/// <summary> /// Creates a new array with the elements from this array that pass the test implemented by /// the given function. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element in the /// array. This function is called with three arguments: the value of the element, the /// index of the element, and the array that is being operated on. The function should /// return <c>true</c> or <c>false</c>. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> /// <returns> A copy of this array but with only those elements which produce <c>true</c> /// when passed to the provided function. </returns> public ObjectInstance Filter(FunctionInstance callbackFunction, ObjectInstance context) { // Create a new array to hold the new values. var result = new List <T>(Length / 2); for (int i = 0; i < Length; i++) { // Get the value of the array element. T elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. bool includeInArray = TypeConverter.ToBoolean(callbackFunction.CallFromNative("filter", context, elementValue, i, WrappedInstance)); // Store the result if the callback function returned true. if (includeInArray == true) { result.Add(elementValue); } } } return(ConstructArray(result.ToArray())); }
public TypedArrayInstance Sort(FunctionInstance comparisonFunction = null) { Comparison <object> comparer; if (comparisonFunction == null) { // Default comparer. comparer = (a, b) => { double x = TypeConverter.ToNumber(a); double y = TypeConverter.ToNumber(b); if (x < y) { return(-1); } if (x > y) { return(1); } if (double.IsNaN(x) && double.IsNaN(y)) { return(0); } if (double.IsNaN(x)) { return(1); } if (double.IsNaN(y)) { return(-1); } if (TypeUtilities.IsNegativeZero(x) && TypeUtilities.IsPositiveZero(y)) { return(-1); } if (TypeUtilities.IsPositiveZero(x) && TypeUtilities.IsNegativeZero(y)) { return(1); } return(0); }; } else { // Custom comparer. comparer = (a, b) => { var v = TypeConverter.ToNumber(comparisonFunction.CallFromNative("sort", null, a, b)); if (double.IsNaN(v)) { return(0); } return(Math.Sign(v)); }; } return((TypedArrayInstance) new TypedArrayAdapter(this).Sort(comparer)); }
/// <summary> /// Calls the given user-defined function once per element in the array. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element in the /// array. This function is called with three arguments: the value of the element, the /// index of the element, and the array that is being operated on. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> public void ForEach(FunctionInstance callbackFunction, ObjectInstance context) { for (int i = 0; i < Length; i++) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. callbackFunction.CallFromNative("forEach", context, elementValue, i, WrappedInstance); } } }
/// <summary> /// Determines if at least one element of the array matches criteria defined by the given /// user-defined function. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element in the /// array. This function is called with three arguments: the value of the element, the /// index of the element, and the array that is being operated on. The function should /// return <c>true</c> or <c>false</c>. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> /// <returns> <c>true</c> if at least one element of the array matches criteria defined by /// the given user-defined function; <c>false</c> otherwise. </returns> public bool Some(FunctionInstance callbackFunction, ObjectInstance context) { for (int i = 0; i < Length; i++) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. if (TypeConverter.ToBoolean(callbackFunction.CallFromNative("some", context, elementValue, i, WrappedInstance)) == true) { return(true); } } } return(false); }
/// <summary> /// Accumulates a single value by calling a user-defined function for each element /// (starting with the last element in the array). /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element /// in the array. This function is called with four arguments: the current accumulated /// value, the value of the element, the index of the element, and the array that is being /// operated on. The return value for this function is the new accumulated value and is /// passed to the next invocation of the function. </param> /// <param name="initialValue"> The initial accumulated value. </param> /// <returns> The accumulated value returned from the last invocation of the callback /// function. </returns> public object ReduceRight(FunctionInstance callbackFunction, object initialValue) { // If an initial value is not provided, the initial value is the last (defined) element. int i = Length - 1; object accumulatedValue = initialValue; if (accumulatedValue == null) { // Scan for a defined element. for (; i >= 0; i--) { if (this[i] != null) { accumulatedValue = this[i--]; break; } } if (accumulatedValue == null) { throw new JavaScriptException(ErrorType.TypeError, "Reduce of empty array with no initial value"); } } // Scan from high to to low. for (; i >= 0; i--) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. accumulatedValue = callbackFunction.CallFromNative("reduceRight", Undefined.Value, accumulatedValue, elementValue, i, WrappedInstance); } } return(accumulatedValue); }
/// <summary> /// Returns a copy of this string with text replaced using a replacement function. /// </summary> /// <param name="thisObject"> The string that is being operated on. </param> /// <param name="substr"> The text to search for. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of this string with text replaced. </returns> public static string Replace(string thisObject, string substr, FunctionInstance replaceFunction) { // Find the first occurrance of substr. int start = thisObject.IndexOf(substr, StringComparison.Ordinal); if (start == -1) { return(thisObject); } int end = start + substr.Length; // Get the replacement text from the provided function. var replaceText = TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, substr, start, thisObject)); // Replace only the first match. var result = new System.Text.StringBuilder(thisObject.Length + (replaceText.Length - substr.Length)); result.Append(thisObject, 0, start); result.Append(replaceText); result.Append(thisObject, end, thisObject.Length - end); return(result.ToString()); }
/// <summary> /// Returns an index in the typed array, if an element in the typed array satisfies the /// provided testing function. Otherwise -1 is returned. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element in the /// array. This function is called with three arguments: the value of the element, the /// index of the element, and the array that is being operated on. The function should /// return <c>true</c> or <c>false</c>. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> /// <returns> The first element that results in the callback returning <c>true</c>. </returns> public int FindIndex(FunctionInstance callbackFunction, ObjectInstance context) { for (int i = 0; i < Length; i++) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. bool result = TypeConverter.ToBoolean(callbackFunction.CallFromNative("findIndex", context, elementValue, i, WrappedInstance)); // Return if the result was true. if (result == true) { return(i); } } } // No matches, return undefined. return(-1); }
/// <summary> /// Creates a new array with the results of calling the given function on every element in /// this array. /// </summary> /// <param name="callbackFunction"> A user-defined function that is called for each element /// in the array. This function is called with three arguments: the value of the element, /// the index of the element, and the array that is being operated on. The value that is /// returned from this function is stored in the resulting array. </param> /// <param name="context"> The value of <c>this</c> in the context of the callback function. </param> /// <returns> A new array with the results of calling the given function on every element /// in the array. </returns> public ObjectInstance Map(FunctionInstance callbackFunction, ObjectInstance context) { // Create a new array to hold the new values. // The length of the output array is always equal to the length of the input array. var resultArray = new T[Length]; for (int i = 0; i < Length; i++) { // Get the value of the array element. object elementValue = this[i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. object result = callbackFunction.CallFromNative("map", context, elementValue, i, WrappedInstance); // Store the result. resultArray[i] = ConvertValue(result); } } return(ConstructArray(resultArray)); }
/// <summary> /// Returns a copy of the given string with text replaced using a regular expression. /// </summary> /// <param name="input"> The string on which to perform the search. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of the given string with text replaced using a regular expression. </returns> public string Replace(string input, FunctionInstance replaceFunction) { return(this.value.Replace(input, match => { // Set the deprecated RegExp properties. this.Engine.RegExp.SetDeprecatedProperties(input, match); object[] parameters = new object[match.Groups.Count + 2]; for (int i = 0; i < match.Groups.Count; i++) { if (match.Groups[i].Success == false) { parameters[i] = Undefined.Value; } else { parameters[i] = match.Groups[i].Value; } } parameters[match.Groups.Count] = match.Index; parameters[match.Groups.Count + 1] = input; return TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, parameters)); }, this.Global == true ? int.MaxValue : 1)); }
/// <summary> /// Returns a copy of this string with text replaced using a replacement function. /// </summary> /// <param name="substr"> The text to search for. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of this string with text replaced. </returns> public static string Replace(string thisObject, string substr, FunctionInstance replaceFunction) { // Find the first occurrance of substr. int start = thisObject.IndexOf(substr, StringComparison.Ordinal); if (start == -1) return thisObject; int end = start + substr.Length; // Get the replacement text from the provided function. var replaceText = TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, substr, start, thisObject)); // Replace only the first match. var result = new System.Text.StringBuilder(thisObject.Length + (replaceText.Length - substr.Length)); result.Append(thisObject, 0, start); result.Append(replaceText); result.Append(thisObject, end, thisObject.Length - end); return result.ToString(); }
public static object ReduceRight(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] object initialValue = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); // If an initial value is not provided, the initial value is the last (defined) element. int i = (int)arrayLength - 1; object accumulatedValue = initialValue; if (accumulatedValue == null) { // Scan for a defined element. for (; i >= 0; i--) { if (thisObj[(uint)i] != null) { accumulatedValue = thisObj[(uint)(i--)]; break; } } if (accumulatedValue == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Reduce of empty array with no initial value"); } // Scan from high to to low. for (; i >= 0; i--) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. accumulatedValue = callbackFunction.CallFromNative("reduceRight", Undefined.Value, accumulatedValue, elementValue, i, thisObj); } } return accumulatedValue; }
public static ArrayInstance Filter(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] ObjectInstance context = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); // Create a new array to hold the new values. var result = thisObj.Engine.Array.New(); for (int i = 0; i < arrayLength; i++) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. bool includeInArray = TypeConverter.ToBoolean(callbackFunction.CallFromNative("filter", context, elementValue, i, thisObj)); // Store the result if the callback function returned true. if (includeInArray == true) result.Push(elementValue); } } return result; }
public static ArrayInstance Map(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] ObjectInstance context = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); // Create a new array to hold the new values. // The length of the output array is always equal to the length of the input array. var resultArray = new ArrayInstance(thisObj.Engine.Array.InstancePrototype, arrayLength, arrayLength); for (int i = 0; i < arrayLength; i++) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. object result = callbackFunction.CallFromNative("map", context, elementValue, i, thisObj); // Store the result. resultArray[(uint)i] = result; } } return resultArray; }
public static void ForEach(ObjectInstance thisObj, FunctionInstance callbackFunction, [DefaultParameterValue(null)] ObjectInstance context = null) { // callbackFunction must be a valid function. if (callbackFunction == null) throw new JavaScriptException(thisObj.Engine, "TypeError", "Invalid callback function"); // Get the length of the array. uint arrayLength = GetLength(thisObj); // This method only supports arrays of length up to 2^31-1. if (arrayLength > int.MaxValue) throw new JavaScriptException(thisObj.Engine, "RangeError", "The array is too long"); for (int i = 0; i < arrayLength; i++) { // Get the value of the array element. object elementValue = thisObj[(uint)i]; // Only call the callback function for array elements that exist in the array. if (elementValue != null) { // Call the callback function. callbackFunction.CallFromNative("forEach", context, elementValue, i, thisObj); } } }
/// <summary> /// Returns a copy of the given string with text replaced using a regular expression. /// </summary> /// <param name="input"> The string on which to perform the search. </param> /// <param name="replaceFunction"> A function that is called to produce the text to replace /// for every successful match. </param> /// <returns> A copy of the given string with text replaced using a regular expression. </returns> public string Replace(string input, FunctionInstance replaceFunction) { return this.value.Replace(input, match => { // Set the deprecated RegExp properties. this.Engine.RegExp.SetDeprecatedProperties(input, match); object[] parameters = new object[match.Groups.Count + 2]; for (int i = 0; i < match.Groups.Count; i++) { if (match.Groups[i].Success == false) parameters[i] = Undefined.Value; else parameters[i] = match.Groups[i].Value; } parameters[match.Groups.Count] = match.Index; parameters[match.Groups.Count + 1] = input; return TypeConverter.ToString(replaceFunction.CallFromNative("replace", null, parameters)); }, this.Global == true ? int.MaxValue : 1); }