BattleNet.AdvancedCheckRevision.BuildFileHasher C# (CSharp) Method

BuildFileHasher() protected static method

protected static BuildFileHasher ( IEnumerable ops ) : FileHasher
ops IEnumerable
return FileHasher
        protected static FileHasher BuildFileHasher(IEnumerable<FormulaOp> ops)
        {
            Type uint_t = typeof(uint).MakeByRefType();
            DynamicMethod method = new DynamicMethod("HashFile", typeof(void),
                  new Type[] { uint_t, uint_t, uint_t, uint_t, typeof(byte[]) });
            MethodInfo touint32 = typeof(BitConverter).GetMethod("ToUInt32");

            ILGenerator gen = method.GetILGenerator();

            Label start = gen.DefineLabel();
            LocalBuilder index = gen.DeclareLocal(typeof(int));
            LocalBuilder len = gen.DeclareLocal(typeof(int));

            // initialize the loop counter
            gen.Emit(OpCodes.Ldc_I4_0);
            gen.Emit(OpCodes.Stloc, index);

            // load the length of the array into a local
            gen.Emit(OpCodes.Ldarg, (short)4);
            gen.Emit(OpCodes.Ldlen);
            gen.Emit(OpCodes.Conv_I4);
            gen.Emit(OpCodes.Stloc, len);

            // start of loop across the file
            gen.MarkLabel(start);

            // load the value of arg4 at index into the address of arg3
            gen.Emit(OpCodes.Ldarg_3);
            gen.Emit(OpCodes.Ldarg_S, (byte)4);
            gen.Emit(OpCodes.Ldloc, index);
            gen.EmitCall(OpCodes.Call, touint32, null);
            gen.Emit(OpCodes.Stind_I4);

            // for each op in the formula...
            foreach (var op in ops)
            {
                // load the result address
                gen.Emit(Ldargs[op.Result]);

                // load the first value
                gen.Emit(Ldargs[op.Variable1]);
                gen.Emit(OpCodes.Ldind_U4);

                // load the second value
                gen.Emit(Ldargs[op.Variable2]);
                gen.Emit(OpCodes.Ldind_U4);

                // execute the operator
                gen.Emit(Operators[op.Operation]);

                // store the result in the result address
                gen.Emit(OpCodes.Stind_I4);
            }

            // increment the loop counter
            gen.Emit(OpCodes.Ldloc, index);
            gen.Emit(OpCodes.Ldc_I4_4);
            gen.Emit(OpCodes.Add);
            gen.Emit(OpCodes.Stloc, index);

            // jump back to the top of the label if the loop counter is less arg4's length
            gen.Emit(OpCodes.Ldloc, index);
            gen.Emit(OpCodes.Ldloc, len);
            gen.Emit(OpCodes.Blt, start);
            gen.Emit(OpCodes.Ret);

            FileHasher del = (FileHasher)method.CreateDelegate(typeof(FileHasher));
            return del;
        }