Пример #1
0
 private void LoadTable()
 {
     if (table != null)
         return;
     var raw = Load();
     table = new Table(new MemoryStream(raw));
 }
Пример #2
0
 public void LoadTableTestFull()
 {
     var resources = new Table(new MemoryStream(TestResource.android_jar_resources));
     var index = resources.Strings.IndexOf("name", -1);
     var pkg = resources.Packages[0];
     var index2 = pkg.KeyStrings.IndexOf("name", -1);
 }
Пример #3
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public TableEntryNode(int entryIndex, Table.TypeSpec typeSpec, Table.Entry entry)
 {
     this.entryIndex = entryIndex;
     this.typeSpec = typeSpec;
     this.entry = entry;
     Text = string.Format("[{0:X4}] {1}", entryIndex, entry.Key);
 }
Пример #4
0
 /// <summary>
 /// Creation ctor
 /// </summary>
 internal Package(Table table, int id, string name)
     : base(ChunkTypes.RES_TABLE_PACKAGE_TYPE)
 {
     this.table = table;
     this.id = id;
     this.name = name;
     keyStrings = new StringPool();
     typeStrings = new StringPool();
 }
Пример #5
0
        /// <summary>
        /// Default ctor
        /// </summary>
        internal DescriptorProviderSet(AttrsXmlParser parser, LayoutXmlParser layoutParser, Table resources)
        {
            this.parser = parser;
            this.layoutParser = layoutParser;

            if (resources != null)
            {
                var pkg = resources.Packages.FirstOrDefault();
                var typeSpec = (pkg != null) ? pkg.TypeSpecs.FirstOrDefault(x => x.Name == "attr") : null;
                parser.AttrTypeSpec = typeSpec;
            }
        }
Пример #6
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public AssemblyCompiler(CompilationMode mode, List<AssemblyDefinition> assemblies, List<AssemblyDefinition> references, Table resources, NameConverter nameConverter, bool generateDebugInfo, AssemblyClassLoader assemblyClassLoader,
     HashSet<string> rootClassNames, XModule module)
 {
     this.mode = mode;
     this.assemblies = assemblies;
     this.references = references;
     this.resources = resources;
     this.generateDebugInfo = generateDebugInfo;
     this.assemblyClassLoader = assemblyClassLoader;
     this.rootClassNames = rootClassNames;
     this.module = module;
     targetPackage = new Target.Dex.DexTargetPackage(nameConverter, this);
 }
Пример #7
0
            /// <summary>
            /// Default ctor
            /// </summary>
            internal Package(Table table, ResReader reader)
                : base(reader, ChunkTypes.RES_TABLE_PACKAGE_TYPE)
            {
                this.table = table;

                id = reader.ReadInt32();
                name = reader.ReadFixedLenghtUnicodeString(128);
                var typeStringsOffset = reader.ReadInt32();
                var lastPublicType = reader.ReadInt32();
                var keyStringsOffset = reader.ReadInt32();
                var lastPublicKey = reader.ReadInt32();

                // Record offset
                var dataOffset = reader.Position;

                // Data
                typeStrings = new StringPool(reader);
                keyStrings = new StringPool(reader);

                TypeSpec currentTypeSpec = null;
                while (reader.Position - dataOffset < DataSize)
                {
                    var chunkType = reader.PeekChunkType();
                    if (chunkType == ChunkTypes.RES_TABLE_TYPE_SPEC_TYPE)
                    {
                        currentTypeSpec = Read(reader, () => new TypeSpec(this, reader));
                        typeSpecs.Add(currentTypeSpec);
                    }
                    else if (chunkType == ChunkTypes.RES_TABLE_TYPE_TYPE)
                    {
                        if (currentTypeSpec == null)
                        {
                            throw new IOException("Invalid chunk sequence: content read before typeSpec.");
                        }
                        var parent = currentTypeSpec;
                        var type = Read(reader, () => new Type(parent, reader));
                        currentTypeSpec.Add(type);
                    }
                    else
                    {
                        throw new IOException("Unexpected chunk type (" + chunkType + ").");
                    }
                }
            }
Пример #8
0
 /// <summary>
 /// TODO: the list of parameters has gotten way to long.
 /// </summary>
 public AssemblyCompiler(CompilationMode mode, List<AssemblyDefinition> assemblies, 
                         List<AssemblyDefinition> references, Table resources, NameConverter nameConverter, 
                         bool generateDebugInfo, AssemblyClassLoader assemblyClassLoader, 
                         Func<AssemblyDefinition, string> assemblyToFilename, DexMethodBodyCompilerCache ccache,
                         HashSet<string> rootClassNames, XModule module, bool generateSetNextInstructionCode)
 {
     this.mode = mode;
     this.assemblies = assemblies;
     this.references = references;
     this.resources = resources;
     this.generateDebugInfo = generateDebugInfo;
     this.assemblyClassLoader = assemblyClassLoader;
     this.assemblyToFilename = assemblyToFilename;
     this.rootClassNames = rootClassNames;
     this.module = module;
     this.generateSetNextInstructionCode = generateDebugInfo && generateSetNextInstructionCode;
     targetPackage = new Target.Dex.DexTargetPackage(nameConverter, this);
     methodBodyCompilerCache = ccache;
     StopAtFirstError = true;
 }
Пример #9
0
        /// <summary>
        /// Default ctor
        /// </summary>
        public ResourceIdMap(Table frameworkResources, XmlTree manifest)
        {
            var package = frameworkResources.Packages.First();
            var resourceNames = package.KeyStrings;

            for (var i = 0; i < resourceNames.Count; i++)
            {
                var name = XName.Get(resourceNames[i], AndroidSchema);
                idMap.Add(name, new Entry(MakeId(0, 0, i)));
            }

            // Find attribute types
            manifest.VisitAttributes(a => {
                Entry entry;
                if (idMap.TryGetValue(a.XName, out entry))
                {
                    entry.ValueType = a.TypedValue.Type;
                }
            });

        }
Пример #10
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public CreateResourceIdsCode(Table resourceTable, List<Tuple<string, ResourceType>> resources, List<StyleableDeclaration> styleableDeclarations)
 {
     this.resourceTable = resourceTable;
     this.resources = resources;
     this.styleableDeclarations = styleableDeclarations;
 }
Пример #11
0
 private static string CreateTypeSpecName(Table.TypeSpec typeSpec)
 {
     var name = Utility.NameConverter.UpperCamelCase(typeSpec.Name);
     //if (!name.EndsWith("s"))
     //    name += "s";
     return name;
 }
Пример #12
0
        /// <summary>
        /// Lookup the value of a resource id with given name.
        /// </summary>
        private static int FindResourceId(Table resourceTable, string name)
        {
            foreach (var typeSpec in resourceTable.Packages[0].TypeSpecs)
            {
                if (typeSpec.EntryCount == 0)
                    continue;

                var index = 0;
                foreach (var entry in typeSpec.Entries)
                {
                    if (entry.Key == name)
                    {
                        var resId = 0x7F000000 | ((typeSpec.Id) << 16) | index;
                        return resId;
                    }
                    index++;
                }
            }
            throw new ArgumentException(string.Format("Unknown resource name '{0}'", name));
        }
Пример #13
0
        /// <summary>
        /// Compile an assembly into a dex file.
        /// </summary>
        private static void CompileAssembly(CommandLineOptions options, NameConverter nsConverter)
        {
            // Load resource type usage info file
            var usedTypeNames = LoadResourceTypeUsageInformation(options);


            // Load assemblies
            List<AssemblyDefinition> assemblies = new List<AssemblyDefinition>();
            List<AssemblyDefinition> references= new List<AssemblyDefinition>();

            var dxJarCompiler = options.EnableDxJarCompilation
                ? new DxClassfileMethodBodyCompiler(options.OutputFolder, options.DebugInfo)
                : null;
            Action<ClassSource> jarLoaded = dxJarCompiler != null ? dxJarCompiler.PreloadJar : (Action<ClassSource>)null;

            var module = new XModule();
            var classLoader = new AssemblyClassLoader(module.OnClassLoaded);
            var resolver = new AssemblyResolver(options.ReferenceFolders, classLoader, module.OnAssemblyLoaded);

            // initialize compiler cache in background.
            var ccache = options.EnableCompilerCache ? new DexMethodBodyCompilerCache(options.OutputFolder, resolver.GetFileName)
                                                     : new DexMethodBodyCompilerCache();

            var readerParameters = new ReaderParameters
            {
                AssemblyResolver = resolver,
                SymbolReaderProvider = new SafeSymbolReaderProvider(),
                ReadSymbols = true,
                ReadingMode = ReadingMode.Immediate
            };

            // load assemblies
            var toLoad = options.Assemblies.Select(path => new {path, target = assemblies})
                 .Concat(options.References.Select(path => new {path, target = references}))
                 // Some micro optimizations... 
                 // Our startup is IO bound until we have loaded first assembly from disk.
                 // So just load from smallest to largest.
                 .Select(load => new { load.path, load.target, length = new FileInfo(resolver.ResolvePath(load.path)).Length})
                 .OrderBy(load=>load.length)
                 .ToList();

            using (AssemblyCompiler.Profile("for loading assemblies"))
            {
                toLoad.AsParallel().ForAll(
                //toLoad.ForEach(
                    load =>
                    {
                        var assm = resolver.Load(load.path, readerParameters);
                        lock (load.target) load.target.Add(assm);
                    });
            }

            // Load resources
            Table table;
            using (var stream = new FileStream(options.InputResources, FileMode.Open, FileAccess.Read))
            {
                table = new Table(stream);
            }

            // Create compiler
            var compiler = new AssemblyCompiler(options.CompilationMode, assemblies, references, table, nsConverter,
                                                options.DebugInfo, classLoader, resolver.GetFileName, ccache, 
                                                usedTypeNames, module, options.GenerateSetNextInstructionCode);
            compiler.DxClassfileMethodBodyCompiler = dxJarCompiler;
            using (AssemblyCompiler.Profile("total compilation time", true))
                compiler.Compile();

            ccache.PrintStatistics();

            using (AssemblyCompiler.Profile("saving results"))
                compiler.Save(options.OutputFolder, options.FreeAppsKeyPath);

            
        }
Пример #14
0
        /// <summary>
        /// Compile the given resources into a suitable output folder.
        /// </summary>
        internal bool Compile(List<Tuple<string, ResourceType>> resources, List<string> appWidgetProviderCodeFiles, List<string> references, List<string> referenceFolders, string baseApkPath)
        {
            // Remove temp folder
            if (Directory.Exists(tempFolder))
            {
                Directory.Delete(tempFolder, true);
            }

            // Ensure temp\res folder exists
            var resFolder = Path.Combine(tempFolder, "res");
            Directory.CreateDirectory(resFolder);
            var tempApkPath = Path.Combine(tempFolder, "temp.apk");

            // Compile each resource
            foreach (var resource in resources.Where(x => x.Item2 != ResourceType.Manifest))
            {
                CopyResourceToFolder(tempFolder, resource.Item1, resource.Item2);
            }

            // Extract resources out of library project references
            var resolver = new AssemblyResolver(referenceFolders, null, null);
            foreach (var path in references)
            {
                ExtractLibraryProjectResources(resFolder, path, resolver);
            }

            // Select manifest path
            var manifestPath = resources.Where(x => x.Item2 == ResourceType.Manifest).Select(x => x.Item1).FirstOrDefault();

            // Ensure files exists for the appwidgetproviders
            CreateAppWidgetProviderFiles(tempFolder, manifestPath, appWidgetProviderCodeFiles);

            // Create system ID's resource
            CreateSystemIdsResource(tempFolder);

            // Run aapt
            var args = new[] {
                                 "p",
                                 "-f",
                                 "-S",
                                 resFolder,
                                 "-M",
                                 GetManifestPath(tempFolder, manifestPath, packageName),
                                 "-I",
                                 baseApkPath,
                                 "-F",
                                 tempApkPath
                             };
            var runner = new ProcessRunner(Locations.Aapt, args);
            var exitCode = runner.Run();
            if (exitCode != 0)
            {
                ProcessAaptErrors(runner.Output, tempFolder, resources);
                return false;
            }

            // Unpack compiled resources to base folder.
            Table resourceTable = null;
            using (var apk = new ApkFile(tempApkPath))
            {
                foreach (var name in apk.FileNames)
                {
                    // Extract
                    var data = apk.Load(name);

                    // Save
                    var path = Path.Combine(baseFolder, name);
                    Directory.CreateDirectory(Path.GetDirectoryName(path));
                    File.WriteAllBytes(path, data);

                    // Is resource table? yes -> load it
                    if (name == "resources.arsc")
                    {
                        resourceTable = new Table(new MemoryStream(data));
                    }
                }
            }

            // Create R.cs
            if (!string.IsNullOrEmpty(generatedCodeFolder))
            {
                var codeBuilder = new CreateResourceIdsCode(resourceTable, resources, valuesResourceProcessor.StyleableDeclarations);
                codeBuilder.Generate(generatedCodeFolder, packageName, generatedCodeNamespace, generatedCodeLanguage, lastModified);
            }

            // Create resource type usage info file
            if (!string.IsNullOrEmpty(resourceTypeUsageInformationPath))
            {
                // Ensure folder exists
                var folder = Path.GetDirectoryName(resourceTypeUsageInformationPath);
                if (!Directory.Exists(folder))
                    Directory.CreateDirectory(folder);

                // Create file
                File.WriteAllLines(resourceTypeUsageInformationPath, layoutProcessor.CustomClassNames);                
            }

            return true;
        }
Пример #15
0
        /// <summary>
        /// Compile an assembly into a dex file.
        /// </summary>
        private static void CompileAssembly(CommandLineOptions options, NameConverter nsConverter)
        {
            // Load resource type usage info file
            var usedTypeNames = LoadResourceTypeUsageInformation(options);

            // Load assemblies
            var assemblies = new List<AssemblyDefinition>();
            var module = new XModule();
            var classLoader = new AssemblyClassLoader(module.OnClassLoaded);
            var resolver = new AssemblyResolver(options.ReferenceFolders, classLoader, module.OnAssemblyLoaded);
            var readerParameters = new ReaderParameters(ReadingMode.Immediate)
            {
                AssemblyResolver = resolver,
                SymbolReaderProvider = new SafeSymbolReaderProvider(),
                ReadSymbols = true
            };
            foreach (var asmPath in options.Assemblies)
            {
                var asm = resolver.Load(asmPath, readerParameters);
                module.OnAssemblyLoaded(asm);
                classLoader.LoadAssembly(asm);
                assemblies.Add(asm);
            }
            // Load references
            var references = new List<AssemblyDefinition>();
            foreach (var refPath in options.References)
            {
                var asm = resolver.Load(refPath, readerParameters);
                module.OnAssemblyLoaded(asm);
                classLoader.LoadAssembly(asm);
                references.Add(asm);
            }

            // Load resources
            Table table;
            using (var stream = new FileStream(options.InputResources, FileMode.Open, FileAccess.Read))
            {
                table = new Table(stream);
            }

            // Create compiler
            var compiler = new AssemblyCompiler(options.CompilationMode, assemblies, references, table, nsConverter, options.DebugInfo, classLoader, usedTypeNames, module);
            compiler.Compile();
            compiler.Save(options.OutputFolder, options.FreeAppsKeyPath);
        }
Пример #16
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public TableEntryInstanceNode(Table.Type type, Table.EntryInstance instance)
 {
     this.type = type;
     this.instance = instance;
     Text = type.Configuration.ToString();
 }
Пример #17
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public TableTypeSpecNode(Table.TypeSpec typeSpec)
 {
     spec = typeSpec;
     Text = typeSpec.Name;
 }
Пример #18
0
 public void LoadTableTest()
 {
     var arsc = new Table(new MemoryStream(TestResource.resources));
 }