Exemple #1
0
        /// <inheritdoc />
        public override Func <ITag, CompileContext, Type> BuildGuessMethod()
        {
            return((tag, c) =>
            {
                var t = tag as ArithmeticTag;
                var types = new List <Type>();
                var opts = new List <Operator>();
                for (var i = 0; i < t.Children.Count; i++)
                {
                    var opt = t.Children[i] as OperatorTag;
                    if (opt == null)
                    {
                        types.Add(c.GuessType(t.Children[i]));
                    }
                }
                if (types.Count == 1)
                {
                    return types[0];
                }
                if (types.Contains(typeof(string)))
                {
                    return typeof(string);
                }
                if (types.Count > 0)
                {
                    return TypeGuesser.FindBestType(types.ToArray());
                }

                return typeof(int);
            });
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="options"></param>
        /// <param name="parser"></param>
        /// <param name="compileBuilder"></param>
        /// <param name="typeGuesser"></param>
        /// <param name="executorBuilder"></param>
        /// <param name="scopeProvider"></param>
        /// <param name="cache"></param>
        /// <param name="resourceLoader"></param>
        public DefaultHostEnvironment(IOptions options   = null
                                      , TagParser parser = null
                                      , CompileBuilder compileBuilder   = null
                                      , TypeGuesser typeGuesser         = null
                                      , ExecutorBuilder executorBuilder = null
                                      , IScopeProvider scopeProvider    = null
                                      , ICache cache = null
                                      , IResourceLoader resourceLoader = null)
        {
            this.Results             = new ResultCollection <IResult>();
            this.EnvironmentVariable = new Dictionary <string, string>(System.StringComparer.OrdinalIgnoreCase);
            this.Options             = options ?? new RuntimeOptions();
            this.RootPath            = System.IO.Directory.GetCurrentDirectory();
            this.Parser          = parser ?? new TagParser();
            this.Builder         = compileBuilder ?? new CompileBuilder();
            this.Guesser         = typeGuesser ?? new TypeGuesser();
            this.ExecutorBuilder = executorBuilder ?? new ExecutorBuilder();
            this.ScopeProvider   = scopeProvider ?? new DefaultScopeProvider();
            this.Cache           = cache ?? new MemoryCache();
            this.Loader          = resourceLoader ?? new FileLoader();
            this.ApplicationName = Guid.NewGuid().ToString("N");
            this.EnvironmentName =
#if DEBUG
                "DEBUG"
#else
                "RELEASE"
#endif
            ;
            if (Options.Data == null &&
                ScopeProvider != null)
            {
                Options.Data = ScopeProvider.CreateScope();
            }
        }
Exemple #3
0
        public TokenCollection ExtractTokens(Response response)
        {
            TokenCollection tokens = new TokenCollection();

            if (response.Headers.ContainsKey("Set-Cookie"))
            {
                foreach (string cookieHeader in response.Headers["Set-Cookie"])
                {
                    string[] vals = cookieHeader.Split(';', '=');
                    tokens.Add(new CookieToken(vals[0], vals[1], TypeGuesser.GuessTypes(vals[1])));
                }
            }

            return(tokens);
        }
Exemple #4
0
        private TokenCollection JsonToTokens(string json)
        {
            TokenCollection tokens = new TokenCollection();

            try
            {
                JsonTextReader reader = new JsonTextReader(new StringReader(json));
                while (reader.Read())
                {
                    if (reader.Value != null && reader.TokenType == Newtonsoft.Json.JsonToken.PropertyName)
                    {
                        string name = reader.Value.ToString() ?? "";
                        string path = reader.Path;
                        // Console.WriteLine(path);
                        reader.Read();
                        if (reader.TokenType == Newtonsoft.Json.JsonToken.String)
                        {
                            string value     = reader.Value.ToString() ?? "";
                            Types  supported = Types.String | TypeGuesser.GuessTypes(value);
                            tokens.Add(new Tokens.JsonToken(name, value, path, supported));
                        }
                        else if (reader.TokenType == Newtonsoft.Json.JsonToken.Integer)
                        {
                            tokens.Add(new Tokens.JsonToken(name, reader.Value.ToString() ?? "", path, Types.Integer));
                        }
                        else if (reader.TokenType == Newtonsoft.Json.JsonToken.Boolean)
                        {
                            tokens.Add(new Tokens.JsonToken(name, reader.Value.ToString() ?? "", path, Types.Boolean));
                        }
                        else if (reader.TokenType == Newtonsoft.Json.JsonToken.Null)
                        {
                            // TODO: Re-Evaluate handling of null values.
                            tokens.Add(new Tokens.JsonToken(name, "", path, Types.Boolean));
                        }
                    }
                }
            }
            catch
            {
                Console.WriteLine("JSON parsing failure.");
            }

            return(tokens);
        }
Exemple #5
0
        public TokenCollection ExtractTokens(Request request)
        {
            TokenCollection tokens = new TokenCollection();

            if (request.Headers.ContainsKey("Cookie"))
            {
                foreach (string cookieHeader in request.Headers["Cookie"])
                {
                    string[] cookies = cookieHeader.Split(';');

                    foreach (string cookieString in cookies)
                    {
                        string[] vals = cookieString.Split('=');
                        tokens.Add(new CookieToken(vals[0], vals[1], TypeGuesser.GuessTypes(vals[1])));
                    }
                }
            }

            return(tokens);
        }
Exemple #6
0
        private static void ResolveField(XmlWriter writer, KeyValuePair <uint, byte[]> kv)
        {
            string fieldType  = FieldHandling.GetTypeName(FieldType.BinHex);
            string fieldValue = BitConverter.ToString(kv.Value).Replace("-", "");

            string r_fieldTypeString  = fieldType;
            string r_fieldValueString = fieldValue;

            if (kv.Key == TextHidNameHash)
            {
                FieldType fileNameFieldType  = FieldType.String;
                string    fileNameFieldValue = FieldHandling.Deserialize <string>(fileNameFieldType, kv.Value);

                writer.WriteAttributeString("type", FieldHandling.GetTypeName(fileNameFieldType));
                writer.WriteString(fileNameFieldValue);

                Console.WriteLine($"Resolved name field in file \"{fileNameFieldValue}\"");
            }
            else
            {
                if (TypeGuesser.FieldHandler(kv.Value, out r_fieldTypeString, out r_fieldValueString) == true)
                {
                    if (r_fieldTypeString != FieldHandling.GetTypeName(FieldType.BinHex))
                    {
                        fieldType  = r_fieldTypeString;
                        fieldValue = r_fieldValueString;
                    }

                    writer.WriteAttributeString($"value-{r_fieldTypeString}", fieldValue);
                }

                //writer.WriteAttributeString("type", r_fieldTypeString);
                //writer.WriteString(fieldValue);

                writer.WriteAttributeString("type", FieldHandling.GetTypeName(FieldType.BinHex));
                writer.WriteBinHex(kv.Value, 0, kv.Value.Length);
            }

            //Utility.Log($"Field Value\n\tfrom: {BitConverter.ToString(kv.Value).Replace(" ", "")}\n\tto: {fieldValue}");
        }
Exemple #7
0
        private static FieldInfo ResolveField(uint key, byte[] value)
        {
            FieldInfo field = new FieldInfo();

            // key
            string keyTypeString = "hash";
            string keyNameString = $"{key:X8}";

            if (StringHasher.CanResolveHash((int)key))
            {
                keyTypeString = "name";
                keyNameString = StringHasher.ResolveHash((int)key);
            }

            // value
            string valueTypeString  = FieldHandling.GetTypeName(FieldType.BinHex);
            string valueValueString = BitConverter.ToString(value).Replace("-", "");

            string r_valueTypeString  = valueTypeString;
            string r_valueValueString = valueValueString;

            if (TypeGuesser.FieldHandler(value, out r_valueTypeString, out r_valueValueString) == true)
            {
                valueTypeString  = r_valueTypeString;
                valueValueString = r_valueValueString;
            }

            // fill structure
            field.key.type = keyTypeString;
            field.key.name = keyNameString;

            field.value.type  = valueTypeString;
            field.value.value = valueValueString;

            return(field);
        }
Exemple #8
0
        private void RegiserCompile(IHost host)
        {
            host.RegisterCompileFunc <ReferenceTag>((tag, c) =>
            {
                return(c.CompileTag(((ReferenceTag)tag).Child));
            });

            host.RegisterCompileFunc <LogicTag>((tag, c) =>
            {
                var t          = tag as LogicTag;
                var type       = c.GuessType(t);
                var mb         = c.CreateReutrnMethod <LogicTag>(type);
                var il         = mb.GetILGenerator();
                Label labelEnd = il.DefineLabel();
                il.DeclareLocal(type);
                var array   = new object[t.Children.Count];
                var types   = new List <Type>();
                var opts    = new List <Operator>();
                var message = new List <string>();
                for (int i = 0; i < t.Children.Count; i++)
                {
                    var opt = t.Children[i] as OperatorTag;
                    if (opt != null)
                    {
                        if (!opts.Contains(opt.Value))
                        {
                            opts.Add(opt.Value);
                        }
                        array[i] = opt.Value;
                        message.Add(OperatorConvert.ToString(opt.Value));
                    }
                    else
                    {
                        array[i] = t.Children[i];
                        types.Add(c.GuessType(t.Children[i]));
                        message.Add(types[types.Count - 1].Name);
                    }
                }

                if (opts.Contains(Operator.Or) || opts.Contains(Operator.And))
                {
                    Label labelTrue  = il.DefineLabel();
                    Label labelFalse = il.DefineLabel();
                    Operator pre     = Operator.None;
                    for (int i = 0; i < t.Children.Count; i++)
                    {
                        var opt = t.Children[i] as OperatorTag;
                        if (opt != null)
                        {
                            pre = opt.Value;
                            continue;
                        }

                        var m = c.CompileTag(t.Children[i]);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Call, m);
                        if (m.ReturnType.Name != "Boolean")
                        {
                            var cm = typeof(Utility).GetMethodInfo("ToBoolean", new Type[] { m.ReturnType });
                            if (cm == null)
                            {
                                cm = typeof(Utility).GetMethodInfo("ToBoolean", new Type[] { typeof(object) });
                                if (m.ReturnType.IsValueType)
                                {
                                    il.Emit(OpCodes.Box, typeof(object));
                                }
                                else
                                {
                                    il.Emit(OpCodes.Castclass, typeof(object));
                                }
                            }
                            il.Emit(OpCodes.Call, cm);
                        }
                        //il.Emit(OpCodes.Stloc_0);
                        if (pre == Operator.None)
                        {
                            pre = (t.Children[i + 1] as OperatorTag).Value;
                        }

                        if (pre == Operator.Or)
                        {
                            il.Emit(OpCodes.Brtrue, labelTrue);
                        }
                        if (pre == Operator.And)
                        {
                            il.Emit(OpCodes.Brfalse, labelFalse);
                        }
                    }

                    if (pre == Operator.Or)
                    {
                        il.Emit(OpCodes.Br, labelEnd);
                    }

                    if (pre == Operator.And)
                    {
                        il.Emit(OpCodes.Br, labelTrue);
                    }
                    il.MarkLabel(labelTrue);
                    il.Emit(OpCodes.Ldc_I4_1);
                    il.Emit(OpCodes.Stloc_0);
                    il.Emit(OpCodes.Br, labelEnd);


                    il.MarkLabel(labelFalse);
                    il.Emit(OpCodes.Ldc_I4_0);
                    il.Emit(OpCodes.Stloc_0);
                }
                else
                {
                    if (t.Children.Count == 1)
                    {
                        var m = c.CompileTag(t.Children[0]);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Call, m);
                        il.Emit(OpCodes.Stloc_0);
                    }
                    else if (t.Children.Count == 3)
                    {
                        var bestType = TypeGuesser.FindBestType(types.ToArray());
                        var stack    = ExpressionEvaluator.ProcessExpression(array);
                        var arr      = stack.ToArray();
                        for (var i = arr.Length - 1; i >= 0; i--)
                        {
                            var obj      = arr[i];
                            var childTag = obj as ITag;
                            if (childTag != null)
                            {
                                var m = c.CompileTag(childTag);
                                il.Emit(OpCodes.Ldarg_0);
                                il.Emit(OpCodes.Ldarg_1);
                                il.Emit(OpCodes.Call, m);
                                if (m.ReturnType.FullName != bestType.FullName)
                                {
                                    switch (bestType.FullName)
                                    {
                                    case "System.Decimal":
                                        Type cType = m.ReturnType;
                                        switch (cType.FullName)
                                        {
                                        case "System.Int16":
                                        case "System.UInt16":
                                        case "System.Byte":
                                            il.Emit(OpCodes.Conv_I4);
                                            break;
                                        }
                                        il.Emit(OpCodes.Call, typeof(decimal).GetConstructor(new Type[] { cType }));
                                        break;

                                    case "System.Double":
                                        il.Emit(OpCodes.Conv_R8);
                                        break;

                                    case "System.Single":
                                        il.Emit(OpCodes.Conv_R4);
                                        break;

                                    case "System.Int64":
                                        il.Emit(OpCodes.Conv_I8);
                                        break;

                                    case "System.UInt64":
                                        il.Emit(OpCodes.Conv_U8);
                                        break;

                                    case "System.Int32":
                                        il.Emit(OpCodes.Conv_I4);
                                        break;

                                    case "System.UInt32":
                                        il.Emit(OpCodes.Conv_U4);
                                        break;

                                    case "System.Int16":
                                        il.Emit(OpCodes.Conv_I2);
                                        break;

                                    case "System.UInt16":
                                        il.Emit(OpCodes.Conv_U2);
                                        break;

                                    case "System.Byte":
                                        il.Emit(OpCodes.Conv_U1);
                                        break;

                                    case "System.String":
                                        if (m.ReturnType.IsValueType)
                                        {
                                            var p = il.DeclareLocal(m.ReturnType);
                                            il.Emit(OpCodes.Stloc, p.LocalIndex);
                                            il.Emit(OpCodes.Ldloca, p.LocalIndex);
                                        }
                                        il.Call(m.ReturnType, typeof(object).GetMethodInfo("ToString", Type.EmptyTypes));
                                        break;

                                    default:
                                        if (m.ReturnType.IsValueType)
                                        {
                                            if (bestType.IsValueType)
                                            {
                                                il.Emit(OpCodes.Isinst, bestType);
                                            }
                                            else
                                            {
                                                il.Emit(OpCodes.Box, bestType);
                                            }
                                        }
                                        else
                                        {
                                            if (bestType.IsValueType)
                                            {
                                                il.Emit(OpCodes.Unbox, bestType);
                                            }
                                            else
                                            {
                                                il.Emit(OpCodes.Castclass, bestType);
                                            }
                                        }
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                switch ((Operator)obj)
                                {
                                case Operator.GreaterThan:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Cgt);
                                    }
                                    else
                                    {
                                        var m = bestType.GetMethodInfo("op_GreaterThan", new Type[] { bestType, bestType });
                                        if (m == null)
                                        {
                                            throw new TemplateException($"Operator \">\" can not be applied operand \"{bestType.FullName}\" and \"{bestType.FullName}\"");
                                        }
                                        il.Emit(OpCodes.Call, m);
                                    }
                                    break;

                                case Operator.GreaterThanOrEqual:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Clt_Un);
                                        il.Emit(OpCodes.Ldc_I4_0);
                                        il.Emit(OpCodes.Ceq);
                                    }
                                    else
                                    {
                                        var m = bestType.GetMethodInfo("op_GreaterThanOrEqual", new Type[] { bestType, bestType });
                                        if (m == null)
                                        {
                                            throw new TemplateException($"Operator \">=\" can not be applied operand \"{bestType.FullName}\" and \"{bestType.FullName}\"");
                                        }
                                        il.Emit(OpCodes.Call, m);
                                    }
                                    break;

                                case Operator.LessThan:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Clt);
                                    }
                                    else
                                    {
                                        var m = bestType.GetMethodInfo("op_LessThan", new Type[] { bestType, bestType });
                                        if (m == null)
                                        {
                                            throw new TemplateException($"Operator \"<\" can not be applied operand \"{bestType.FullName}\" and \"{bestType.FullName}\"");
                                        }
                                        il.Emit(OpCodes.Call, m);
                                    }
                                    break;

                                case Operator.LessThanOrEqual:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Cgt_Un);
                                        il.Emit(OpCodes.Ldc_I4_0);
                                        il.Emit(OpCodes.Ceq);
                                    }
                                    else
                                    {
                                        var m = bestType.GetMethodInfo("op_LessThanOrEqual", new Type[] { bestType, bestType });
                                        if (m == null)
                                        {
                                            throw new TemplateException($"Operator \"<=\" can not be applied operand \"{bestType.FullName}\" and \"{bestType.FullName}\"");
                                        }
                                        il.Emit(OpCodes.Call, m);
                                    }
                                    break;

                                case Operator.Equal:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Ceq);
                                    }
                                    else
                                    {
                                        il.EmitEquals(bestType);
                                        //il.Emit(OpCodes.Call, DynamicHelpers.GetMethodInfo(bestType, "Equals", new Type[] { bestType }));
                                    }
                                    break;

                                case Operator.NotEqual:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Ceq);
                                    }
                                    else
                                    {
                                        il.EmitEquals(bestType);
                                        //il.Emit(OpCodes.Call, DynamicHelpers.GetMethodInfo(bestType, "Equals", new Type[] { bestType }));
                                    }
                                    il.Emit(OpCodes.Ldc_I4_0);
                                    il.Emit(OpCodes.Ceq);
                                    break;

                                default:
                                    throw new CompileException(tag, $"The operator \"{obj}\" is not supported on type  \"{bestType.FullName}\" .");
                                }
                            }
                        }
                        il.Emit(OpCodes.Stloc_0);
                    }
                    else
                    {
                        throw new CompileException(tag, $"[LogicExpressionTag] : The expression \"{string.Concat(message)}\" is not supported .");
                    }
                }

                il.MarkLabel(labelEnd);
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ret);
                return(mb.GetBaseDefinition());
            });

            host.RegisterCompileFunc <ArithmeticTag>((tag, c) =>
            {
                var stringBuilderType = typeof(StringBuilder);
                var t          = tag as ArithmeticTag;
                var type       = c.GuessType(t);
                var mb         = c.CreateReutrnMethod <ArithmeticTag>(type);
                var il         = mb.GetILGenerator();
                Label labelEnd = il.DefineLabel();
                il.DeclareLocal(type);
                var array   = new object[t.Children.Count];
                var types   = new List <Type>();
                var opts    = new List <Operator>();
                var message = new List <string>();
                for (int i = 0; i < t.Children.Count; i++)
                {
                    var opt = t.Children[i] as OperatorTag;
                    if (opt != null)
                    {
                        if (!opts.Contains(opt.Value))
                        {
                            opts.Add(opt.Value);
                        }
                        array[i] = opt.Value;
                        message.Add(OperatorConvert.ToString(opt.Value));
                    }
                    else
                    {
                        array[i] = t.Children[i];
                        types.Add(c.GuessType(t.Children[i]));
                        message.Add(types[types.Count - 1].Name);
                    }
                }
                if (types.Contains(typeof(string)) && opts.Count == 1 && opts[0] == Operator.Add)
                {
                    il.DeclareLocal(stringBuilderType);
                    il.Emit(OpCodes.Newobj, stringBuilderType.GetConstructor(Type.EmptyTypes));
                    il.Emit(OpCodes.Stloc_1);
                    for (int i = 0; i < t.Children.Count; i++)
                    {
                        var opt = t.Children[i] as OperatorTag;
                        if (opt != null)
                        {
                            continue;
                        }
                        il.Emit(OpCodes.Ldloc_1);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldarg_1);
                        var m = c.CompileTag(t.Children[i]);
                        il.Emit(OpCodes.Call, m);
                        il.StringAppend(c, m.ReturnType);
                        il.Emit(OpCodes.Pop);
                    }

                    il.Emit(OpCodes.Ldloc_1);
                    il.Call(stringBuilderType, typeof(object).GetMethodInfo("ToString", Type.EmptyTypes));
                    il.Emit(OpCodes.Stloc_0);
                }
                else
                {
                    var bestType = TypeGuesser.FindBestType(types.ToArray());
                    var stack    = ExpressionEvaluator.ProcessExpression(array);
                    var arr      = stack.ToArray();
                    for (var i = arr.Length - 1; i >= 0; i--)
                    {
                        var obj      = arr[i];
                        var childTag = obj as ITag;
                        if (childTag != null)
                        {
                            var m = c.CompileTag(childTag);
                            il.Emit(OpCodes.Ldarg_0);
                            il.Emit(OpCodes.Ldarg_1);
                            il.Emit(OpCodes.Call, m);
                            if (m.ReturnType.FullName != bestType.FullName)
                            {
                                switch (bestType.FullName)
                                {
                                case "System.Decimal":
                                    Type cType = m.ReturnType;
                                    switch (cType.FullName)
                                    {
                                    case "System.Int16":
                                    case "System.UInt16":
                                    case "System.Byte":
                                        il.Emit(OpCodes.Conv_I4);
                                        break;
                                    }
                                    il.Emit(OpCodes.Call, typeof(decimal).GetConstructor(new Type[] { cType }));
                                    break;

                                case "System.Double":
                                    il.Emit(OpCodes.Conv_R8);
                                    break;

                                case "System.Single":
                                    il.Emit(OpCodes.Conv_R4);
                                    break;

                                case "System.Int64":
                                    il.Emit(OpCodes.Conv_I8);
                                    break;

                                case "System.UInt64":
                                    il.Emit(OpCodes.Conv_U8);
                                    break;

                                case "System.Int32":
                                    il.Emit(OpCodes.Conv_I4);
                                    break;

                                case "System.UInt32":
                                    il.Emit(OpCodes.Conv_U4);
                                    break;

                                case "System.Int16":
                                    il.Emit(OpCodes.Conv_I2);
                                    break;

                                case "System.UInt16":
                                    il.Emit(OpCodes.Conv_U2);
                                    break;

                                case "System.Byte":
                                    il.Emit(OpCodes.Conv_U1);
                                    break;

                                default:
                                    throw new CompileException(tag, $"[ExpressionTag] : The type \"{bestType.FullName}\" is not supported .");
                                }
                            }
                        }
                        else
                        {
                            switch ((Operator)obj)
                            {
                            case Operator.Add:
                                il.Emit(OpCodes.Add);
                                break;

                            case Operator.Subtract:
                                il.Emit(OpCodes.Sub);
                                break;

                            case Operator.Multiply:
                                il.Emit(OpCodes.Mul);
                                break;

                            case Operator.Divided:
                                il.Emit(OpCodes.Div);
                                break;

                            case Operator.Remainder:
                                il.Emit(OpCodes.Rem);
                                break;

                            case Operator.GreaterThan:
                                il.Emit(OpCodes.Cgt);
                                break;

                            case Operator.GreaterThanOrEqual:
                                il.Emit(OpCodes.Clt_Un);
                                il.Emit(OpCodes.Ldc_I4_0);
                                il.Emit(OpCodes.Ceq);
                                break;

                            case Operator.LessThan:
                                il.Emit(OpCodes.Clt);
                                break;

                            case Operator.LessThanOrEqual:
                                il.Emit(OpCodes.Cgt_Un);
                                il.Emit(OpCodes.Ldc_I4_0);
                                il.Emit(OpCodes.Ceq);
                                break;

                            case Operator.Equal:
                                il.Emit(OpCodes.Ceq);
                                break;

                            case Operator.NotEqual:
                                il.Emit(OpCodes.Ceq);
                                il.Emit(OpCodes.Ldc_I4_0);
                                il.Emit(OpCodes.Ceq);
                                break;

                            default:
                                throw new CompileException(tag, $"[ExpressionTag] : The expression \"{string.Concat(message)}\" is not supported .");
                                //throw new CompileException($"The operator \"{obj}\" is not supported on type  \"{bestType.FullName}\" .");
                                //case Operator.Or:
                                //    il.Emit(OpCodes.Blt);
                                //    break;
                            }
                        }
                    }
                    il.Emit(OpCodes.Stloc_0);
                }
                il.MarkLabel(labelEnd);
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ret);
                return(mb.GetBaseDefinition());
            });

            host.RegisterGuessFunc <ReferenceTag>((tag, c) =>
            {
                return(c.GuessType(((ReferenceTag)tag).Child));
            });

            host.RegisterGuessFunc <LogicTag>((tag, ctx) =>
            {
                return(typeof(bool));
            });

            host.RegisterGuessFunc <ArithmeticTag>((tag, ctx) =>
            {
                var t     = tag as ArithmeticTag;
                var types = new List <Type>();
                var opts  = new List <Operator>();
                for (var i = 0; i < t.Children.Count; i++)
                {
                    var opt = t.Children[i] as OperatorTag;
                    if (opt == null)
                    {
                        types.Add(ctx.GuessType(t.Children[i]));
                    }
                }
                if (types.Count == 1)
                {
                    return(types[0]);
                }
                if (types.Contains(typeof(string)))
                {
                    return(typeof(string));
                }
                if (types.Count > 0)
                {
                    return(TypeGuesser.FindBestType(types.ToArray()));
                }

                return(typeof(int));
            });
        }
        /// <inheritdoc />
        public override Func <ITag, CompileContext, MethodInfo> BuildCompileMethod()
        {
            return((tag, c) =>
            {
                var t = tag as LogicTag;
                var type = c.GuessType(t);
                var mb = c.CreateReutrnMethod <LogicTag>(type);
                var il = mb.GetILGenerator();
                Label labelEnd = il.DefineLabel();
                il.DeclareLocal(type);
                var array = new object[t.Children.Count];
                var types = new List <Type>();
                var opts = new List <Operator>();
                var message = new List <string>();
                for (int i = 0; i < t.Children.Count; i++)
                {
                    var opt = t.Children[i] as OperatorTag;
                    if (opt != null)
                    {
                        if (!opts.Contains(opt.Value))
                        {
                            opts.Add(opt.Value);
                        }
                        array[i] = opt.Value;
                        message.Add(OperatorConvert.ToString(opt.Value));
                    }
                    else
                    {
                        array[i] = t.Children[i];
                        types.Add(c.GuessType(t.Children[i]));
                        message.Add(types[types.Count - 1].Name);
                    }
                }

                if (opts.Contains(Operator.Or) || opts.Contains(Operator.And))
                {
                    Label labelTrue = il.DefineLabel();
                    Label labelFalse = il.DefineLabel();
                    Operator pre = Operator.None;
                    for (int i = 0; i < t.Children.Count; i++)
                    {
                        var opt = t.Children[i] as OperatorTag;
                        if (opt != null)
                        {
                            pre = opt.Value;
                            continue;
                        }

                        var m = c.CompileTag(t.Children[i]);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Call, m);
                        if (m.ReturnType.Name != "Boolean")
                        {
                            var cm = typeof(Utility).GetMethodInfo("ToBoolean", new Type[] { m.ReturnType });
                            if (cm == null)
                            {
                                cm = typeof(Utility).GetMethodInfo("ToBoolean", new Type[] { typeof(object) });
                                if (m.ReturnType.IsValueType)
                                {
                                    il.Emit(OpCodes.Box, typeof(object));
                                }
                                else
                                {
                                    il.Emit(OpCodes.Castclass, typeof(object));
                                }
                            }
                            il.Emit(OpCodes.Call, cm);
                        }
                        //il.Emit(OpCodes.Stloc_0);
                        if (pre == Operator.None)
                        {
                            pre = (t.Children[i + 1] as OperatorTag).Value;
                        }

                        if (pre == Operator.Or)
                        {
                            il.Emit(OpCodes.Brtrue, labelTrue);
                        }
                        if (pre == Operator.And)
                        {
                            il.Emit(OpCodes.Brfalse, labelFalse);
                        }
                    }

                    if (pre == Operator.Or)
                    {
                        il.Emit(OpCodes.Br, labelEnd);
                    }

                    if (pre == Operator.And)
                    {
                        il.Emit(OpCodes.Br, labelTrue);
                    }
                    il.MarkLabel(labelTrue);
                    il.Emit(OpCodes.Ldc_I4_1);
                    il.Emit(OpCodes.Stloc_0);
                    il.Emit(OpCodes.Br, labelEnd);


                    il.MarkLabel(labelFalse);
                    il.Emit(OpCodes.Ldc_I4_0);
                    il.Emit(OpCodes.Stloc_0);
                }
                else
                {
                    if (t.Children.Count == 1)
                    {
                        var m = c.CompileTag(t.Children[0]);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Call, m);
                        il.Emit(OpCodes.Stloc_0);
                    }
                    else if (t.Children.Count == 3)
                    {
                        var bestType = TypeGuesser.FindBestType(types.ToArray());
                        var stack = ExpressionEvaluator.ProcessExpression(array);
                        var arr = stack.ToArray();
                        for (var i = arr.Length - 1; i >= 0; i--)
                        {
                            var obj = arr[i];
                            var childTag = obj as ITag;
                            if (childTag != null)
                            {
                                var m = c.CompileTag(childTag);
                                il.Emit(OpCodes.Ldarg_0);
                                il.Emit(OpCodes.Ldarg_1);
                                il.Emit(OpCodes.Call, m);
                                if (m.ReturnType.FullName != bestType.FullName)
                                {
                                    il.ConvertTo(m.ReturnType, bestType);
                                }
                            }
                            else
                            {
                                switch ((Operator)obj)
                                {
                                case Operator.GreaterThan:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Cgt);
                                    }
                                    else
                                    {
                                        var m = bestType.GetMethodInfo("op_GreaterThan", new Type[] { bestType, bestType });
                                        if (m == null)
                                        {
                                            throw new TemplateException($"Operator \">\" can not be applied operand \"{bestType.FullName}\" and \"{bestType.FullName}\"");
                                        }
                                        il.Emit(OpCodes.Call, m);
                                    }
                                    break;

                                case Operator.GreaterThanOrEqual:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Clt_Un);
                                        il.Emit(OpCodes.Ldc_I4_0);
                                        il.Emit(OpCodes.Ceq);
                                    }
                                    else
                                    {
                                        var m = bestType.GetMethodInfo("op_GreaterThanOrEqual", new Type[] { bestType, bestType });
                                        if (m == null)
                                        {
                                            throw new TemplateException($"Operator \">=\" can not be applied operand \"{bestType.FullName}\" and \"{bestType.FullName}\"");
                                        }
                                        il.Emit(OpCodes.Call, m);
                                    }
                                    break;

                                case Operator.LessThan:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Clt);
                                    }
                                    else
                                    {
                                        var m = bestType.GetMethodInfo("op_LessThan", new Type[] { bestType, bestType });
                                        if (m == null)
                                        {
                                            throw new TemplateException($"Operator \"<\" can not be applied operand \"{bestType.FullName}\" and \"{bestType.FullName}\"");
                                        }
                                        il.Emit(OpCodes.Call, m);
                                    }
                                    break;

                                case Operator.LessThanOrEqual:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Cgt_Un);
                                        il.Emit(OpCodes.Ldc_I4_0);
                                        il.Emit(OpCodes.Ceq);
                                    }
                                    else
                                    {
                                        var m = bestType.GetMethodInfo("op_LessThanOrEqual", new Type[] { bestType, bestType });
                                        if (m == null)
                                        {
                                            throw new TemplateException($"Operator \"<=\" can not be applied operand \"{bestType.FullName}\" and \"{bestType.FullName}\"");
                                        }
                                        il.Emit(OpCodes.Call, m);
                                    }
                                    break;

                                case Operator.Equal:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Ceq);
                                    }
                                    else
                                    {
                                        il.EmitEquals(bestType);
                                        //il.Emit(OpCodes.Call, DynamicHelpers.GetMethodInfo(bestType, "Equals", new Type[] { bestType }));
                                    }
                                    break;

                                case Operator.NotEqual:
                                    if (TypeGuesser.CanUseEqual(bestType))
                                    {
                                        il.Emit(OpCodes.Ceq);
                                    }
                                    else
                                    {
                                        il.EmitEquals(bestType);
                                        //il.Emit(OpCodes.Call, DynamicHelpers.GetMethodInfo(bestType, "Equals", new Type[] { bestType }));
                                    }
                                    il.Emit(OpCodes.Ldc_I4_0);
                                    il.Emit(OpCodes.Ceq);
                                    break;

                                default:
                                    throw new CompileException(tag, $"The operator \"{obj}\" is not supported on type  \"{bestType.FullName}\" .");
                                }
                            }
                        }
                        il.Emit(OpCodes.Stloc_0);
                    }
                    else
                    {
                        throw new CompileException(tag, $"[LogicExpressionTag] : The expression \"{string.Concat(message)}\" is not supported .");
                    }
                }

                il.MarkLabel(labelEnd);
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ret);
                return mb.GetBaseDefinition();
            });
        }
Exemple #10
0
        /// <inheritdoc />
        public override Func <ITag, CompileContext, MethodInfo> BuildCompileMethod()
        {
            return((tag, c) =>
            {
                var stringBuilderType = typeof(StringBuilder);
                var t = tag as ArithmeticTag;
                var type = c.GuessType(t);
                var mb = c.CreateReutrnMethod <ArithmeticTag>(type);
                var il = mb.GetILGenerator();
                Label labelEnd = il.DefineLabel();
                il.DeclareLocal(type);
                var array = new object[t.Children.Count];
                var types = new List <Type>();
                var opts = new List <Operator>();
                var message = new List <string>();
                for (int i = 0; i < t.Children.Count; i++)
                {
                    var opt = t.Children[i] as OperatorTag;
                    if (opt != null)
                    {
                        if (!opts.Contains(opt.Value))
                        {
                            opts.Add(opt.Value);
                        }
                        array[i] = opt.Value;
                        message.Add(OperatorConvert.ToString(opt.Value));
                    }
                    else
                    {
                        array[i] = t.Children[i];
                        types.Add(c.GuessType(t.Children[i]));
                        message.Add(types[types.Count - 1].Name);
                    }
                }
                if (types.Contains(typeof(string)) && opts.Count == 1 && opts[0] == Operator.Add)
                {
                    il.DeclareLocal(stringBuilderType);
                    il.Emit(OpCodes.Newobj, stringBuilderType.GetConstructor(Type.EmptyTypes));
                    il.Emit(OpCodes.Stloc_1);
                    for (int i = 0; i < t.Children.Count; i++)
                    {
                        var opt = t.Children[i] as OperatorTag;
                        if (opt != null)
                        {
                            continue;
                        }
                        il.Emit(OpCodes.Ldloc_1);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldarg_1);
                        var m = c.CompileTag(t.Children[i]);
                        il.Emit(OpCodes.Call, m);
                        il.StringAppend(c, m.ReturnType);
                        il.Emit(OpCodes.Pop);
                    }

                    il.Emit(OpCodes.Ldloc_1);
                    il.Call(stringBuilderType, typeof(object).GetMethodInfo("ToString", Type.EmptyTypes));
                    il.Emit(OpCodes.Stloc_0);
                }
                else
                {
                    var bestType = TypeGuesser.FindBestType(types.ToArray());
                    var stack = ExpressionEvaluator.ProcessExpression(array);
                    var arr = stack.ToArray();
                    for (var i = arr.Length - 1; i >= 0; i--)
                    {
                        var obj = arr[i];
                        var childTag = obj as ITag;
                        if (childTag != null)
                        {
                            var m = c.CompileTag(childTag);
                            il.Emit(OpCodes.Ldarg_0);
                            il.Emit(OpCodes.Ldarg_1);
                            il.Emit(OpCodes.Call, m);
                            if (m.ReturnType.FullName != bestType.FullName)
                            {
                                switch (bestType.FullName)
                                {
                                case "System.Decimal":
                                    Type cType = m.ReturnType;
                                    switch (cType.FullName)
                                    {
                                    case "System.Int16":
                                    case "System.UInt16":
                                    case "System.Byte":
                                        il.Emit(OpCodes.Conv_I4);
                                        break;
                                    }
                                    il.Emit(OpCodes.Call, typeof(decimal).GetConstructor(new Type[] { cType }));
                                    break;

                                case "System.Double":
                                    il.Emit(OpCodes.Conv_R8);
                                    break;

                                case "System.Single":
                                    il.Emit(OpCodes.Conv_R4);
                                    break;

                                case "System.Int64":
                                    il.Emit(OpCodes.Conv_I8);
                                    break;

                                case "System.UInt64":
                                    il.Emit(OpCodes.Conv_U8);
                                    break;

                                case "System.Int32":
                                    il.Emit(OpCodes.Conv_I4);
                                    break;

                                case "System.UInt32":
                                    il.Emit(OpCodes.Conv_U4);
                                    break;

                                case "System.Int16":
                                    il.Emit(OpCodes.Conv_I2);
                                    break;

                                case "System.UInt16":
                                    il.Emit(OpCodes.Conv_U2);
                                    break;

                                case "System.Byte":
                                    il.Emit(OpCodes.Conv_U1);
                                    break;

                                default:
                                    throw new CompileException(tag, $"[ExpressionTag] : The type \"{bestType.FullName}\" is not supported .");
                                }
                            }
                        }
                        else
                        {
                            switch ((Operator)obj)
                            {
                            case Operator.Add:
                                il.Emit(OpCodes.Add);
                                break;

                            case Operator.Subtract:
                                il.Emit(OpCodes.Sub);
                                break;

                            case Operator.Multiply:
                                il.Emit(OpCodes.Mul);
                                break;

                            case Operator.Divided:
                                il.Emit(OpCodes.Div);
                                break;

                            case Operator.Remainder:
                                il.Emit(OpCodes.Rem);
                                break;

                            case Operator.GreaterThan:
                                il.Emit(OpCodes.Cgt);
                                break;

                            case Operator.GreaterThanOrEqual:
                                il.Emit(OpCodes.Clt_Un);
                                il.Emit(OpCodes.Ldc_I4_0);
                                il.Emit(OpCodes.Ceq);
                                break;

                            case Operator.LessThan:
                                il.Emit(OpCodes.Clt);
                                break;

                            case Operator.LessThanOrEqual:
                                il.Emit(OpCodes.Cgt_Un);
                                il.Emit(OpCodes.Ldc_I4_0);
                                il.Emit(OpCodes.Ceq);
                                break;

                            case Operator.Equal:
                                il.Emit(OpCodes.Ceq);
                                break;

                            case Operator.NotEqual:
                                il.Emit(OpCodes.Ceq);
                                il.Emit(OpCodes.Ldc_I4_0);
                                il.Emit(OpCodes.Ceq);
                                break;

                            default:
                                throw new CompileException(tag, $"[ExpressionTag] : The expression \"{string.Concat(message)}\" is not supported .");
                                //throw new CompileException($"The operator \"{obj}\" is not supported on type  \"{bestType.FullName}\" .");
                                //case Operator.Or:
                                //    il.Emit(OpCodes.Blt);
                                //    break;
                            }
                        }
                    }
                    il.Emit(OpCodes.Stloc_0);
                }
                il.MarkLabel(labelEnd);
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Ret);
                return mb.GetBaseDefinition();
            });
        }
Exemple #11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="c"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        public static MethodInfo EnumerableForeachCompile(CompileContext c, ForeachTag tag, Type sourceType)
        {
            var getVariableScope = DynamicHelpers.GetPropertyGetMethod(typeof(TemplateContext), "TempData");
            var getVariableValue = typeof(VariableScope).GetMethod("get_Item", new[] { typeof(string) });

            var  stringBuilderType = typeof(StringBuilder);
            var  t    = tag;
            var  type = c.GuessType(t);
            var  variableScopeType   = typeof(VariableScope);
            var  templateContextType = typeof(TemplateContext);
            var  childType           = TypeGuesser.InferChildType(sourceType);
            var  enumerableType      = sourceType.GetInterface("IEnumerable`1");// typeof(System.Collections.IEnumerable);
            Type enumeratorType;
            bool mustTo = false;

            if (enumerableType == null)
            {
                enumerableType = typeof(System.Collections.IEnumerable);
                enumeratorType = typeof(System.Collections.IEnumerator);
                mustTo         = true;
            }
            else
            {
                enumeratorType = typeof(IEnumerator <>).MakeGenericType(childType);
            }
            if (childType.Length != 1)
            {
                throw new CompileException("[ForeachTag]:source error.");
            }
            var old   = c.Data;
            var scope = new VariableScope(old);

            c.Data = scope;
            c.Set(t.Name, childType[0]);
            c.Set("foreachIndex", typeof(int));
            var   mb         = c.CreateReutrnMethod <ForeachTag>(type);
            var   il         = mb.GetILGenerator();
            Label labelEnd   = il.DefineLabel();
            Label labelNext  = il.DefineLabel();
            Label labelStart = il.DefineLabel();

            il.DeclareLocal(stringBuilderType);
            il.DeclareLocal(enumerableType);
            il.DeclareLocal(templateContextType);
            il.DeclareLocal(typeof(bool));
            il.DeclareLocal(enumeratorType);
            il.DeclareLocal(typeof(Int32));
            il.DeclareLocal(childType[0]);
            il.DeclareLocal(typeof(bool));
            il.DeclareLocal(typeof(string));
            var types = new Type[t.Children.Count];

            for (var i = 0; i < t.Children.Count; i++)
            {
                types[i] = c.GuessType(t.Children[i]);
                if (t.Children[i] is SetTag setTag)
                {
                    c.Set(setTag.Name, c.GuessType(setTag.Value));
                }
                if (types[i].FullName == "System.Void" || t.Children[i] is TextTag)
                {
                    continue;
                }
            }
            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Newobj, stringBuilderType.GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            var method = c.CompileTag(t.Source);

            il.Emit(OpCodes.Call, method);
            il.Emit(OpCodes.Stloc_1);
            il.Emit(OpCodes.Ldloc_1);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Cgt_Un);
            il.Emit(OpCodes.Stloc_3);
            il.Emit(OpCodes.Ldloc_3);
            il.Emit(OpCodes.Brfalse, labelEnd);
            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldloc_1);
            il.Emit(OpCodes.Callvirt, DynamicHelpers.GetMethod(enumerableType, "GetEnumerator", Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_S, 4);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Call, DynamicHelpers.GetMethod(templateContextType, "CreateContext", new Type[] { templateContextType }));
            il.Emit(OpCodes.Stloc_2);
            il.Emit(OpCodes.Ldc_I4, 0);
            il.Emit(OpCodes.Stloc_S, 5);
            il.Emit(OpCodes.Br, labelNext);
            il.MarkLabel(labelStart);
            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldloc_S, 5);
            il.Emit(OpCodes.Ldc_I4, 1);
            il.Emit(OpCodes.Add);
            il.Emit(OpCodes.Stloc_S, 5);
            il.Emit(OpCodes.Ldloc_S, 4);
            il.Emit(OpCodes.Callvirt, DynamicHelpers.GetPropertyGetMethod(enumeratorType, "Current"));
            if (mustTo)
            {
                if (childType[0].IsValueType)
                {
                    il.Emit(OpCodes.Unbox_Any, childType[0]);
                }
                else
                {
                    il.Emit(OpCodes.Isinst, childType[0]);
                }
            }
            il.Emit(OpCodes.Stloc_S, 6);
            il.Emit(OpCodes.Ldloc, 2);
            il.Emit(OpCodes.Callvirt, getVariableScope);
            il.Emit(OpCodes.Ldstr, t.Name);
            il.Emit(OpCodes.Ldloc_S, 6);
            il.Emit(OpCodes.Callvirt, DynamicHelpers.GetGenericMethod(variableScopeType, childType, "Set", new Type[] { typeof(string), childType[0] }));

            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ldloc, 2);
            il.Emit(OpCodes.Callvirt, getVariableScope);
            il.Emit(OpCodes.Ldstr, "foreachIndex");
            il.Emit(OpCodes.Ldloc_S, 5);
            il.Emit(OpCodes.Callvirt, DynamicHelpers.GetGenericMethod(variableScopeType, new Type[] { typeof(int) }, "Set", new Type[] { typeof(string), typeof(int) }));
            il.Emit(OpCodes.Nop);

            il.StringAppend(c, t.Children, 0, 2);

            il.Emit(OpCodes.Nop);
            il.MarkLabel(labelNext);
            il.Emit(OpCodes.Ldloc_S, 4);
            if (!mustTo)
            {
                il.Emit(OpCodes.Callvirt, DynamicHelpers.GetMethod(typeof(System.Collections.IEnumerator), "MoveNext", Type.EmptyTypes));
            }
            else
            {
                il.Emit(OpCodes.Callvirt, DynamicHelpers.GetMethod(enumeratorType, "MoveNext", Type.EmptyTypes));
            }
            il.Emit(OpCodes.Stloc_S, 7);
            il.Emit(OpCodes.Ldloc_S, 7);
            il.Emit(OpCodes.Brtrue, labelStart);
            il.MarkLabel(labelEnd);
            il.Emit(OpCodes.Ldloc_0);
            il.Call(stringBuilderType, DynamicHelpers.GetMethod(typeof(object), "ToString", Type.EmptyTypes));
            il.Emit(OpCodes.Stloc_S, 8);
            il.Emit(OpCodes.Ldloc_S, 8);
            il.Emit(OpCodes.Ret);
            c.Data = old;
            return(mb.GetBaseDefinition());
        }
