progress
This commit is contained in:
parent
16e76d6b31
commit
484dbfc9d9
529 changed files with 113694 additions and 0 deletions
667
AspClassic.VBScript/Runtime/HelperFunctions.cs
Normal file
667
AspClassic.VBScript/Runtime/HelperFunctions.cs
Normal file
|
@ -0,0 +1,667 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
#if USE35
|
||||
using AspClassic.Scripting.Ast;
|
||||
#else
|
||||
using System.Linq.Expressions;
|
||||
#endif
|
||||
|
||||
namespace Dlrsoft.VBScript.Runtime
|
||||
{
|
||||
public class HelperFunctions
|
||||
{
|
||||
public static object GetDefaultPropertyValue(object target)
|
||||
{
|
||||
if (target == null) return target;
|
||||
|
||||
while (target.GetType().IsCOMObject)
|
||||
{
|
||||
target = target.GetType().InvokeMember(string.Empty,
|
||||
BindingFlags.Default | BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.GetProperty,
|
||||
null,
|
||||
target,
|
||||
null);
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
public static object Concatenate(object left, object right)
|
||||
{
|
||||
bool leftDBNull = false;
|
||||
|
||||
if (left == null)
|
||||
{
|
||||
left = String.Empty;
|
||||
}
|
||||
else if (left is DBNull)
|
||||
{
|
||||
left = String.Empty;
|
||||
leftDBNull = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (left.GetType().IsCOMObject)
|
||||
{
|
||||
left = GetDefaultPropertyValue(left);
|
||||
}
|
||||
|
||||
if (!(left is string))
|
||||
{
|
||||
left = left.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
if (right == null)
|
||||
{
|
||||
right = string.Empty;
|
||||
}
|
||||
else if (right is DBNull)
|
||||
{
|
||||
if (leftDBNull) return DBNull.Value;
|
||||
right = string.Empty;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (right.GetType().IsCOMObject)
|
||||
{
|
||||
right = GetDefaultPropertyValue(right);
|
||||
}
|
||||
|
||||
if (!(right is string))
|
||||
{
|
||||
right = right.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return (string)left + (string)right;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static object BinaryOp(ExpressionType op, object left, object right)
|
||||
{
|
||||
if (left == null || right == null)
|
||||
{
|
||||
if (op == ExpressionType.Equal)
|
||||
{
|
||||
if (left == null && right == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (string.Empty.Equals(left) || string.Empty.Equals(right))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (op == ExpressionType.NotEqual)
|
||||
{
|
||||
if (left == null && right == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (string.Empty.Equals(left) || string.Empty.Equals(right))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Type ltype = left.GetType();
|
||||
Type rtype = right.GetType();
|
||||
|
||||
if (op == ExpressionType.Equal)
|
||||
{
|
||||
if (left == right) return true;
|
||||
}
|
||||
|
||||
|
||||
if (ltype.IsCOMObject)
|
||||
{
|
||||
left = GetDefaultPropertyValue(left);
|
||||
ltype = left.GetType();
|
||||
}
|
||||
|
||||
if (rtype.IsCOMObject)
|
||||
{
|
||||
right = GetDefaultPropertyValue(right);
|
||||
rtype = right.GetType();
|
||||
}
|
||||
|
||||
if (!ltype.IsValueType && ltype != typeof(string))
|
||||
{
|
||||
left = left.ToString();
|
||||
ltype = typeof(string);
|
||||
}
|
||||
|
||||
if (!rtype.IsValueType && rtype != typeof(string))
|
||||
{
|
||||
right = right.ToString();
|
||||
rtype = typeof(string);
|
||||
}
|
||||
|
||||
Type targetType;
|
||||
if (ltype == rtype || CanConvert(rtype, ltype))
|
||||
{
|
||||
targetType = ltype;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetType = rtype;
|
||||
}
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case ExpressionType.Add:
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) + Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double))
|
||||
{
|
||||
return Convert.ToDouble(left) + Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) + Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) + Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) + Convert.ToDecimal(right);
|
||||
}
|
||||
else if (targetType == typeof(string))
|
||||
{
|
||||
return (string)left + (string)right;
|
||||
}
|
||||
break;
|
||||
case ExpressionType.Subtract:
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) - Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double) || targetType == typeof(string))
|
||||
{
|
||||
return Convert.ToDouble(left) - Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) - Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) - Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) - Convert.ToDecimal(right);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.Multiply:
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) * Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double) || targetType == typeof(string))
|
||||
{
|
||||
return Convert.ToDouble(left) * Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) * Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) * Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) * Convert.ToDecimal(right);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.Divide:
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) / Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double) || targetType == typeof(string))
|
||||
{
|
||||
return Convert.ToDouble(left) / Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) / Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) / Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) / Convert.ToDecimal(right);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.Equal:
|
||||
try
|
||||
{
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) == Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double))
|
||||
{
|
||||
return Convert.ToDouble(left) == Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) == Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) == Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) == Convert.ToDecimal(right);
|
||||
}
|
||||
else if (targetType == typeof(string))
|
||||
{
|
||||
return ((string)left).Equals(right);
|
||||
}
|
||||
else
|
||||
{
|
||||
return left == right;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
case ExpressionType.NotEqual:
|
||||
try
|
||||
{
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) != Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double))
|
||||
{
|
||||
return Convert.ToDouble(left) != Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) != Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) != Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) != Convert.ToDecimal(right);
|
||||
}
|
||||
else if (targetType == typeof(string))
|
||||
{
|
||||
return !((string)left).Equals(right);
|
||||
}
|
||||
else
|
||||
{
|
||||
return left != right;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
case ExpressionType.GreaterThan:
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) > Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double))
|
||||
{
|
||||
return Convert.ToDouble(left) > Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) > Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) > Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) > Convert.ToDecimal(right);
|
||||
}
|
||||
else if (targetType == typeof(string))
|
||||
{
|
||||
int result = ((string)left).CompareTo(right);
|
||||
return (result > 0);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.GreaterThanOrEqual:
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) >= Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double))
|
||||
{
|
||||
return Convert.ToDouble(left) >= Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) >= Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) >= Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) >= Convert.ToDecimal(right);
|
||||
}
|
||||
else if (targetType == typeof(string))
|
||||
{
|
||||
int result = ((string)left).CompareTo(right);
|
||||
return (result >= 0);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.LessThan:
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) < Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double))
|
||||
{
|
||||
return Convert.ToDouble(left) < Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) < Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) < Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) < Convert.ToDecimal(right);
|
||||
}
|
||||
else if (targetType == typeof(string))
|
||||
{
|
||||
int result = ((string)left).CompareTo(right);
|
||||
return (result < 0);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.LessThanOrEqual:
|
||||
if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) <= Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(double))
|
||||
{
|
||||
return Convert.ToDouble(left) <= Convert.ToDouble(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) <= Convert.ToInt64(right);
|
||||
}
|
||||
else if (targetType == typeof(float))
|
||||
{
|
||||
return Convert.ToSingle(left) <= Convert.ToSingle(right);
|
||||
}
|
||||
else if (targetType == typeof(decimal))
|
||||
{
|
||||
return Convert.ToDecimal(left) <= Convert.ToDecimal(right);
|
||||
}
|
||||
else if (targetType == typeof(string))
|
||||
{
|
||||
int result = ((string)left).CompareTo(right);
|
||||
return (result <= 0);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.And:
|
||||
if (targetType == typeof(bool))
|
||||
{
|
||||
return (bool)left && (bool)right;
|
||||
}
|
||||
else if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) & Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) & Convert.ToInt64(right);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bool)BuiltInFunctions.CBool(left) && (bool)BuiltInFunctions.CBool(right);
|
||||
}
|
||||
break;
|
||||
case ExpressionType.Or:
|
||||
if (targetType == typeof(bool))
|
||||
{
|
||||
return (bool)left || (bool)right;
|
||||
}
|
||||
else if (targetType == typeof(int))
|
||||
{
|
||||
return Convert.ToInt32(left) | Convert.ToInt32(right);
|
||||
}
|
||||
else if (targetType == typeof(long))
|
||||
{
|
||||
return Convert.ToInt64(left) | Convert.ToInt64(right);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (bool)BuiltInFunctions.CBool(left) || (bool)BuiltInFunctions.CBool(right);
|
||||
}
|
||||
break;
|
||||
}
|
||||
throw new ArgumentException(string.Format("Operation {0} between {1} and {2} is not implemeted.", op, ltype.Name, rtype.Name));
|
||||
}
|
||||
|
||||
private static bool CanConvert(Type fromType, Type toType)
|
||||
{
|
||||
if (toType.IsAssignableFrom(fromType)) return true;
|
||||
|
||||
if (fromType == typeof(string) && (toType.IsPrimitive))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static object Redim(Type t, params int[] ubounds)
|
||||
{
|
||||
return redimInternal(t, ubounds);
|
||||
}
|
||||
|
||||
public static Array redimInternal(Type t, params int[] ubounds)
|
||||
{
|
||||
if (ubounds == null) throw new ArgumentException("Must supply bound(s) when redim an array.");
|
||||
for (int i = 0; i < ubounds.Length; i++)
|
||||
{
|
||||
//Convert from ubound to length
|
||||
ubounds[i] += 1;
|
||||
}
|
||||
|
||||
|
||||
return Array.CreateInstance(t, ubounds);
|
||||
}
|
||||
|
||||
//public static object RedimPreserve(object array, int length1)
|
||||
//{
|
||||
// return redimPreserveInternal(array, length1);
|
||||
//}
|
||||
|
||||
//public static object RedimPreserve(object array, int length1, int length2)
|
||||
//{
|
||||
// return redimPreserveInternal(array, length1, length2);
|
||||
//}
|
||||
|
||||
//public static object RedimPreserve(object array, int length1, int length2, int length3)
|
||||
//{
|
||||
// return redimPreserveInternal(array, length1, length2, length3);
|
||||
//}
|
||||
|
||||
//public static object RedimPreserve(object array, int length1, int length2, int length3, int length4)
|
||||
//{
|
||||
// return redimPreserveInternal(array, length1, length2, length3, length4);
|
||||
//}
|
||||
|
||||
//public static object RedimPreserve(object array, int length1, int length2, int length3, int length4, int length5)
|
||||
//{
|
||||
// return redimPreserveInternal(array, length1, length2, length3, length4, length5);
|
||||
//}
|
||||
|
||||
//public static object RedimPreserve(object array, int length1, int length2, int length3, int length4, int length5, int length6)
|
||||
//{
|
||||
// return redimPreserveInternal(array, length1, length2, length3, length4, length5, length6);
|
||||
//}
|
||||
|
||||
public static object RedimPreserve(object array, params int[] lengths)
|
||||
{
|
||||
return redimPreserveInternal(array, lengths);
|
||||
}
|
||||
|
||||
private static Array redimPreserveInternal(object array, params int[] lengths)
|
||||
{
|
||||
if (array == null) throw new ArgumentException("To redim an array, the array must be a previously declared array.");
|
||||
|
||||
Type t = array.GetType();
|
||||
|
||||
if (!t.IsArray) throw new ArgumentException("Redim variable is not an array.");
|
||||
|
||||
int oldDimension = ((Array)array).Rank;
|
||||
int newDimension = lengths.Length;
|
||||
|
||||
if (oldDimension != newDimension) throw new ArgumentException(string.Format("Cannot change dimension of the array from {0} to {1}", oldDimension, newDimension));
|
||||
|
||||
int elementsToCopy = 1;
|
||||
for (int i = 0; i < oldDimension - 1; i++)
|
||||
{
|
||||
int oldBound = ((Array)array).GetUpperBound(i);
|
||||
if (oldBound != lengths[i])
|
||||
throw new ArgumentException(string.Format("Can only resize the last dimension. You are trying to resize dimension {0} from {1} to {2}",
|
||||
i + 1, oldBound, lengths[i]));
|
||||
|
||||
elementsToCopy *= ((Array)array).GetLength(i);
|
||||
}
|
||||
|
||||
elementsToCopy *= (((Array)array).GetLength(oldDimension - 1) < lengths[oldDimension - 1]) ? ((Array)array).GetLength(oldDimension - 1) : lengths[oldDimension - 1];
|
||||
|
||||
Array newArray = redimInternal(t.GetElementType(), lengths);
|
||||
|
||||
Array.Copy((Array)array, newArray, elementsToCopy);
|
||||
|
||||
return newArray;
|
||||
}
|
||||
|
||||
public static void SetError(ErrObject err, Exception ex)
|
||||
{
|
||||
//Don't catch ThreadAbortException since it is captured by Response.Redirect
|
||||
if (ex is ThreadAbortException)
|
||||
throw ex;
|
||||
|
||||
err.internalRaise(ex);
|
||||
}
|
||||
|
||||
public static object Eqv(object left, object right)
|
||||
{
|
||||
if (left is DBNull || right is DBNull) return DBNull.Value;
|
||||
|
||||
CheckLogicOperand(ref left);
|
||||
CheckLogicOperand(ref right);
|
||||
if (left is int) BoolToInt(ref right);
|
||||
if (right is int) BoolToInt(ref left);
|
||||
|
||||
if (left is bool)
|
||||
return (bool)left == (bool)right;
|
||||
|
||||
return ~((int)left ^ (int)right);
|
||||
}
|
||||
|
||||
public static object Imp(object left, object right)
|
||||
{
|
||||
throw new NotImplementedException("Imp method is not implemented.");
|
||||
}
|
||||
|
||||
public static object Not(object target)
|
||||
{
|
||||
if (target == null) return null;
|
||||
|
||||
if (target.GetType().IsCOMObject)
|
||||
{
|
||||
target = GetDefaultPropertyValue(target);
|
||||
}
|
||||
|
||||
return !(bool)BuiltInFunctions.CBool(target);
|
||||
}
|
||||
|
||||
public static object Negate(object target)
|
||||
{
|
||||
if (target == null) return null;
|
||||
|
||||
if (target.GetType().IsCOMObject)
|
||||
{
|
||||
target = GetDefaultPropertyValue(target);
|
||||
}
|
||||
|
||||
return -(double)BuiltInFunctions.CDbl(target);
|
||||
}
|
||||
|
||||
private static void CheckLogicOperand(ref object value)
|
||||
{
|
||||
if (value == null) value = 0;
|
||||
|
||||
if (value is float || value is double)
|
||||
{
|
||||
value = Convert.ToInt32(value);
|
||||
}
|
||||
|
||||
if (value is string)
|
||||
{
|
||||
bool boolResult;
|
||||
int intResult;
|
||||
if (bool.TryParse((string)value, out boolResult))
|
||||
{
|
||||
value = boolResult;
|
||||
}
|
||||
else if (int.TryParse((string)value, out intResult))
|
||||
{
|
||||
value = intResult;
|
||||
}
|
||||
}
|
||||
|
||||
if (value is bool || value is int) return;
|
||||
|
||||
throw new ArgumentException("Logic functions or operators requires arguments that can be converted to bool or int.");
|
||||
}
|
||||
|
||||
private static void BoolToInt(ref object value)
|
||||
{
|
||||
if (value is bool) value = (bool)value ? -1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue