Monobjc.Tools.Generators.NativeCodeGenerator.GenerateMainSource C# (CSharp) Method

GenerateMainSource() private method

private GenerateMainSource ( string mainSource, string mainImage, string>.IEnumerable assemblies, string>.IEnumerable configurations, string>.Dictionary machineConfig ) : void
mainSource string
mainImage string
assemblies string>.IEnumerable
configurations string>.IEnumerable
machineConfig string>.Dictionary
return void
        private void GenerateMainSource(string mainSource, string mainImage, IEnumerable<Dictionary<string, string>> assemblies, IEnumerable<Dictionary<string, string>> configurations, Dictionary<string, string> machineConfig)
        {
            using (StreamWriter sourceWriter = new StreamWriter(mainSource))
            {
                // Output header for the main source
                sourceWriter.WriteLine("// This source code was produced by the Monobjc Tools, DO NOT EDIT !!!");
                sourceWriter.WriteLine();
                sourceWriter.WriteLine("#include <stdlib.h>");
                if (this.Compress) {
                    sourceWriter.WriteLine("#include <zlib.h>");
                }
                sourceWriter.WriteLine("#include <mono/metadata/assembly.h>");
                sourceWriter.WriteLine("#include \"monobjc.h\"");
                sourceWriter.WriteLine();
                sourceWriter.WriteLine("#ifdef RECEIGEN");
                sourceWriter.WriteLine("#define RUNNER mono_main");
                sourceWriter.WriteLine("#include \"receigen.h\"");
                sourceWriter.WriteLine("#endif");
                sourceWriter.WriteLine();

                // Output the custom structure
                sourceWriter.WriteLine("// Structure for MonoBundledAssemblyExt");
                sourceWriter.WriteLine("typedef struct {");
                sourceWriter.WriteLine("\tconst char *name;");
                sourceWriter.WriteLine("\tconst unsigned char *data;");
                sourceWriter.WriteLine("\tconst unsigned int size;");
                sourceWriter.WriteLine("\tconst unsigned char *zip_data;");
                sourceWriter.WriteLine("\tconst unsigned int zip_size;");
                sourceWriter.WriteLine("} MonoBundledAssemblyExt;");
                sourceWriter.WriteLine();

                // Output the symbols for the assemblies
                this.Logger.LogInfo("Output symbols for assemblies (" + assemblies.Count() + ")");
                sourceWriter.WriteLine("// Symbols for assemblies");
                foreach (Dictionary<string, string> dictionary in assemblies)
                {
                    sourceWriter.WriteLine("extern const unsigned char {0}[];", dictionary[KEY_SYMBOL]);
                }
                sourceWriter.WriteLine();

                // Output the symbols for the configuration
                this.Logger.LogInfo("Output symbols for configuration (" + configurations.Count() + ")");
                sourceWriter.WriteLine("// Symbols for configurations");
                foreach (Dictionary<string, string> dictionary in configurations)
                {
                    sourceWriter.WriteLine("extern const char {0}[];", dictionary[KEY_SYMBOL]);
                }
                sourceWriter.WriteLine();

                // Output the symbol for the machine configuration
                sourceWriter.WriteLine("// Symbol for machine configuration");
                this.Logger.LogInfo("Output symbol for machine configuration");
                if (machineConfig != null)
                {
                    sourceWriter.WriteLine("extern const char {0}[];", machineConfig[KEY_SYMBOL]);
                }
                sourceWriter.WriteLine();

                // Output the bundle for each assembly
                this.Logger.LogInfo("Output bundle for assemblies (" + assemblies.Count() + ")");
                sourceWriter.WriteLine("// Bundle for assemblies");
                foreach (Dictionary<string, string> dictionary in assemblies)
                {
                    if (this.Compress) {
                        sourceWriter.WriteLine("static MonoBundledAssemblyExt bundle_{0} = {{ \"{1}\", NULL, {2}, {0}, {3} }};", dictionary[KEY_SYMBOL], dictionary[KEY_NAME], dictionary[KEY_INPUT_SIZE], dictionary[KEY_OUTPUT_SIZE]);
                    } else {
                        sourceWriter.WriteLine("static MonoBundledAssemblyExt bundle_{0} = {{ \"{1}\", {0}, {2}, NULL, 0 }};", dictionary[KEY_SYMBOL], dictionary[KEY_NAME], dictionary[KEY_INPUT_SIZE]);
                    }
                }
                sourceWriter.WriteLine();

                // Output the inflate function
                if (this.Compress) {
                    sourceWriter.WriteLine("int bundle_inflate(MonoBundledAssemblyExt *bundle) {");
                    sourceWriter.WriteLine("\tif (!bundle->zip_data) {");
                    sourceWriter.WriteLine("\t\treturn 0;");
                    sourceWriter.WriteLine("\t}");
                    sourceWriter.WriteLine();
                    sourceWriter.WriteLine("\tbundle->data = (const unsigned char *) malloc(bundle->size);");
                    sourceWriter.WriteLine();
                    sourceWriter.WriteLine("\tint ret;");
                    sourceWriter.WriteLine("\tz_stream strm = { 0 };");
                    sourceWriter.WriteLine("\tret = inflateInit(&strm);");
                    sourceWriter.WriteLine("\tif (ret != Z_OK) {");
                    sourceWriter.WriteLine("\t\treturn ret;");
                    sourceWriter.WriteLine("\t}");
                    sourceWriter.WriteLine();
                    sourceWriter.WriteLine("\tstrm.next_in = (Bytef *) bundle->zip_data;");
                    sourceWriter.WriteLine("\tstrm.avail_in = (uInt) bundle->zip_size;");
                    sourceWriter.WriteLine();
                    sourceWriter.WriteLine("\twhile(1) {");
                    sourceWriter.WriteLine("\t\tstrm.next_out = (Bytef *) bundle->data;");
                    sourceWriter.WriteLine("\t\tstrm.avail_out = (uInt) bundle->size;");
                    sourceWriter.WriteLine("\t\tret = inflate(&strm, Z_NO_FLUSH);");
                    sourceWriter.WriteLine("\t\tif (ret == Z_STREAM_END) {");
                    sourceWriter.WriteLine("\t\t\tbreak;");
                    sourceWriter.WriteLine("\t\t}");
                    sourceWriter.WriteLine("\t\tif (ret != Z_OK) {");
                    sourceWriter.WriteLine("\t\t\treturn ret;");
                    sourceWriter.WriteLine("\t\t}");
                    sourceWriter.WriteLine("\t}");
                    sourceWriter.WriteLine();
                    sourceWriter.WriteLine("\tret = inflateEnd(&strm);");
                    sourceWriter.WriteLine("\tif (ret != Z_OK) {");
                    sourceWriter.WriteLine("\t\treturn ret;");
                    sourceWriter.WriteLine("\t}");
                    sourceWriter.WriteLine();
                    sourceWriter.WriteLine("\treturn 0;");
                    sourceWriter.WriteLine("}");
                    sourceWriter.WriteLine();
                }

                // Output the main image
                sourceWriter.WriteLine("static char *image_name = \"{0}\";", mainImage);
                sourceWriter.WriteLine();

                // Output the main method
                sourceWriter.WriteLine("int main(int argc, char* argv[]) {");
                sourceWriter.WriteLine("\tint i;");
                sourceWriter.WriteLine();

                int i = 0;
                sourceWriter.WriteLine("\tMonoBundledAssemblyExt *bundled[{0}];", assemblies.Count() + 1);
                foreach (Dictionary<string, string> dictionary in assemblies)
                {
                    if (this.Compress) {
                        sourceWriter.WriteLine("\tbundle_inflate(&bundle_{1});", i, dictionary[KEY_SYMBOL]);
                    }
                    sourceWriter.WriteLine("\tbundled[{0}] = &bundle_{1};", i, dictionary[KEY_SYMBOL]);
                    i++;
                }
                sourceWriter.WriteLine("\tbundled[{0}] = NULL;", i);
                sourceWriter.WriteLine("\t");

                sourceWriter.WriteLine("\t// Disabled shared area");
                sourceWriter.WriteLine("\tsetenv(\"MONO_DISABLE_SHARED_AREA\", \"1\", 1);");
                sourceWriter.WriteLine("\t");

                sourceWriter.WriteLine("\t// Shift the arguments to include the image name");
                sourceWriter.WriteLine("\tchar **newargs = (char **) malloc (sizeof(char *) * (argc + 2));");
                sourceWriter.WriteLine("\tnewargs [0] = argv[0];");
                sourceWriter.WriteLine("\tnewargs [1] = image_name;");
                sourceWriter.WriteLine("\tfor(i = 1; i < argc; i++) {");
                sourceWriter.WriteLine("\t\tnewargs[i+1] = argv [i];");
                sourceWriter.WriteLine("\t}");
                sourceWriter.WriteLine("\tnewargs[++i] = NULL;");
                sourceWriter.WriteLine();

                sourceWriter.WriteLine("\t// Registers the configurations and the assemblies");
                if (machineConfig != null)
                {
                    sourceWriter.WriteLine("\tmono_register_machine_config({0});", machineConfig[KEY_SYMBOL]);
                }
                foreach (Dictionary<string, string> dictionary in configurations)
                {
                    sourceWriter.WriteLine("\tmono_register_config_for_assembly(\"{0}\", {1});", dictionary[KEY_ASSEMBLY], dictionary[KEY_SYMBOL]);
                }
                sourceWriter.WriteLine("\tmono_register_bundled_assemblies((const MonoBundledAssembly **) bundled);");
                sourceWriter.WriteLine();

                sourceWriter.WriteLine("\t// Invoke the Mono runtime");
                sourceWriter.WriteLine("#ifdef RECEIGEN");
                sourceWriter.WriteLine("\treturn CheckReceiptAndRun(argc + 1, newargs);");
                sourceWriter.WriteLine("#else");
                sourceWriter.WriteLine("\treturn mono_main(argc + 1, newargs);");
                sourceWriter.WriteLine("#endif");
                sourceWriter.WriteLine("}");
            }
        }