Exemple #12
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="c"></param>
        /// <param name="sourceType"></param>
        /// <returns></returns>
        public static MethodInfo ArrayForeachCompile(CompileContext c, ForeachTag tag, Type sourceType)
        {
            var getVariableScope = DynamicHelpers.GetPropertyGetMethod(typeof(TemplateContext), "TempData");
            var getVariableValue = typeof(VariableScope).GetMethod("get_Item", new[] { typeof(string) });

            var stringBuilderType = typeof(StringBuilder);
            var t                   = tag;
            var type                = c.GuessType(t);
            var childType           = TypeGuesser.InferChildType(sourceType);
            var templateContextType = typeof(TemplateContext);
            var variableScopeType   = typeof(VariableScope);

            if (childType.Length != 1)
            {
                throw new CompileException("[ForeachTag]:source error.");
            }

            var old   = c.Data;
            var scope = new VariableScope(old);

            c.Data = scope;
            c.Set(t.Name, childType[0]);
            c.Set("foreachIndex", typeof(int));

            var mb         = c.CreateReutrnMethod <ForeachTag>(type);
            var il         = mb.GetILGenerator();
            var labelNext  = il.DefineLabel();
            var labelStart = il.DefineLabel();
            var labelEnd   = il.DefineLabel();

            il.DeclareLocal(stringBuilderType);
            il.DeclareLocal(sourceType);
            il.DeclareLocal(typeof(bool));
            il.DeclareLocal(templateContextType);
            il.DeclareLocal(typeof(int));
            il.DeclareLocal(sourceType);
            il.DeclareLocal(typeof(int));
            il.DeclareLocal(childType[0]);
            il.DeclareLocal(typeof(string));

            var types = new Type[t.Children.Count];

            for (var i = 0; i < t.Children.Count; i++)
            {
                types[i] = c.GuessType(t.Children[i]);
                if (t.Children[i] is SetTag setTag)
                {
                    c.Set(setTag.Name, c.GuessType(setTag.Value));
                }
                if (types[i].FullName == "System.Void" || t.Children[i] is TextTag)
                {
                    continue;
                }
                il.DeclareLocal(types[i]);
            }


            il.Emit(OpCodes.Newobj, stringBuilderType.GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc, 0);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            var method = c.CompileTag(t.Source);

            il.Emit(OpCodes.Call, method);

            il.Emit(OpCodes.Stloc_1);
            il.Emit(OpCodes.Ldloc_1);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Cgt_Un);
            il.Emit(OpCodes.Stloc_2);
            il.Emit(OpCodes.Ldloc_2);
            il.Emit(OpCodes.Brfalse, labelEnd);


            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Call, DynamicHelpers.GetMethod(templateContextType, "CreateContext", new Type[] { templateContextType }));
            il.Emit(OpCodes.Stloc_3);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Stloc, 4);
            il.Emit(OpCodes.Ldloc_1);
            il.Emit(OpCodes.Stloc, 5);
            il.Emit(OpCodes.Ldc_I4_0);
            il.Emit(OpCodes.Stloc, 6);
            il.Emit(OpCodes.Br, labelStart);

            // loop start
            il.MarkLabel(labelNext);
            il.Emit(OpCodes.Ldloc, 5);
            il.Emit(OpCodes.Ldloc, 6);
            il.Ldelem(childType[0]);
            il.Emit(OpCodes.Stloc, 7);
            il.Emit(OpCodes.Ldloc, 4);
            il.Emit(OpCodes.Ldc_I4_1);
            il.Emit(OpCodes.Add);
            il.Emit(OpCodes.Stloc, 4);
            il.Emit(OpCodes.Ldloc, 3);
            il.Emit(OpCodes.Callvirt, getVariableScope);
            il.Emit(OpCodes.Ldstr, t.Name);
            il.Emit(OpCodes.Ldloc, 7);
            il.Emit(OpCodes.Callvirt, DynamicHelpers.GetGenericMethod(variableScopeType, childType, "Set", new Type[] { typeof(string), childType[0] }));
            il.Emit(OpCodes.Ldloc, 3);
            il.Emit(OpCodes.Callvirt, getVariableScope);
            il.Emit(OpCodes.Ldstr, "foreachIndex");
            il.Emit(OpCodes.Ldloc, 4);
            il.Emit(OpCodes.Callvirt, DynamicHelpers.GetGenericMethod(variableScopeType, new Type[] { typeof(int) }, "Set", new Type[] { typeof(string), typeof(int) }));

            il.StringAppend(c, t.Children, 0, 3);

            il.Emit(OpCodes.Ldloc, 6);
            il.Emit(OpCodes.Ldc_I4_1);
            il.Emit(OpCodes.Add);
            il.Emit(OpCodes.Stloc, 6);
            il.MarkLabel(labelStart);
            il.Emit(OpCodes.Ldloc, 6);
            il.Emit(OpCodes.Ldloc, 5);
            il.Emit(OpCodes.Ldlen);
            il.Emit(OpCodes.Conv_I4);
            il.Emit(OpCodes.Blt, labelNext);
            // end loop

            il.MarkLabel(labelEnd);
            il.Emit(OpCodes.Ldloc_0);
            il.Call(stringBuilderType, DynamicHelpers.GetMethod(typeof(object), "ToString", Type.EmptyTypes));
            il.Emit(OpCodes.Stloc, 8);
            il.Emit(OpCodes.Ldloc, 8);
            il.Emit(OpCodes.Ret);

            return(mb.GetBaseDefinition());
        }
