Exemple #1
0
        protected void AddTextBlock(TextBlock textBlock)
        {
            //string text = "";
            //for (int i = 0; i < (textBlock.indent); i++)
            //    text += "    ";

            foreach (var line in textBlock.lines)
                lines.Add(() => line());
        }
        public NativeConstantsDeclaration(IEnumerable<TypeDesc> types, TextBlock container, AccessModifierType accessModifier)
            : base(new TypeDesc("void"), container, accessModifier)
        {
            var constants = types.SelectMany(x => x.Fields).OrderBy(x => x.Name).Select(x => new ConstDeclaration(x, this, AccessModifier)).ToList();

            WriteBaseLine(() => "{");
            constants.ForEach(AddTextBlock);
            WriteBaseLine(() => "}");
        }
        protected BaseTypeDeclaration(TypeDesc type, TextBlock container, AccessModifierType accessModifier)
            : base(container, 1)
        {
            Type = type;
            AccessModifier = accessModifier;

            foreach (string attribute in Attributes)
                WriteBaseLine(() => attribute);
            WriteBaseLine(() => AccessModifier + " " + DeclarationType + " " + TypeName + (BaseTypes.Any() ? " : " + string.Join(", ", BaseTypes) : string.Empty));
        }
        public NativeMethodsDeclaration(IEnumerable<TypeDesc> types, TextBlock container, AccessModifierType accessModifier)
            : base(new TypeDesc("void"), container, accessModifier)
        {
            var methods = types.SelectMany(x => x.Methods).Where(x => x.Dll != null).OrderBy(x => x.Name).Select(x => new MethodDeclaration(x, this, AccessModifier)).ToArray();

            WriteBaseLine(() => "{");
            for (int i = 0; i < methods.Length; i++)
            {
                AddTextBlock(methods[i]);
                if (i != (methods.Length - 1))
                    WriteLine();
            }
            WriteBaseLine(() => "}");
        }
        public MethodDeclaration(MethodDesc method, BaseTypeDeclaration container, AccessModifierType accessModifier, bool isNew = false, TextBlock code = null, string nameOverride = null)
            : base(container, 0)
        {
            string additionalModifier = (accessModifier == AccessModifierType.Empty ? "" : " ") + ((method.Dll != null) ? "static extern " : "") + "unsafe " + (isNew ? "new " : "");

            if (code == null)
            {
                if (method.Dll != null)
                    WriteLine(() => "[DllImport(\"" + method.Dll + "\", EntryPoint = \"" + method.EntryPoint + "\", CallingConvention = CallingConvention." + method.Convention.ToString() + ", CharSet = CharSet.Unicode, SetLastError = true)]");
                else
                    WriteLine(() => "[PreserveSig]");
            }

            WriteLine(() => accessModifier + additionalModifier + GetReturnValue(method) + " " + ((nameOverride == null) ? method.Name : nameOverride) + "(" + GetParameters(method) + ")" + ((code == null) ? ";" : ""));
            if (code != null)
                AddTextBlock(code);
        }
        public EnumDeclaration(TypeDesc type, TextBlock container, AccessModifierType accessModifier)
            : base(type, container, accessModifier)
        {
            if (type.AutoGeneratedName)
                throw new Exception("Name of the enum should be specified");

            int counter = 0;
            var fields = Type.Fields.ToArray();

            WriteBaseLine(() => "{");
            foreach (var field in fields)
            {
                counter++;
                int currentIndex = counter;
                WriteLine(() => field.Name + (field.HasValue ? (" = " + field.Value.ToString()) : string.Empty) + ((currentIndex < fields.Length) ? "," : string.Empty));
            }
            WriteBaseLine(() => "}");
        }
        public InterfaceDeclaration(TypeDesc type, TextBlock container, AccessModifierType accessModifier)
            : base(type, container, accessModifier)
        {
            isIUnknown = type.BaseTypes.Any(x => x.Name == "IUnknown");
            isUserImplemented = IsUserImplemented(type);
            ignoreIdentifier = IsWithoutIdentifier(type);

            var methods = type.AllMethods.Select(x => new MethodDeclaration(x, this, AccessModifierType.Empty, IsInherited(x, type))).ToArray();

            WriteBaseLine(() => "{");
            for (int i = 0; i < methods.Length; i++)
            {
                AddTextBlock(methods[i]);
                if (i != (methods.Length - 1))
                    WriteLine();
            }
            WriteBaseLine(() => "}");
        }
        private StructDeclaration(TypeDesc type, TextBlock container, AccessModifierType accessModifier, bool root)
            : base(type, container, accessModifier)
        {
            if (type.BaseTypes.Any())
                throw new Exception("Base types are not expected for struct");
            if (type.Methods.Any())
                throw new Exception("Methods are not expected for struct");

            TypeDesc bitField = CheckBitField(Type);

            var fields = type.Fields.ToArray();

            WriteBaseLine(() => "{");

            if (bitField == null)
            {
                if (root)
                {
                    Action<TypeDesc, List<TypeDesc>, List<ParameterDesc>> getNestedTypes = null;
                    getNestedTypes = (currentType, types, parameters) =>
                    {
                        if (!types.Any(x => x.Name == currentType.Name))
                        {
                            types.Add(currentType);
                            parameters.AddRange(currentType.Fields);
                            if (CheckBitField(currentType) == null)
                                currentType.Fields.ToList().ForEach(x => getNestedTypes(x.Type, types, parameters));
                        }
                    };

                    List<TypeDesc> nestedTypeDescList = new List<TypeDesc>();
                    List<ParameterDesc> parameterDescList = new List<ParameterDesc>();
                    getNestedTypes(type, nestedTypeDescList, parameterDescList);

                    List<BaseTypeDeclaration> nestedTypes = new List<BaseTypeDeclaration>();

                    nestedTypes.AddRange(nestedTypeDescList.Where(x => x.AutoGeneratedName).Select(x => (BaseTypeDeclaration)new StructDeclaration(x, this, accessModifier, false)));
                    nestedTypes.AddRange(parameterDescList.Where(x => x.ArraySizes.Any()).Select(x => (BaseTypeDeclaration)new ArrayWrapperDeclararation(x, this, accessModifier)).Where(x => !nestedTypes.Any(y => y.TypeName == x.TypeName)));

                    nestedTypes.ForEach(x =>
                    {
                        AddTextBlock(x);
                        WriteLine();
                    });
                }

                Action<List<ParameterDesc>> processNamelessField = null;
                processNamelessField = list =>
                {
                    ParameterDesc currentParameter = list[list.Count - 1];
                    if (currentParameter.AutoGeneratedName)
                    {
                        foreach (var item in currentParameter.Type.Fields.ToArray())
                            processNamelessField(list.Union(new ParameterDesc[] { item }).ToList());
                    }
                    else
                    {
                        if (!currentParameter.Hidden)
                        {
                            string propertyType = currentParameter.TypeDeclaration;
                            if (currentParameter.ArraySizes.Any() && !currentParameter.SpecialFlag)
                                propertyType = new ArrayWrapperDeclararation(currentParameter, this, accessModifier).TypeName;

                            WriteLine();
                            WriteLine(() => AccessModifier + " " + propertyType + " " + currentParameter.Name);
                            WriteLine(() => "{");
                            WriteLine(() => "    get");
                            WriteLine(() => "    {");
                            WriteLine(() => "        return " + string.Join(".", list.Select(x => x.Name)) + ";");
                            WriteLine(() => "    }");
                            WriteLine(() => "    set");
                            WriteLine(() => "    {");
                            WriteLine(() => "        " + string.Join(".", list.Select(x => x.Name)) + " = value;");
                            WriteLine(() => "    }");
                            WriteLine(() => "}");
                        }
                    }
                };

                for (int i = 0; i < fields.Length; i++)
                {
                    ParameterDesc field = fields[i];

                    if (type.Kind == TypeKind.Union)
                        WriteLine(() => "[FieldOffset(0)]");

                    AddTextBlock(new FieldDeclaration(field, this, AccessModifier));
                }

                foreach (var field in type.Fields.Where(x => x.AutoGeneratedName))
                    processNamelessField(new ParameterDesc[] { field }.ToList());
            }
            else
            {
                AddTextBlock(new FieldDeclaration(bitField, "__bit_field_value", this, AccessModifierType.Private));

                int bitFieldOffset = 0;
                for (int i = 0; i < fields.Length; i++)
                {
                    ParameterDesc field = fields[i];
                    int bitFieldSize = field.ArraySizes.Single();
                    int bitFieldMask = 0;
                    for (int j = 0; j < bitFieldSize; j++)
                        bitFieldMask |= (1 << j);

                    WriteLine();
                    WriteLine(() => AccessModifier + " " + bitField.Name + " " + field.Name);
                    WriteLine(() => "{");
                    WriteLine(() => "    get");
                    WriteLine(() => "    {");
                    WriteLine(() => "        return (" + bitField.Name + ")((__bit_field_value >> " + bitFieldOffset.ToString() + ") & " + bitFieldMask.ToString() + ");");
                    WriteLine(() => "    }");
                    WriteLine(() => "    set");
                    WriteLine(() => "    {");
                    WriteLine(() => "        __bit_field_value = (" + bitField.Name + ")((value & " + bitFieldMask.ToString() + ") << " + bitFieldOffset.ToString() + ");");
                    WriteLine(() => "    }");
                    WriteLine(() => "}");

                    bitFieldOffset += bitFieldSize;
                }
            }

            WriteLine();
            WriteLine(() => AccessModifier + " unsafe static int GetSize()");
            WriteLine(() => "{");
            WriteLine(() => "    return Marshal.SizeOf(typeof(" + TypeName + "));");
            WriteLine(() => "}");

            if ((TypeName == "BOOL") || (TypeName == "BOOLEAN"))
            {
                WriteLine();
                WriteLine(() => "public static unsafe implicit operator bool(" + TypeName + " value)");
                WriteLine(() => "{");
                WriteLine(() => "    return (value.Value != 0);");
                WriteLine(() => "}");
                WriteLine();
                WriteLine(() => "public static unsafe implicit operator " + TypeName + "(bool value)");
                WriteLine(() => "{");
                WriteLine(() => "    return new " + TypeName + " { Value = (byte)(value ? 1 : 0) };");
                WriteLine(() => "}");
            }

            WriteLine();
            WriteLine(() => "public unsafe override bool Equals(object obj)");
            WriteLine(() => "{");
            WriteLine(() => "    if (!(obj is " + TypeName + "))");
            WriteLine(() => "        return false;");
            WriteLine(() => "    fixed (" + TypeName + "* address = &this)");
            WriteLine(() => "    {");
            WriteLine(() => "        " + TypeName + " other = (" + TypeName + ")obj;");
            WriteLine(() => "        IntPtr size = new IntPtr(GetSize());");
            WriteLine(() => "        IntPtr equalBytes = NativeMethods.RtlCompareMemory(address, &other, size);");
            WriteLine(() => "        return size == equalBytes;");
            WriteLine(() => "    }");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe override int GetHashCode()");
            WriteLine(() => "{");
            WriteLine(() => "    int result = 0;");
            WriteLine(() => "    int size = GetSize();");
            WriteLine(() => "    fixed (" + TypeName + "* address = &this)");
            WriteLine(() => "    {");
            WriteLine(() => "        byte* byteAddress = (byte*)address;");
            WriteLine(() => "        for (int i = 0; i < size; i++)");
            WriteLine(() => "            result ^= byteAddress[i] << i;");
            WriteLine(() => "    }");
            WriteLine(() => "    return result;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe static bool operator ==(" + TypeName + " left, " + TypeName + " right)");
            WriteLine(() => "{");
            WriteLine(() => "    IntPtr size = new IntPtr(GetSize());");
            WriteLine(() => "    IntPtr equalBytes = NativeMethods.RtlCompareMemory(&left, &right, size);");
            WriteLine(() => "    return size == equalBytes;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe static bool operator !=(" + TypeName + " left, " + TypeName + " right)");
            WriteLine(() => "{");
            WriteLine(() => "    IntPtr size = new IntPtr(GetSize());");
            WriteLine(() => "    IntPtr equalBytes = NativeMethods.RtlCompareMemory(&left, &right, size);");
            WriteLine(() => "    return size != equalBytes;");
            WriteLine(() => "}");

            WriteBaseLine(() => "}");
        }
 public StructDeclaration(TypeDesc type, TextBlock container, AccessModifierType accessModifier)
     : this(type, container, accessModifier, true)
 {
 }
 public DelegateDeclaration(TypeDesc type, TextBlock container, AccessModifierType accessModifier)
     : base(new TypeDesc("void"), container, accessModifier)
 {
     this.method = type.Methods.Single(x => x.Name == type.Name);
     prefix = "_";
 }
 public DelegateDeclaration(MethodDesc method, TextBlock container, AccessModifierType accessModifier)
     : base(new TypeDesc("void"), container, accessModifier)
 {
     this.method = method;
 }
Exemple #12
0
 protected TextBlock(TextBlock container, int indent)
 {
     this.indent = container.indent + indent;
 }
        public DelegateWrapperDeclaration(TypeDesc type, TextBlock container, AccessModifierType accessModifier)
            : base(type, container, accessModifier)
        {
            DelegateDeclaration delegateDeclaration = new DelegateDeclaration(type, container, accessModifier);

            WriteBaseLine(() => "{");
            WriteLine(() => "private static readonly ConcurrentDictionary<IntPtr, " + delegateDeclaration.DelegateTypeName + "> references = new ConcurrentDictionary<IntPtr, " + delegateDeclaration.DelegateTypeName + ">();");
            WriteLine();
            WriteLine(() => "private readonly IntPtr reference;");
            WriteLine();
            WriteLine(() => AccessModifier + " unsafe " + TypeName + "(" + delegateDeclaration.DelegateTypeName + " value)");
            WriteLine(() => "    : this()");
            WriteLine(() => "{");
            WriteLine(() => "    IntPtr reference = IntPtr.Zero;");
            WriteLine(() => "    if (value != null)");
            WriteLine(() => "    {");
            WriteLine(() => "        value = new " + delegateDeclaration.DelegateTypeName + "(value);");
            WriteLine(() => "        reference = Marshal.GetFunctionPointerForDelegate(value);");
            WriteLine(() => "        references.TryAdd(reference, value);");
            WriteLine(() => "    }");
            WriteLine(() => "    this.reference = reference;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => AccessModifier + " unsafe " + TypeName + "(IntPtr value)");
            WriteLine(() => "{");
            WriteLine(() => "    reference = value;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => AccessModifier + " unsafe " + TypeName + "(void* value)");
            WriteLine(() => "{");
            WriteLine(() => "    reference = new IntPtr(value);");
            WriteLine(() => "}");

            WriteLine();
            WriteLine(() => "public static unsafe implicit operator IntPtr(" + TypeName + " value)");
            WriteLine(() => "{");
            WriteLine(() => "    return value.reference;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public static unsafe implicit operator void*(" + TypeName + " value)");
            WriteLine(() => "{");
            WriteLine(() => "    return (void*)value.reference;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public static unsafe implicit operator " + TypeName + "(IntPtr value)");
            WriteLine(() => "{");
            WriteLine(() => "    return new " + TypeName + "(value);");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public static unsafe implicit operator " + TypeName + "(void* value)");
            WriteLine(() => "{");
            WriteLine(() => "    return new " + TypeName + "(value);");
            WriteLine(() => "}");

            WriteLine();
            WriteLine(() => "public static unsafe implicit operator " + TypeName + "(" + delegateDeclaration.DelegateTypeName + " value)");
            WriteLine(() => "{");
            WriteLine(() => "    return new " + TypeName + "(value);");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public static unsafe implicit operator " + delegateDeclaration.DelegateTypeName + "(" + TypeName + " value)");
            WriteLine(() => "{");
            WriteLine(() => "    IntPtr reference = value.reference;");
            WriteLine(() => "    return (reference == IntPtr.Zero) ? null : (" + delegateDeclaration.DelegateTypeName + ")Marshal.GetDelegateForFunctionPointer(reference, typeof(" + delegateDeclaration.DelegateTypeName + "));");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public void Dispose()");
            WriteLine(() => "{");
            WriteLine(() => "    " + delegateDeclaration.DelegateTypeName + " removedReference;");
            WriteLine(() => "    references.TryRemove(reference, out removedReference);");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => AccessModifier + " void RemoveAllReferences()");
            WriteLine(() => "{");
            WriteLine(() => "    references.Clear();");
            WriteLine(() => "}");

            WriteLine();
            WriteLine(() => "public unsafe override bool Equals(object obj)");
            WriteLine(() => "{");
            WriteLine(() => "    " + TypeName + " other = (" + TypeName + ")obj;");
            WriteLine(() => "    return reference == other.reference;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe override int GetHashCode()");
            WriteLine(() => "{");
            WriteLine(() => "    return reference.GetHashCode();");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe static bool operator ==(" + TypeName + " left, " + TypeName + " right)");
            WriteLine(() => "{");
            WriteLine(() => "    return left.reference == right.reference;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe static bool operator !=(" + TypeName + " left, " + TypeName + " right)");
            WriteLine(() => "{");
            WriteLine(() => "    return left.reference != right.reference;");
            WriteLine(() => "}");

            WriteLine();

            MethodDesc method = type.AllMethods.Single();

            AddTextBlock(new MethodDeclaration(method, this, AccessModifier, false, new DelegateCaller(method, this), "Invoke"));

            WriteBaseLine(() => "}");
        }
        public InterfaceWrapperDeclaration(TypeDesc type, TextBlock container, AccessModifierType accessModifier)
            : base(type, container, accessModifier)
        {
            isIUnknown = type.BaseTypes.Any(x => x.Name == "IUnknown");
            isUserImplemented = InterfaceDeclaration.IsUserImplemented(type);
            ignoreIdentifier = InterfaceDeclaration.IsWithoutIdentifier(type);

            var methods = type.AllMethods.ToArray();

            vtbl = new InterfaceVtblDeclaration(type, this);

            WriteBaseLine(() => "{");
            AddTextBlock(vtbl);
            WriteLine();

            for(int i = 0; i < methods.Length; i++)
            {
                int index = i;
                MethodDesc method = type.AllMethods.ToArray()[i];
                string parameters = vtbl.TypeName + "** @this";
                if (MethodDeclaration.GetParameterNames(method).Any())
                    parameters += ", " + MethodDeclaration.GetParameters(method);
                WriteLine(() => "private unsafe delegate " + MethodDeclaration.GetReturnValue(method) + " " + GetDelegateName(index) + "(" + parameters + ");");
            }
            WriteLine();

            WriteLine(() => "private readonly void* reference;");
            if (!ignoreIdentifier)
            {
                WriteLine(() => "private static readonly Guid iid = new Guid(\"" + type.CLSID.ToString() + "\");");
                WriteLine();
                WriteLine(() => AccessModifier + " static unsafe Guid IID");
                WriteLine(() => "{");
                WriteLine(() => "    get");
                WriteLine(() => "    {");
                WriteLine(() => "        return iid;");
                WriteLine(() => "    }");
                WriteLine(() => "}");
            }

            for (int i = 0; i < methods.Length; i++)
            {
                WriteLine();
                bool isNew = ((methods[i].Name == "GetType" || methods[i].Name == "ToString") && !methods[i].Parameters.Any());
                AddTextBlock(new MethodDeclaration(methods[i], this, AccessModifierType.Public, isNew, new DelegateCaller(i, methods[i], this)));
            }

            if (isIUnknown)
            {
                WriteLine();
                WriteLine(() => "void IDisposable.Dispose()");
                WriteLine(() => "{");
                WriteLine(() => "    while ((reference != null) && (Release() > 0))");
                WriteLine(() => "    {");
                WriteLine(() => "    }");
                WriteLine(() => "}");
            }

            WriteLine();
            WriteLine(() => AccessModifier + " unsafe " + TypeName + "(IntPtr value)");
            WriteLine(() => "{");
            WriteLine(() => "    reference = (void*)value;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => AccessModifier + " unsafe " + TypeName + "(void* value)");
            WriteLine(() => "{");
            WriteLine(() => "    reference = value;");
            WriteLine(() => "}");
            foreach (string baseTypeRefName in type.BaseTypes.Where(x => !InterfaceDeclaration.IsSpecialInterface(x)).Select(x => x.Name))
            {
                WriteLine();
                WriteLine(() => "public static unsafe explicit operator " + TypeName + "(" + baseTypeRefName + " value)");
                WriteLine(() => "{");
                WriteLine(() => "    return new " + TypeName + "(*((void**)(&value)));");
                WriteLine(() => "}");
                WriteLine();
                WriteLine(() => "public static unsafe implicit operator " + baseTypeRefName + "(" + TypeName + " value)");
                WriteLine(() => "{");
                WriteLine(() => "    return new " + baseTypeRefName + "(value.reference);");
                WriteLine(() => "}");
            }

            WriteLine();
            WriteLine(() => "public static unsafe implicit operator IntPtr(" + TypeName + " value)");
            WriteLine(() => "{");
            WriteLine(() => "    return new IntPtr(value.reference);");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public static unsafe implicit operator void*(" + TypeName + " value)");
            WriteLine(() => "{");
            WriteLine(() => "    return value.reference;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public static unsafe implicit operator " + TypeName + "(IntPtr value)");
            WriteLine(() => "{");
            WriteLine(() => "    return new " + TypeName + "(value);");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public static unsafe implicit operator " + TypeName + "(void* value)");
            WriteLine(() => "{");
            WriteLine(() => "    return new " + TypeName + "(value);");
            WriteLine(() => "}");

            WriteLine();
            WriteLine(() => "public unsafe override bool Equals(object obj)");
            WriteLine(() => "{");
            WriteLine(() => "    " + TypeName + " other = (" + TypeName + ")obj;");
            WriteLine(() => "    return reference == other.reference;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe override int GetHashCode()");
            WriteLine(() => "{");
            WriteLine(() => "    return new IntPtr(reference).GetHashCode();");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe static bool operator ==(" + TypeName + " left, " + TypeName + " right)");
            WriteLine(() => "{");
            WriteLine(() => "    return left.reference == right.reference;");
            WriteLine(() => "}");
            WriteLine();
            WriteLine(() => "public unsafe static bool operator !=(" + TypeName + " left, " + TypeName + " right)");
            WriteLine(() => "{");
            WriteLine(() => "    return left.reference != right.reference;");
            WriteLine(() => "}");

            WriteBaseLine(() => "}");
        }