Exemple #13
0
        void TypeGuesser_SimpleData_TypeInferredCorrectly(string val, Types expected)
        {
            Types types = TypeGuesser.GuessTypes(val);

            Assert.Equal(expected, types);
        }
Exemple #14
0
        private static bool ValidateField(KeyValuePair <uint, byte[]> kvCurrent, KeyValuePair <uint, byte[]> kvNext, out FieldInfo overrideFieldInfo)
        {
            FieldInfo fieldInfo = new FieldInfo();

            overrideFieldInfo = fieldInfo;

            uint currentKey = kvCurrent.Key;

            byte[] currentValue = kvCurrent.Value;

            //string currentKeyName = StringHasher.ResolveHash((int)currentKey) ?? $"{currentKey:X8}";
            string currentKeyName     = "";
            string currentValueString = BitConverter.ToString(currentValue).Replace("-", "");

            string r_currentKeyName;

            if (StringHasher.TryResolveHash((int)currentKey, out r_currentKeyName))
            {
                currentKeyName = r_currentKeyName;
            }

            if (kvNext.Value != null && kvNext.Value.Length > 0)
            {
                uint   nextKey   = kvNext.Key;
                byte[] nextValue = kvNext.Value;

                //string nextKeyName = StringHasher.ResolveHash((int) nextKey);
                string nextKeyName     = "";
                string nextValueString = BitConverter.ToString(nextValue).Replace("-", "");

                string r_nextKeyName;

                if (StringHasher.TryResolveHash((int)nextKey, out r_nextKeyName))
                {
                    nextKeyName = r_nextKeyName;
                }

                /*
                 * var textPrefix = "text_";
                 * var currentKeyGuessName = $"{textPrefix}{nextKeyName}";
                 * uint currentKeyGuessHash = FileFormats.Hashing.CRC32.Compute(currentKeyGuessName);
                 *
                 * if (currentKeyGuessHash == currentKey)
                 * {
                 *  // current key is text of next key
                 *
                 *  //Console.WriteLine($"{currentKeyGuessHash:X8} == {currentKey:X8}");
                 *
                 *  currentValueString = FieldHandling.Deserialize<string>(FieldType.String, currentValue);
                 * }
                 */

                FieldType r_currentFieldType;
                string    r_currentValueString;

                if (currentKeyName == "text_hidName")
                {
                    currentValueString = FieldHandling.Deserialize <string>(FieldType.String, currentValue);

                    Utility.Log("Exporting " + currentValueString);
                }
                else if (TypeGuesser.TryParse(currentValue, out r_currentFieldType, out r_currentValueString))
                {
                    if (r_currentFieldType == FieldType.String)
                    {
                        currentValueString = r_currentValueString;
                    }
                }

                uint  r_nextValueHash32 = 0;
                ulong r_nextValueHash64 = 0;
                ulong nextValueHash     = 0;

                if (uint.TryParse(nextValueString, NumberStyles.HexNumber, null, out r_nextValueHash32))
                {
                    nextValueHash = r_nextValueHash32;

                    //Console.WriteLine($"Parsing uint: {nextValueHash:X8}");
                }
                else if (ulong.TryParse(nextValueString, NumberStyles.HexNumber, null, out r_nextValueHash64))
                {
                    nextValueHash = r_nextValueHash64;

                    //Console.WriteLine($"Parsing ulong: {nextValueHash:X16}");
                }

                ulong[] hashValues = HashHandler.CollectHashes(currentValueString);

                var hashTypeIterator = 0;

                for (int b = 0; b < hashValues.Length; b++)
                {
                    ulong hash = hashValues[b];

                    //Console.WriteLine($"Iterating hash: {hash:X}");

                    if (hash > 0 && hash == nextValueHash)
                    {
                        hashTypeIterator = b;

                        //Console.WriteLine($"{hash:X} == {nextValueHash:X}");

                        break;
                    }
                }

                ulong resolvedHash = hashValues[hashTypeIterator];

                if (hashTypeIterator > 0 && resolvedHash == nextValueHash)
                {
                    // current value is text of next value
                    //string fieldName = nextKeyName ?? $"{nextValueHash:X8}";

                    if (string.IsNullOrEmpty(nextKeyName))
                    {
                        fieldInfo.key.type = "hash";
                        fieldInfo.key.name = $"{nextKey:X8}";
                    }
                    else
                    {
                        fieldInfo.key.type = "name";
                        fieldInfo.key.name = nextKeyName;
                    }

                    fieldInfo.value.type  = Convert.ToString((HashType)hashTypeIterator);
                    fieldInfo.value.value = currentValueString;

                    Console.WriteLine($"{fieldInfo.key.name} = {currentValueString}");

                    overrideFieldInfo = fieldInfo;

                    //Utility.Log($"{fieldName} = \"{currentValueString}\"");
                    //Utility.Log($"Found text value of field \"{fieldName}\": \"{currentValueString}\"");
                    //Utility.Log($"Element:\n\tcurrent:\n\t\tname: {currentKey:X8} -> {currentKeyName}\n\t\tvalue: {currentValueString} -> {resolvedHash:X8}\n\tnext:\n\t\tname: {nextKeyName} -> {nextKey:X8}\n\t\tvalue: {nextValueString}");

                    return(false);
                }
            }

            return(true);
        }
Exemple #15
0
        public TokenCollection ExtractTokens(Response response)
        {
            TokenCollection tokens = new TokenCollection();

            if (response.Headers.ContainsKey("Content-Type") &&
                response.Headers["Content-Type"].Count >= 1 &&
                response.Headers["Content-Type"][0].Contains("text/html"))
            {
                HtmlDocument doc = new HtmlDocument();
                doc.LoadHtml(response.Content);

                var nodes = doc.DocumentNode.SelectNodes("//input[@type=\"hidden\"]");

                if (nodes != null)
                {
                    foreach (HtmlNode node in nodes)
                    {
                        string value = node.GetAttributeValue("value", "");
                        if (value != "")
                        {
                            HtmlFormToken token = new HtmlFormToken(node.GetAttributeValue("name", "likely-csrf"), value, TypeGuesser.GuessTypes(value));
                            tokens.Add(token);
                        }
                    }
                }
            }
            return(tokens);
        }
Exemple #16
0
        public TokenCollection ExtractTokens(Request request)
        {
            TokenCollection tokens = new TokenCollection();

            if (request.Headers.ContainsKey("Content-Type") &&
                request.Headers["Content-Type"].Count >= 1 &&
                request.Headers["Content-Type"][0] == "application/x-www-form-urlencoded")
            {
                string[] pairs = request.Content.Split("&");
                foreach (string pair in pairs)
                {
                    if (pair.Length >= 3)
                    {
                        string[]      data  = pair.Split('=', 2);
                        HtmlFormToken token = new HtmlFormToken(HttpUtility.UrlDecode(data[0]), HttpUtility.UrlDecode(data[1]), TypeGuesser.GuessTypes(HttpUtility.UrlDecode(data[1])));
                        tokens.Add(token);
                    }
                }
            }
            return(tokens);
        }